From d84186c01caa6728aff157b596908e8c5fdd2ad0 Mon Sep 17 00:00:00 2001 From: Chris Stewart Date: Tue, 3 Jan 2017 17:07:37 -0600 Subject: [PATCH 001/454] Specify which 1 byte push op codes are valid This adds documentation to BIP141 about which 1 byte push op codes are valid for segwit. This is needed because `OP_1NEGATE` is a 1 byte push op code, but is NOT a valid 1 byte push op code for segwit. See the implementation here for why `OP_1NEGATE` is not valid: https://github.com/bitcoin/bitcoin/blob/14d01309bed59afb08651f2b701ff90371b15b20/src/script/script.cpp#L228 --- bip-0141.mediawiki | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/bip-0141.mediawiki b/bip-0141.mediawiki index 7cc587a28f..cbdf5cedf5 100644 --- a/bip-0141.mediawiki +++ b/bip-0141.mediawiki @@ -83,7 +83,7 @@ If all transactions in a block do not have witness data, the commitment is optio === Witness program === -A scriptPubKey (or redeemScript as defined in BIP16/P2SH) that consists of a 1-byte push opcode (for 0 to 16) followed by a data push between 2 and 40 bytes gets a new special meaning. The value of the first push is called the "version byte". The following byte vector pushed is called the "witness program". +A scriptPubKey (or redeemScript as defined in BIP16/P2SH) that consists of a valid 1-byte push opcode (OP_0,OP_1,OP_2...,OP_16) followed by a data push between 2 and 40 bytes gets a new special meaning. The value of the first push is called the "version byte". The following byte vector pushed is called the "witness program". There are two cases in which witness validation logic are triggered. Each case determines the location of the witness version byte and program, as well as the form of the scriptSig: # Triggered by a scriptPubKey that is exactly a push of a version byte, plus a push of a witness program. The scriptSig must be exactly empty or validation fails. (''"native witness program"'') From 608d5dc95f2ddcee32758fe73de6d68b99021e39 Mon Sep 17 00:00:00 2001 From: Chris Stewart Date: Tue, 3 Jan 2017 17:46:14 -0600 Subject: [PATCH 002/454] Update bip-0141.mediawiki Clarifying rewording, `OP_0` is not a 1 byte push op code since it pushes the empty byte vector onto the stack. --- bip-0141.mediawiki | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/bip-0141.mediawiki b/bip-0141.mediawiki index cbdf5cedf5..eeb6eb93db 100644 --- a/bip-0141.mediawiki +++ b/bip-0141.mediawiki @@ -83,7 +83,7 @@ If all transactions in a block do not have witness data, the commitment is optio === Witness program === -A scriptPubKey (or redeemScript as defined in BIP16/P2SH) that consists of a valid 1-byte push opcode (OP_0,OP_1,OP_2...,OP_16) followed by a data push between 2 and 40 bytes gets a new special meaning. The value of the first push is called the "version byte". The following byte vector pushed is called the "witness program". +A scriptPubKey (or redeemScript as defined in BIP16/P2SH) that consists of a select subset of opcodes (OP_0,OP_1,OP_2,...,OP_16) followed by a data push between 2 and 40 bytes gets a new special meaning. The value of the first push is called the "version byte". The following byte vector pushed is called the "witness program". There are two cases in which witness validation logic are triggered. Each case determines the location of the witness version byte and program, as well as the form of the scriptSig: # Triggered by a scriptPubKey that is exactly a push of a version byte, plus a push of a witness program. The scriptSig must be exactly empty or validation fails. (''"native witness program"'') From b2b24b53935544f45188fbe1ae8701074b8cc9f6 Mon Sep 17 00:00:00 2001 From: azuchi Date: Sun, 19 Feb 2017 16:19:17 +0900 Subject: [PATCH 003/454] BIP 143: Unify coin unit --- bip-0143.mediawiki | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/bip-0143.mediawiki b/bip-0143.mediawiki index 476b84da5a..77d75c9a49 100644 --- a/bip-0143.mediawiki +++ b/bip-0143.mediawiki @@ -551,7 +551,7 @@ These examples show that FindAndDelete for the signature is not app nLockTime: 00000000 The input comes from a P2WSH witness program: - scriptPubKey : 00209e1be07558ea5cc8e02ed1d80c0911048afad949affa36d5c3951e3159dbea19, value: 200000 + scriptPubKey : 00209e1be07558ea5cc8e02ed1d80c0911048afad949affa36d5c3951e3159dbea19, value: 0.00200000 redeemScript : OP_CHECKSIGVERIFY <0x30450220487fb382c4974de3f7d834c1b617fe15860828c7f96454490edd6d891556dcc9022100baf95feb48f845d5bfc9882eb6aeefa1bc3790e39f59eaa46ff7f15ae626c53e01> ad4830450220487fb382c4974de3f7d834c1b617fe15860828c7f96454490edd6d891556dcc9022100baf95feb48f845d5bfc9882eb6aeefa1bc3790e39f59eaa46ff7f15ae626c53e01 From ce5d831516bfdb34904a765b3f742e38621ec036 Mon Sep 17 00:00:00 2001 From: Luke Dashjr Date: Wed, 27 Sep 2017 18:50:05 +0000 Subject: [PATCH 004/454] BIP 2: Allow editors to fix typos --- bip-0002.mediawiki | 2 ++ 1 file changed, 2 insertions(+) diff --git a/bip-0002.mediawiki b/bip-0002.mediawiki index ea60d1d7c1..05f13e547e 100644 --- a/bip-0002.mediawiki +++ b/bip-0002.mediawiki @@ -95,6 +95,8 @@ The BIP editor will: The BIP editors are intended to fulfill administrative and editorial responsibilities. The BIP editors monitor BIP changes, and update BIP headers as appropriate. +BIP editors may also, at their option, unilaterally make and merge strictly-editorial changes to BIPs, such as correcting misspellings, fixing broken links, etc. + ==BIP format and structure== ===Specification=== From b84deb2adf23695a0f21b5f056257be65294c064 Mon Sep 17 00:00:00 2001 From: philsmd <921533+philsmd@users.noreply.github.com> Date: Tue, 7 Nov 2017 22:19:47 +0100 Subject: [PATCH 005/454] bip38 typo: specifid -> specified There was a small typo in the bip38 specification. If I'm not totally mistaken the word should be "specified" (not specifid) Thx --- bip-0038.mediawiki | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/bip-0038.mediawiki b/bip-0038.mediawiki index bfe1f4ab61..9e4d3ef164 100644 --- a/bip-0038.mediawiki +++ b/bip-0038.mediawiki @@ -170,7 +170,7 @@ To recalculate the address: # Derive ''passfactor'' using scrypt with ''ownerentropy'' and the user's passphrase and use it to recompute ''passpoint'' # Derive decryption key for ''pointb'' using scrypt with ''passpoint'', ''addresshash'', and ''ownerentropy'' # Decrypt ''encryptedpointb'' to yield ''pointb'' -# ECMultiply ''pointb'' by ''passfactor''. Use the resulting EC point as a public key and hash it into ''address'' using either compressed or uncompressed public key methodology as specifid in ''flagbyte''. +# ECMultiply ''pointb'' by ''passfactor''. Use the resulting EC point as a public key and hash it into ''address'' using either compressed or uncompressed public key methodology as specified in ''flagbyte''. =====Decryption===== # Collect encrypted private key and passphrase from user. From 9d879aaf5ce36c270d6874ef72aa723732f3bc12 Mon Sep 17 00:00:00 2001 From: nopara73 Date: Sat, 12 May 2018 21:51:18 +0700 Subject: [PATCH 006/454] Fix typos --- bip-0126.mediawiki | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/bip-0126.mediawiki b/bip-0126.mediawiki index f498b1cb33..4cfa2929a7 100644 --- a/bip-0126.mediawiki +++ b/bip-0126.mediawiki @@ -50,7 +50,7 @@ Applications which wish to comply both with this procedure and BIP69 should appl A HIT is Standard form if it adheres to all of the following rules: -# The number of unique output scripts must be equal to the number of unique inputs scripts (irrespective of the number of inputs and outputs). +# The number of unique output scripts must be equal to the number of unique input scripts (irrespective of the number of inputs and outputs). # All output scripts must be unique. # At least one pair of outputs must be of equal value. # The largest output in the transaction is a member of a set containing at least two identically-sized outputs. @@ -88,7 +88,7 @@ Clients which create intentional HITs must have the capability to form alternate An HIT formed via the preceding procedure will adhere to the following conditions: -# The number of unique inputs scripts must exceed the number of output scripts. +# The number of unique input scripts must exceed the number of output scripts. # All output scripts must be unique. # At least one pair of outputs must be of equal value. ## "Standard outputs" refers to the set of outputs with equal value From 1dcb4eef3083323f17a3446e240e07a1115c3b3f Mon Sep 17 00:00:00 2001 From: tadhg Date: Fri, 30 Nov 2018 18:37:42 +0100 Subject: [PATCH 007/454] Fix typo in BIP47 --- bip-0047.mediawiki | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/bip-0047.mediawiki b/bip-0047.mediawiki index af801f96ac..4b1763fb2d 100644 --- a/bip-0047.mediawiki +++ b/bip-0047.mediawiki @@ -150,7 +150,7 @@ It is assumed that Alice can easily obtain Bob's payment code via a suitable met Prior to the first time Alice initiates a transaction to Bob, Alice MUST inform Bob of her payment code via the following procedure: -Note: this procedure is used if Bob uses a version 1 payment code (regardless of the the version of Alice's payment code). If Bob's payment code is not version 1, see the appropriate section in this specification. +Note: this procedure is used if Bob uses a version 1 payment code (regardless of the version of Alice's payment code). If Bob's payment code is not version 1, see the appropriate section in this specification. # Alice constructs a transaction which sends a small quantity of bitcoins to Bob's notification address (notification transaction) ## The inputs selected for this transaction MUST NOT be easily associated with Alice's notification address From a66d1852a27007e14d1d233afbeb3ce362f1c13c Mon Sep 17 00:00:00 2001 From: tadhg Date: Fri, 7 Dec 2018 01:25:19 +0100 Subject: [PATCH 008/454] Missing word --- bip-0047.mediawiki | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/bip-0047.mediawiki b/bip-0047.mediawiki index af801f96ac..ce4af498fe 100644 --- a/bip-0047.mediawiki +++ b/bip-0047.mediawiki @@ -229,7 +229,7 @@ The following actions are recommended to reduce this risk: # Bob is watching for incoming payments on B' ever since he received the notification transaction from Alice. -## Bob calculates n shared secrets with Alice, using the 0th public key derived Alice's payment code, and private keys 0 - n derived from Bob's payment code, where n is his desired lookahead window. +## Bob calculates n shared secrets with Alice, using the 0th public key derived from Alice's payment code, and private keys 0 - n derived from Bob's payment code, where n is his desired lookahead window. ## Bob calculates the ephemeral deposit addresses using the same procedure as Alice:
B' = B + sG
## Bob calculate the private key for each ephemeral address as:
b' = b + s
From e5c708b3e74f8ab0e855c215f94ed8aadbca3e7d Mon Sep 17 00:00:00 2001 From: Chm Date: Sat, 22 Dec 2018 23:50:26 +0800 Subject: [PATCH 009/454] Typo of test data in bip 143 Transaction signature got sigHashType byte missing in decomposed block. --- bip-0143.mediawiki | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/bip-0143.mediawiki b/bip-0143.mediawiki index ed07c8281d..9619da1c17 100644 --- a/bip-0143.mediawiki +++ b/bip-0143.mediawiki @@ -187,7 +187,7 @@ To ensure consistency in consensus-critical behaviour, developers should test th nHashType: 01000000 sigHash: c37af31116d1b27caf68aae9e3ac82f1477929014d5b917657d0eb49478cb670 - signature: 304402203609e17b84f6a7d30c80bfa610b5b4542f32a8a0d5447a12fb1366d7f01cc44a0220573a954c4518331561406f90300e8f3358f51928d43c212a8caed02de67eebee + signature: 304402203609e17b84f6a7d30c80bfa610b5b4542f32a8a0d5447a12fb1366d7f01cc44a0220573a954c4518331561406f90300e8f3358f51928d43c212a8caed02de67eebee01 The serialized signed transaction is: 01000000000102fff7f7881a8099afa6940d42d1e7f6362bec38171ea3edf433541db4e4ad969f00000000494830450221008b9d1dc26ba6a9cb62127b02742fa9d754cd3bebf337f7a55d114c8e5cdd30be022040529b194ba3f9281a99f2b1c0a19c0489bc22ede944ccf4ecbab4cc618ef3ed01eeffffffef51e1b804cc89d182d279655c3aa89e815b1b309fe287d9b2b55d57b90ec68a0100000000ffffffff02202cb206000000001976a9148280b37df378db99f66f85c95a783a76ac7a6d5988ac9093510d000000001976a9143bde42dbee7e4dbe6a21b2d50ce2f0167faa815988ac000247304402203609e17b84f6a7d30c80bfa610b5b4542f32a8a0d5447a12fb1366d7f01cc44a0220573a954c4518331561406f90300e8f3358f51928d43c212a8caed02de67eebee0121025476c2e83188368da1ff3e292e7acafcdb3566bb0ad253f62fc70f07aeee635711000000 From 9b03604c5bae35510c420b7a8a42dd00eed41dd3 Mon Sep 17 00:00:00 2001 From: Javed Khan Date: Thu, 25 Oct 2018 21:00:52 +0530 Subject: [PATCH 010/454] bip158: update test vectors --- bip-0158.mediawiki | 2 ++ 1 file changed, 2 insertions(+) diff --git a/bip-0158.mediawiki b/bip-0158.mediawiki index 535ffd9a5e..5ebfaed3d9 100644 --- a/bip-0158.mediawiki +++ b/bip-0158.mediawiki @@ -315,6 +315,8 @@ complete serialization of a filter is: * N, encoded as a CompactSize * The bytes of the compressed filter itself +A zero element filter MUST be written as one byte containing zeroes. + ==== Signaling ==== This BIP allocates a new service bit: From c7cc17f14ec44fa2c0463a6ed2fd9bfcaac7535c Mon Sep 17 00:00:00 2001 From: Luke Childs Date: Fri, 7 Jun 2019 14:26:45 +0700 Subject: [PATCH 011/454] [bip38] Consistent hyphenation usage --- bip-0038.mediawiki | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/bip-0038.mediawiki b/bip-0038.mediawiki index bfe1f4ab61..9642f42f1c 100644 --- a/bip-0038.mediawiki +++ b/bip-0038.mediawiki @@ -39,7 +39,7 @@ This proposal is hereby placed in the public domain. :'''''User story:''' As a Bitcoin user who uses paper wallets, I would like the ability to add encryption, so that my Bitcoin paper storage can be two factor: something I have plus something I know.'' :'''''User story:''' As a Bitcoin user who would like to pay a person or a company with a private key, I do not want to worry that any part of the communication path may result in the interception of the key and theft of my funds. I would prefer to offer an encrypted private key, and then follow it up with the password using a different communication channel (e.g. a phone call or SMS).'' :'''''User story:''' (EC-multiplied keys) As a user of physical bitcoins, I would like a third party to be able to create password-protected Bitcoin private keys for me, without them knowing the password, so I can benefit from the physical bitcoin without the issuer having access to the private key. I would like to be able to choose a password whose minimum length and required format does not preclude me from memorizing it or engraving it on my physical bitcoin, without exposing me to an undue risk of password cracking and/or theft by the manufacturer of the item.'' -:'''''User story:''' (EC multiplied keys) As a user of paper wallets, I would like the ability to generate a large number of Bitcoin addresses protected by the same password, while enjoying a high degree of security (highly expensive scrypt parameters), but without having to incur the scrypt delay for each address I generate. +:'''''User story:''' (EC-multiplied keys) As a user of paper wallets, I would like the ability to generate a large number of Bitcoin addresses protected by the same password, while enjoying a high degree of security (highly expensive scrypt parameters), but without having to incur the scrypt delay for each address I generate. ==Specification== This proposal makes use of the following functions and definitions: From 62c759eae68c380c1a494540331254039cbbd1ee Mon Sep 17 00:00:00 2001 From: Bryan Bishop Date: Sat, 3 Aug 2019 13:55:29 -0500 Subject: [PATCH 012/454] bip112: fix trivial typo --- bip-0112.mediawiki | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/bip-0112.mediawiki b/bip-0112.mediawiki index f3d370a3f1..b159786586 100644 --- a/bip-0112.mediawiki +++ b/bip-0112.mediawiki @@ -36,7 +36,7 @@ When executed, if any of the following conditions are true, the script interpret Otherwise, script execution will continue as if a NOP had been executed. -BIP 68 prevents a non-final transaction from being selected for inclusion in a block until the corresponding input has reached the specified age, as measured in block-height or block-time. By comparing the argument to CHECKSEQUENCEVERIFY against the nSequence field, we indirectly verify a desired minimum age of the +BIP 68 prevents a non-final transaction from being selected for inclusion in a block until the corresponding input has reached the specified age, as measured in block-height or block-time. By comparing the argument to CHECKSEQUENCEVERIFY against the nSequence field, we indirectly verify a desired minimum age of the output being spent; until that relative age has been reached any script execution pathway including the CHECKSEQUENCEVERIFY will fail to validate, causing the transaction not to be selected for inclusion in a block. From a0481edf92c91ca785d3b6da577aba5a0929213d Mon Sep 17 00:00:00 2001 From: Enegnei Date: Sun, 30 Aug 2020 22:01:46 +0200 Subject: [PATCH 013/454] Minor grammar fix --- bip-0032.mediawiki | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/bip-0032.mediawiki b/bip-0032.mediawiki index f2f1e48b7e..5a1d778440 100644 --- a/bip-0032.mediawiki +++ b/bip-0032.mediawiki @@ -118,7 +118,7 @@ To shorten notation, we will write CKDpriv(CKDpriv(CKDpriv(m,3H),2),5 * N(m/aH/b/c) = N(m/aH/b)/c = N(m/aH)/b/c. However, N(m/aH) cannot be rewritten as N(m)/aH, as the latter is not possible. -Each leaf node in the tree corresponds to an actual key, while the internal nodes correspond to the collections of keys that descend from them. The chain codes of the leaf nodes are ignored, and only their embedded private or public key is relevant. Because of this construction, knowing an extended private key allows reconstruction of all descendant private keys and public keys, and knowing an extended public keys allows reconstruction of all descendant non-hardened public keys. +Each leaf node in the tree corresponds to an actual key, while the internal nodes correspond to the collections of keys that descend from them. The chain codes of the leaf nodes are ignored, and only their embedded private or public key is relevant. Because of this construction, knowing an extended private key allows reconstruction of all descendant private keys and public keys, and knowing an extended public key allows reconstruction of all descendant non-hardened public keys. ===Key identifiers=== From 688b0dabab2fcdadffe69bf1bdf5d4773b5be391 Mon Sep 17 00:00:00 2001 From: Enegnei Date: Sun, 30 Aug 2020 22:41:52 +0200 Subject: [PATCH 014/454] A few more minor grammar fixes / improvements --- bip-0032.mediawiki | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/bip-0032.mediawiki b/bip-0032.mediawiki index 5a1d778440..341dc08949 100644 --- a/bip-0032.mediawiki +++ b/bip-0032.mediawiki @@ -24,7 +24,7 @@ This document describes hierarchical deterministic wallets (or "HD Wallets"): wa The specification is intended to set a standard for deterministic wallets that can be interchanged between different clients. Although the wallets described here have many features, not all are required by supporting clients. -The specification consists of two parts. In a first part, a system for deriving a tree of keypairs from a single seed is presented. The second part demonstrates how to build a wallet structure on top of such a tree. +The specification consists of two parts. In the first part, a system for deriving a tree of keypairs from a single seed is presented. The second part demonstrates how to build a wallet structure on top of such a tree. ==Copyright== @@ -36,7 +36,7 @@ The Bitcoin reference client uses randomly generated keys. In order to avoid the Deterministic wallets do not require such frequent backups, and elliptic curve mathematics permit schemes where one can calculate the public keys without revealing the private keys. This permits for example a webshop business to let its webserver generate fresh addresses (public key hashes) for each order or for each customer, without giving the webserver access to the corresponding private keys (which are required for spending the received funds). -However, deterministic wallets typically consist of a single "chain" of keypairs. The fact that there is only one chain means that sharing a wallet happens on an all-or-nothing basis. However, in some cases one only wants some (public) keys to be shared and recoverable. In the example of a webshop, the webserver does not need access to all public keys of the merchant's wallet; only to those addresses which are used to receive customer's payments, and not for example the change addresses that are generated when the merchant spends money. Hierarchical deterministic wallets allow such selective sharing by supporting multiple keypair chains, derived from a single root. +However, deterministic wallets typically consist of a single "chain" of keypairs. The fact that there is only one chain means that sharing a wallet happens on an all-or-nothing basis. However, in some cases one only wants some (public) keys to be shared and recoverable. In the example of a webshop, the webserver does not need access to all public keys of the merchant's wallet; only to those addresses which are used to receive customers' payments, and not for example the change addresses that are generated when the merchant spends money. Hierarchical deterministic wallets allow such selective sharing by supporting multiple keypair chains, derived from a single root. ==Specification: Key derivation== @@ -103,7 +103,7 @@ The function N((k, c)) → (K, c) computes the extended public key correspond To compute the public child key of a parent private key: * N(CKDpriv((kpar, cpar), i)) (works always). * CKDpub(N(kpar, cpar), i) (works only for non-hardened child keys). -The fact that they are equivalent is what makes non-hardened keys useful (one can derive child public keys of a given parent key without knowing any private key), and also what distinguishes them from hardened keys. The reason for not always using non-hardened keys (which are more useful) is security; see further for more information. +The fact that they are equivalent is what makes non-hardened keys useful (one can derive child public keys of a given parent key without knowing any private key), and also what distinguishes them from hardened keys. The reason for not always using non-hardened keys (which are more useful) is security; see further below for more information. ====Public parent key → private child key==== @@ -183,7 +183,7 @@ When a business has several independent offices, they can all use wallets derive ====Recurrent business-to-business transactions: N(m/iH/0)==== In case two business partners often transfer money, one can use the extended public key for the external chain of a specific account (M/i h/0) as a sort of "super address", allowing frequent transactions that cannot (easily) be associated, but without needing to request a new address for each payment. -Such a mechanism could also be used by mining pool operators as variable payout address. +Such a mechanism could also be used by mining pool operators as a variable payout address. ====Unsecure money receiver: N(m/iH/0)==== @@ -211,7 +211,7 @@ Private and public keys must be kept safe as usual. Leaking a private key means Somewhat more care must be taken regarding extended keys, as these correspond to an entire (sub)tree of keys. One weakness that may not be immediately obvious, is that knowledge of a parent extended public key plus any non-hardened private key descending from it is equivalent to knowing the parent extended private key (and thus every private and public key descending from it). This means that extended public keys must be treated more carefully than regular public keys. -It is also the reason for the existence of hardened keys, and why they are used for the account level in the tree. This way, a leak of account-specific (or below) private key never risks compromising the master or other accounts. +It is also the reason for the existence of hardened keys, and why they are used for the account level in the tree. This way, a leak of account-specific (or below) private keys never risks compromising the master or other accounts. ==Test Vectors== From 5ec9df085ebc2adfef5ab667662a8aba967f06cd Mon Sep 17 00:00:00 2001 From: Justus Ranvier Date: Thu, 28 Sep 2017 08:47:50 -0500 Subject: [PATCH 015/454] BIP-0047: Adjust text to match test vectors The original implementation of BIP-47 in Samourai Wallet reversed the parameters in the calculation of the HMAC-SHA512 step of notification transaction blinding. This change adjusts the text to match the as-implementend behavior in deployed BIP-47 wallets and the test vectors. --- bip-0047.mediawiki | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/bip-0047.mediawiki b/bip-0047.mediawiki index af801f96ac..ada9deb5d9 100644 --- a/bip-0047.mediawiki +++ b/bip-0047.mediawiki @@ -1,7 +1,7 @@ RECENT CHANGES: +* (28 Sep 2017) Adjust text to match test vectors * (19 Apr 2016) Define version 2 payment codes * (17 Apr 2016) Clarify usage of outpoints in notification transactions -* (18 Dec 2015) Update explanations to resolve FAQs
   BIP: 47
@@ -158,7 +158,7 @@ Note: this procedure is used if Bob uses a version 1 payment code (regardless of
 ## Alice selects the private key corresponding to the designated pubkey: 
a
## Alice selects the public key associated with Bob's notification address:
B, where B = bG
## Alice calculates a secret point:
S = aB
-## Alice calculates a 64 byte blinding factor:
s = HMAC-SHA512(x, o)
+## Alice calculates a 64 byte blinding factor:
s = HMAC-SHA512(o, x)
### "x" is the x value of the secret point ### "o" is the outpoint being spent by the designated input # Alice serializes her payment code in binary form. From bc069fa050fb9816746c9e13b34d9d13a7d89562 Mon Sep 17 00:00:00 2001 From: Justus Ranvier Date: Mon, 15 Feb 2021 06:22:42 -0900 Subject: [PATCH 016/454] Finalize BIP-47 --- bip-0047.mediawiki | 10 ++++++++-- 1 file changed, 8 insertions(+), 2 deletions(-) diff --git a/bip-0047.mediawiki b/bip-0047.mediawiki index ada9deb5d9..4806b0b625 100644 --- a/bip-0047.mediawiki +++ b/bip-0047.mediawiki @@ -1,7 +1,7 @@ RECENT CHANGES: +* (15 Feb 2021) Finalize specification * (28 Sep 2017) Adjust text to match test vectors * (19 Apr 2016) Define version 2 payment codes -* (17 Apr 2016) Clarify usage of outpoints in notification transactions
   BIP: 47
@@ -10,11 +10,17 @@ RECENT CHANGES:
   Author: Justus Ranvier 
   Comments-Summary: Unanimously Discourage for implementation
   Comments-URI: https://github.com/bitcoin/bips/wiki/Comments:BIP-0047
-  Status: Draft
+  Status: Final
   Type: Informational
   Created: 2015-04-24
 
+==Status== + +This BIP can be be considered final in terms of enabling compatibility with wallets that implement version 1 and version 2 reusable payment codes, however future developments of the reusable payment codes specification will not be distributed via the BIP process. + +The Open Bitcoin Privacy Project RFC repo should be consulted for specifications related to version 3 or higher payment codes: https://github.com/OpenBitcoinPrivacyProject/rfc + ==Abstract== This BIP defines a technique for creating a payment code which can be publicly advertised and associated with a real-life identity without creating the loss of security or privacy inherent to P2PKH address reuse. From aa206adf59483979fda5de30264c4017b2fcd8a5 Mon Sep 17 00:00:00 2001 From: Tobin Harding Date: Tue, 17 Aug 2021 18:35:36 +1000 Subject: [PATCH 017/454] Remove newline to fix list rendering Currently the newline in list items is causing the text on the new line to be rendered as a code section. I am unsure why but I'm guessing putting all the text for each list item on a single line will fix it. --- bip-0158.mediawiki | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) diff --git a/bip-0158.mediawiki b/bip-0158.mediawiki index ce4a4af949..1ac0c9c1f5 100644 --- a/bip-0158.mediawiki +++ b/bip-0158.mediawiki @@ -273,10 +273,8 @@ This BIP defines one initial filter type: The basic filter is designed to contain everything that a light client needs to sync a regular Bitcoin wallet. A basic filter MUST contain exactly the following items for each transaction in a block: -* The previous output script (the script being spent) for each input, except - for the coinbase transaction. -* The scriptPubKey of each output, aside from all OP_RETURN output - scripts. +* The previous output script (the script being spent) for each input, except for the coinbase transaction. +* The scriptPubKey of each output, aside from all OP_RETURN output scripts. Any "nil" items MUST NOT be included into the final set of filter elements. From 497ad1c81a8d7e882c86ffe780db5b01db66d686 Mon Sep 17 00:00:00 2001 From: katesalazar Date: Fri, 17 Sep 2021 21:08:05 +0200 Subject: [PATCH 018/454] Remove transparent background from figure. Before this change, the figure presented black text on transparent background, which might be unconvenient when using a browser able to pass a dark theme preference to some environments where this document is published, currently notably GitHub. A white background could help a better visualization compromise. White background on the figure is the single purpose of this revision. This PNG was compiled using: dot -Tpng states.gv -o states.png --- bip-0009/states.gv | 22 ++++++++++++++++++++++ bip-0009/states.png | Bin 30632 -> 50153 bytes 2 files changed, 22 insertions(+) create mode 100644 bip-0009/states.gv diff --git a/bip-0009/states.gv b/bip-0009/states.gv new file mode 100644 index 0000000000..9dc95c56e3 --- /dev/null +++ b/bip-0009/states.gv @@ -0,0 +1,22 @@ +/* There are many ways to compile this, but one of them is: + * + * $ dot -Tpng states.gv -o states.png + */ +digraph { + /* States. */ + DEFINED; FAILED; STARTED; LOCKED_IN; ACTIVE; + + /* Relationships between states, labeled where applicable. */ + DEFINED -> DEFINED; + DEFINED -> FAILED [label = "timeout ≤ MTP"]; + DEFINED -> STARTED [label = "starttime ≤ MTP < timeout"]; + FAILED -> FAILED; + STARTED -> STARTED; + STARTED -> FAILED [label = "timeout ≤ MTP"]; + STARTED -> LOCKED_IN [label = "(MTP < timeout) AND (threshold reached)"]; + LOCKED_IN -> ACTIVE [label = "Always"]; + ACTIVE -> ACTIVE; + + /* Visualization hack to unclutter output. */ + nodesep = 1.2; +} diff --git a/bip-0009/states.png b/bip-0009/states.png index 09312a1c0381845d10afe2ffbbec912ee1b1b1e0..2048ed870df296d86bef1145b1f10aa980801c8f 100644 GIT binary patch literal 50153 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 literal 30632 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 Date: Thu, 18 Nov 2021 23:55:55 +0100 Subject: [PATCH 019/454] BIP 155: add Yggdrasil --- bip-0155.mediawiki | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/bip-0155.mediawiki b/bip-0155.mediawiki index 3e7b0d829d..0ec680194d 100644 --- a/bip-0155.mediawiki +++ b/bip-0155.mediawiki @@ -117,6 +117,11 @@ The list of reserved network IDs is as follows: | CJDNS | 16 | Cjdns overlay network address +|- +| 0x07 +| YGGDRASIL +| 16 +| Yggdrasil overlay network address |} Clients are RECOMMENDED to gossip addresses from all known networks even if they are currently not connected to some of them. That could help multi-homed nodes and make it more difficult for an observer to tell which networks a node is connected to. @@ -184,6 +189,10 @@ I2P addresses MUST be sent with the I2P network ID, with the decode Cjdns addresses are simply IPv6 addresses in the fc00::/8 range[https://github.com/cjdelisle/cjdns/blob/6e46fa41f5647d6b414612d9d63626b0b952746b/doc/Whitepaper.md#pulling-it-all-together Cjdns whitepaper: Pulling It All Together]. They MUST be sent with the CJDNS network ID. +==Appendix E: Yggdrasil address encoding== + +Yggdrasil addresses are simply IPv6 addresses in the 0200::/7 range[https://yggdrasil-network.github.io/faq.html#will-yggdrasil-conflict-with-my-network-routing Yggdrasil FAQ]. They MUST be sent with the YGGDRASIL network ID. + ==References== From 3248581928b5299525b32979c8a569ce9107fdfc Mon Sep 17 00:00:00 2001 From: katesalazar Date: Fri, 13 May 2022 20:20:49 +0000 Subject: [PATCH 020/454] Bring back transparent background to figures Black arrows are visible only in light theme (unless white background for dark theme). Two-color arrows are visible in light theme and in dark theme. --- .gitignore | 6 + bip-0174/build.sh | 9 + bip-0174/coinjoin-workflow.svg | 1460 +++++++++++++--- bip-0174/coinjoin-workflow.tex | 12 +- bip-0174/multisig-workflow.svg | 2957 ++++++++++++++++++++++++++------ bip-0174/multisig-workflow.tex | 19 +- 6 files changed, 3612 insertions(+), 851 deletions(-) create mode 100644 .gitignore create mode 100755 bip-0174/build.sh diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000000..d939d2a572 --- /dev/null +++ b/.gitignore @@ -0,0 +1,6 @@ +bip-0174/coinjoin-workflow.aux +bip-0174/coinjoin-workflow.log +bip-0174/coinjoin-workflow.pdf +bip-0174/multisig-workflow.aux +bip-0174/multisig-workflow.log +bip-0174/multisig-workflow.pdf diff --git a/bip-0174/build.sh b/bip-0174/build.sh new file mode 100755 index 0000000000..2de1e56275 --- /dev/null +++ b/bip-0174/build.sh @@ -0,0 +1,9 @@ +#!/bin/bash + +pdflatex -output-format=pdf coinjoin-workflow.tex && \ +inkscape --with-gui --export-text-to-path \ + --export-plain-svg=coinjoin-workflow.svg coinjoin-workflow.pdf && \ +pdflatex -output-format=pdf multisig-workflow.tex && \ +inkscape --with-gui --export-text-to-path \ + --export-plain-svg=multisig-workflow.svg multisig-workflow.pdf && \ +echo '"success"' diff --git a/bip-0174/coinjoin-workflow.svg b/bip-0174/coinjoin-workflow.svg index 4c2a041d70..3b6b952e8f 100644 --- a/bip-0174/coinjoin-workflow.svg +++ b/bip-0174/coinjoin-workflow.svg @@ -1,8 +1,54 @@ - - - - + + + + + + image/svg+xml + + + + + + + + @@ -107,7 +153,7 @@ - + @@ -376,281 +422,1133 @@ - + - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/bip-0174/coinjoin-workflow.tex b/bip-0174/coinjoin-workflow.tex index e0516ffeea..a325321ae4 100644 --- a/bip-0174/coinjoin-workflow.tex +++ b/bip-0174/coinjoin-workflow.tex @@ -7,7 +7,7 @@ \usepackage{lmodern} \renewcommand*\familydefault{\sfdefault} \usepackage{tikz} -\usetikzlibrary{shapes,arrows} +\usetikzlibrary{shapes,arrows.meta} \tikzset{>=latex} \begin{document} % \sffamily{} @@ -22,7 +22,7 @@ rounded corners] \begin{tikzpicture}[auto] % outlining the flowchart on a grid - \matrix[column sep=3ex,row sep=2ex]{ + \matrix[column sep=3ex,row sep=3ex]{ \node [block_center] (0alice1) {Alice creates a PSBT with only her inputs with UTXOs filled in.\\Sends it to Bob.}; @@ -49,7 +49,13 @@ \\ };% end matrix % connecting nodes with paths - \draw[line width = 1pt, ->] + \draw [ultra thick, draw=black, -{Stealth[length=8pt]}] + (0alice1) edge (1bob1) + (1bob1) edge (2carol1) + (2carol1) edge (3bob2) + (3bob2) edge (4alice1) + (4alice1) edge (5alice2); + \draw [thin, white, -{Stealth[color=black, fill=white, length=8pt]}] (0alice1) edge (1bob1) (1bob1) edge (2carol1) (2carol1) edge (3bob2) diff --git a/bip-0174/multisig-workflow.svg b/bip-0174/multisig-workflow.svg index 8abe4c51c6..2d873b052b 100644 --- a/bip-0174/multisig-workflow.svg +++ b/bip-0174/multisig-workflow.svg @@ -1,6 +1,47 @@ - + + viewBox="0 0 375.988 411.906" version="1.2" + xmlns:dc="http://purl.org/dc/elements/1.1/" + xmlns:cc="http://creativecommons.org/ns#" + xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#" + xmlns:svg="http://www.w3.org/2000/svg" + xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd" + xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape" + id="svg1424" + sodipodi:docname="multisig-workflow.svg" + inkscape:version="0.92.4 (5da689c313, 2019-01-14)"> + + + + image/svg+xml + + + + + + @@ -192,277 +233,931 @@ - - - - - - - + + + + + + + - - - - - - + + + + + + - - - - - - - - - - - - - - - + + + + + + + + + + + + + + + - - - - - + + + + + - - - - - - - - - - + + + + + + + + + + - - - - - - - - - - - - - - + + + + + + + + + + + + + + - - - - - - - - - - - - - - - - - + + + + + + + + + + + + + + + + + - - - - - - - - - - - + + + + + + + + + + + - - - - - - - + + + + + + + - - - - - - - - - - - - - - - - - - + + + + + + + + + + + + + + + + + + - - - - - - - - - - - - + + + + + + + + + + + + - - - - - - - - - + + + + + + + + + - - - - + + + + - - - - - - - - - + + + + + + + + + - - - - - - - - - - - - + + + + + + + + + + + + - - - - - - - - - + + + + + + + + + - - - - - - - - - + + + + + + + + + - - - - - - - - - - - + + + + + + + + + + + - - - - - - - - - - + + + + + + + + + + - - - - - - - - - - + + + + + + + + + + - - - - - - - - - - + + + + + + + + + + @@ -471,397 +1166,1381 @@ - - - - - + - - - - - + + + + + - - - - - - - - - + + + + + + + + + - + - - - - + + + + - - - - - - - - - + + + + + + + + + - - - - - - - - - - - - - - + + + + + + + + + + + + + + - - - - - - - - - - + + + + + + + + + + - - - - - - - - - - - - - - - - - - + + + + + + + + + + + + + + + + + + - - - - - - - - - + + + + + + + + + - - - - - - - - - - + + + + + + + + + + - - - - - - - - - - + + + + + + + + + + - - - - - - - - - + + + + + + + + + - - - - - - - - + + + + + + + + - - - - - - - - - - + + + + + + + + + + - - - - - - - - - - - + + + + + + + + + + + - - - - - - - - - - - - + + + + + + + + + + + + - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + - - - - - - - - - - - + + + + + + + + + + + - - - - - - - - - - - - - - - - - - - - - - - - - - - + + + + + + + + + + + + + + + + + + + + + + + + + + + - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + @@ -873,23 +2552,173 @@ - - - - - - - - - - - - - - - - - - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/bip-0174/multisig-workflow.tex b/bip-0174/multisig-workflow.tex index 2b8744d32a..d2250cfa6b 100644 --- a/bip-0174/multisig-workflow.tex +++ b/bip-0174/multisig-workflow.tex @@ -7,7 +7,7 @@ \usepackage{lmodern} \renewcommand*\familydefault{\sfdefault} \usepackage{tikz} -\usetikzlibrary{shapes,arrows} +\usetikzlibrary{shapes,arrows.meta} \tikzset{>=latex} %\pgfdeclarelayer{bg} % declare background layer %\pgfsetlayers{bg,main} % set order of layers @@ -83,7 +83,15 @@ };% end matrix % connecting nodes with paths % \begin{pgfonlayer}{bg} - \draw[line width = 1pt, ->] + \draw [ultra thick, draw=black, -{Stealth[length=8pt]}] + (R1) edge (R2) + (R2) edge (R3) + (R3) -| (R4C1) + (R3) edge (R4C2) + (R5) edge (R6) + (R6) edge (R7) + (R7) edge (stop); + \draw [thin, white, -{Stealth[color=black, fill=white, length=8pt]}] (R1) edge (R2) (R2) edge (R3) (R3) -| (R4C1) @@ -92,7 +100,12 @@ (R6) edge (R7) (R7) edge (stop); % circumvent missing arrow - \draw[line width = 1pt, ->] + \draw [ultra thick, draw=black, -{Stealth[length=8pt]}] + (R4C1) |-+(0,-2.2em)-| (R5) + (R4C2) edge (R5) + (R4C3) |-+(0,-2.2em)-| (R5) + (R3) -| (R4C3); + \draw [thin, white, -{Stealth[color=black, fill=white, length=8pt]}] (R4C1) |-+(0,-2.2em)-| (R5) (R4C2) edge (R5) (R4C3) |-+(0,-2.2em)-| (R5) From bf2eb4f680f537e344370f7bc92cc234b5ca5083 Mon Sep 17 00:00:00 2001 From: chris-belcher Date: Sat, 2 Jul 2022 18:43:09 +0100 Subject: [PATCH 021/454] Specify BIP-fidelity-bonds For storing fidelity bonds in HD wallets --- bip-fidelity-bonds.mediawiki | 167 +++++++++++++++++++++++++++++++++++ 1 file changed, 167 insertions(+) create mode 100644 bip-fidelity-bonds.mediawiki diff --git a/bip-fidelity-bonds.mediawiki b/bip-fidelity-bonds.mediawiki new file mode 100644 index 0000000000..571eca2e77 --- /dev/null +++ b/bip-fidelity-bonds.mediawiki @@ -0,0 +1,167 @@ +
+  BIP: TBD. Preferably a two-digit number to match the bip44, bip49, bip84, bip86 family of bips
+  Layer: Applications
+  Title: Derivation scheme for timelocked address fidelity bond based accounts
+  Author: Chris Belcher 
+  Status: Draft
+  Type: Standards Track
+  Comments-Summary: No comments yet.
+  Created: 2022-04-01
+  License: CC0-1.0
+  Post-History: 2022-5-1: https://lists.linuxfoundation.org/pipermail/bitcoin-dev/2022-May/020389.html
+
+ +== Abstract == + +This BIP defines the derivation scheme for HD wallets which create timelocked addresses used for creating fidelity bonds. It also defines how to sign fidelity bond certificates, which are needed when using fidelity bonds that are stored offline. + +== Motivation == + +Fidelity bonds are used to resist sybil attacks in certain decentralized anonymous protocols. They are created by locking up bitcoins using the `OP_CHECKLOCKTIMEVERIFY` opcode. + +It would be useful to have a common derivation scheme so that users of wallet software can have a backup of their fidelity bonds by storing only the HD seed and a reference to this BIP. Importantly the user does not need to backup any timelock values. + +We largely use the same approach used in BIPs 49, 84 and 86 for ease of implementation. + +This standard is already implemented and deployed in JoinMarket. As most changes would requires a protocol change of a live system, there is limited scope for changing this standard in review. This BIP is more about documenting something which already exists, warts and all. + +It would be useful to be able to keep the private keys of fidelity bonds in cold storage. This would allow the sybil resistance of a system to increase without hot wallet risk. + +== Background == + +=== Fidelity bonds === + +A fidelity bond is a mechanism where bitcoin value is deliberately sacrificed to make a cryptographic identity expensive to obtain. A way to create a fidelity bond is to lock up bitcoins by sending them to a timelocked address. The valuable thing being sacrificed is the time-value-of-money. + +The sacrifice must be done in a way that can be proven to a third party. This proof can be made by showing the UTXO outpoint, the address redeemscript and a signature which signs a message using the private key corresponding to the public key in the redeemscript. + +The sacrificed value is an objective measurement that can't be faked and which can be verified by anybody (just like, for example PoW mining). Sybil attacks can be made very expensive by forcing a hypothetical sybil attacker to lock up many bitcoins for a long time. JoinMarket implements fidelity bonds for protection from sybil attackers. At the time of writing over 600 BTC in total have been locked up with some for many years. Their UTXOs and signatures have been advertised to the world as proof. We can calculate that for a sybil attacker to succeed in unmixing all the CoinJoins, they would have to lock up over 100k BTC for several years. + +=== Fidelity bonds in cold storage === + +To allow for holding fidelity bonds in cold storage, there is an intermediate keypair called the certificate. + + UTXO key ---signs---> certificate ---signs---> endpoint + +Where the endpoint might be a IRC nickname or Tor onion hostname. The certificate keypair can be kept online and used to prove ownership of the fidelity bond. Even if the hot wallet private keys are stolen, the coins in the timelocked address will still be safe, although the thief will be able to impersonate the fidelity bond until the expiry. + +=== Fixed timelock values === + +It would be useful for the user to avoid having to keep a record of the timelocks in the time-locked addresses. So only a limited small set of timelocks are defined by this BIP. This way the user must only store their seed phrase, and knowledge that they have coins stored using this BIP standard. The user doesn't need to remember or store any dates. + + +== Specifications == + +This BIP defines the two needed steps to derive multiple deterministic addresses based on a [[bip-0032.mediawiki|BIP 32]] master private key. It also defines the format of the certificate can be signed by the deterministic address key. + +=== Public key derivation === + +To derive a public key from the root account, this BIP uses a similar account-structure as defined in BIP [[bip-0084.mediawiki|44]] but with change set to 2. + +
+m / 84' / 0' / 0' / 2 / index
+
+ +A key derived with this derivation path pattern will be referred to as derived_key further +in this document. + +For index, addresses are numbered from 0 in a sequentially increasing manner, but index does not increase forever like in other similar standards. The index only goes up to 959 inclusive. Only 960 addresses can be derived for a given BIP32 master key. Furthermore there is no concept of a gap limit, instead wallets must always generate all 960 addresses and check all of them if they have a balance and history. + +=== Timelock derivation === + +The timelock used in the time-locked address is derived from the index. The timelock is a unix time. It is always the first of the month at midnight. The index counts upwards the months from January 2020, ending in December 2099. At 12 months per year for 80 years this totals 960 timelocks. Note that care must be taken with the year 2038 problem on 32-bit systems. + +
+year = 2020 + index // 12
+month = 1 + index % 12
+
+ + +=== Address derivation === + +To derive the address from the above calculated public key and timelock, we create a redeemScript which locks the funds until the timelock, and then checks the signature of the derived_key. The redeemScript is hashed with SHA256 to produce a 32-byte hash value that forms the scriptPubKey of the P2WSH address. + + redeemScript: OP_CHECKLOCKTIMEVERIFY OP_DROP OP_CHECKSIG + witness: + scriptSig: (empty) + scriptPubKey: 0 <32-byte-hash> + (0x0020{32-byte-hash}) + +=== Message signing === + +In order to support signing of certificates, implementors should support signing ascii messages. + +A certificate message can be created by another application external to this standard. It is then prepended with the string `\x18Bitcoin Signed Message:\n` and a byte denoting the length of the certificate message. The whole thing is then signed with the private key of the derived_key. This part is identical to the "Sign Message" function which many wallets already implement. + +Almost all wallets implementing this standard can use their already-existing "Sign Message" function to sign the certificate message. As the certificate message itself is always an ascii string, the wallet may not need to specially implement this section at all but just rely on users copypasting their certificate message into the already-existing "Sign Message" user interface. This works as long as the wallet knows how to use the private key of the timelocked address for signing messages. + +It is most important for wallet implementions of this standard to support creating the certificate signature. Verifying the certificate signature is less important. + + +== Test vectors == + +
+mnemonic = abandon abandon abandon abandon abandon abandon abandon abandon abandon abandon abandon about
+rootpriv = xprv9s21ZrQH143K3GJpoapnV8SFfukcVBSfeCficPSGfubmSFDxo1kuHnLisriDvSnRRuL2Qrg5ggqHKNVpxR86QEC8w35uxmGoggxtQTPvfUu
+rootpub  = xpub661MyMwAqRbcFkPHucMnrGNzDwb6teAX1RbKQmqtEF8kK3Z7LZ59qafCjB9eCRLiTVG3uxBxgKvRgbubRhqSKXnGGb1aoaqLrpMBDrVxga8
+
+// First timelocked address = m/84'/0'/0'/2/0
+derived private_key = L2tQBEdhC48YLeEWNg3e4msk94iKfyVa9hdfzRwUERabZ53TfH3d
+derived public_key  = 02a1b09f93073c63f205086440898141c0c3c6d24f69a18db608224bcf143fa011
+unix locktime       = 1577836800
+string locktime     = 2020-01-01 00:00:00
+redeemscript        = 0400e10b5eb1752102a1b09f93073c63f205086440898141c0c3c6d24f69a18db608224bcf143fa011ac
+scriptPubKey        = 0020bdee9515359fc9df912318523b4cd22f1c0b5410232dc943be73f9f4f07e39ad
+address             = bc1qhhhf29f4nlyalyfrrpfrknxj9uwqk4qsyvkujsa7w0ulfur78xkspsqn84
+
+// Test certificate using first timelocked address
+// Note that as signatures contains a random nonce, it might not be exactly the same when your code generates it
+// p2pkh address is the p2pkh address corresponding to the derived public key, it can be used to verify the message
+//  signature in any wallet that supports Verify Message.
+// As mentioned before, it is more important for implementors of this standard to support signing such messages, not verifying them
+Message       = fidelity-bond-cert|020000000000000000000000000000000000000000000000000000000000000001|375
+Address       = bc1qhhhf29f4nlyalyfrrpfrknxj9uwqk4qsyvkujsa7w0ulfur78xkspsqn84
+p2pkh address = 16vmiGpY1rEaYnpGgtG7FZgr2uFCpeDgV6
+Signature     = H2b/90XcKnIU/D1nSCPhk8OcxrHebMCr4Ok2d2yDnbKDTSThNsNKA64CT4v2kt+xA1JmGRG/dMnUUH1kKqCVSHo=
+
+// 2nd timelocked address = m/84'/0'/0'/2/1
+derived private_key = KxctaFBzetyc9KXeUr6jxESCZiCEXRuwnQMw7h7hroP6MqnWN6Pf
+derived public_key  = 02599f6db8b33265a44200fef0be79c927398ed0b46c6a82fa6ddaa5be2714002d
+unix locktime       = 1580515200
+string locktime     = 2020-02-01 00:00:00
+redeemscript        = 0480bf345eb1752102599f6db8b33265a44200fef0be79c927398ed0b46c6a82fa6ddaa5be2714002dac
+scriptPubKey        = 0020b8f898643991608524ed04e0c6779f632a57f1ffa3a3a306cd81432c5533e9ae
+address             = bc1qhrufsepej9sg2f8dqnsvvaulvv490u0l5w36xpkds9pjc4fnaxhq7pcm4h
+
+// timelocked address after the year 2038 = m/84'/0'/0'/2/240
+derived private_key = L3SYqae23ZoDDcyEA8rRBK83h1MDqxaDG57imMc9FUx1J8o9anQe
+derived public_key  = 03ec8067418537bbb52d5d3e64e2868e67635c33cfeadeb9a46199f89ebfaab226
+unix locktime       = 2208988800
+string locktime     = 2040-01-01 00:00:00
+redeemscript        = 05807eaa8300b1752103ec8067418537bbb52d5d3e64e2868e67635c33cfeadeb9a46199f89ebfaab226ac
+scriptPubKey        = 0020e7de0ad2720ae1d6cc9b6ad91af57eb74646762cf594c91c18f6d5e7a873635a
+address             = bc1qul0q45njptsadnymdtv34at7karyva3v7k2vj8qc7m2702rnvddq0z20u5
+
+// last timelocked address = m/84'/0'/0'/2/959
+derived private_key = L5Z9DDMnj5RZMyyPiQLCvN48Xt7GGmev6cjvJXD8uz5EqiY8trNJ
+derived public_key  = 0308c5751121b1ae5c973cdc7071312f6fc10ab864262f0cbd8134f056166e50f3
+unix locktime       = 4099766400
+string locktime     = 2099-12-01 00:00:00
+redeemscript        = 0580785df400b175210308c5751121b1ae5c973cdc7071312f6fc10ab864262f0cbd8134f056166e50f3ac
+scriptPubKey        = 0020803268e042008737cf439748cbb5a4449e311da9aa64ae3ac56d84d059654f85
+address             = bc1qsqex3czzqzrn0n6rjayvhddygj0rz8df4fj2uwk9dkzdqkt9f7zs5c493u
+
+ +Code generating these test vectors can be found here: https://github.com/chris-belcher/timelocked-addresses-fidelity-bond-bip-testvectors + +==Reference== + +* [[https://gist.github.com/chris-belcher/18ea0e6acdb885a2bfbdee43dcd6b5af/|Design for improving JoinMarket's resistance to sybil attacks using fidelity bonds]] +* [[https://github.com/JoinMarket-Org/joinmarket-clientserver/blob/master/docs/fidelity-bonds.md|JoinMarket fidelity bonds doc page]] +* [[bip-0065.mediawiki|BIP65 - OP_CHECKLOCKTIMEVERIFY]] +* [[bip-0032.mediawiki|BIP32 - Hierarchical Deterministic Wallets]] +* [[bip-0044.mediawiki|BIP44 - Multi-Account Hierarchy for Deterministic Wallets]] +* [[bip-0049.mediawiki|BIP49 - Derivation scheme for P2WPKH-nested-in-P2SH based accounts]] +* [[bip-0084.mediawiki|BIP84 - Derivation scheme for P2WPKH based accounts]] +* [[bip-0086.mediawiki|BIP86 - Key Derivation for Single Key P2TR Outputs]] + From 76d561fb2c3b1fb01f18126aaccc7d2c95ad2f25 Mon Sep 17 00:00:00 2001 From: Richard Ulrich Date: Mon, 17 Oct 2022 17:55:17 +0200 Subject: [PATCH 022/454] Added the BDK implementation for bip-0127 proof of reserves --- bip-0127.mediawiki | 1 + 1 file changed, 1 insertion(+) diff --git a/bip-0127.mediawiki b/bip-0127.mediawiki index 15c7755f3f..44a90d7991 100644 --- a/bip-0127.mediawiki +++ b/bip-0127.mediawiki @@ -219,6 +219,7 @@ A work-in-progress implementation of a tool that produces and verifies proofs in the described format can be found here: https://github.com/stevenroose/reserves +An implementation of the custom proof PSBTs is part of the [https://bitcoindevkit.org/ BDK], and can be found here: https://crates.io/crates/bdk-reserves == Footnotes == From be340277fcaa57a813a898700c1aef9637cfa90e Mon Sep 17 00:00:00 2001 From: Jonas Nick Date: Mon, 24 Oct 2022 20:33:05 +0000 Subject: [PATCH 023/454] BIP 341: Fix taproot_tweak_pubkey `lift_x` returns `None` if the input integer is not an X coordinate on the curve to indicate failure. `point_add`, on the other hand, interprets `None` as the point at infinity. Therefore, without this commit, if the internal `pubkey` is not a valid X coordinate, the function will not fail, which contradicts the specification in the "Script validation rules section". Instead, it sets `Q` to `t*G`. --- bip-0341.mediawiki | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/bip-0341.mediawiki b/bip-0341.mediawiki index 504514ef88..17a1797c11 100644 --- a/bip-0341.mediawiki +++ b/bip-0341.mediawiki @@ -182,7 +182,10 @@ def taproot_tweak_pubkey(pubkey, h): t = int_from_bytes(tagged_hash("TapTweak", pubkey + h)) if t >= SECP256K1_ORDER: raise ValueError - Q = point_add(lift_x(int(pubkey)), point_mul(G, t)) + P = lift_x(int_from_bytes(pubkey)) + if P is None: + raise ValueError + Q = point_add(P, point_mul(G, t)) return 0 if has_even_y(Q) else 1, bytes_from_int(x(Q)) def taproot_tweak_seckey(seckey0, h): From e24f6859710a8047931eb68788dce0d0400a1569 Mon Sep 17 00:00:00 2001 From: Darius Parvin Date: Sun, 9 Oct 2022 14:36:32 -0700 Subject: [PATCH 024/454] BIP341: add bip340_aux_rand argument to taproot_sign_key --- bip-0341.mediawiki | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/bip-0341.mediawiki b/bip-0341.mediawiki index 504514ef88..9ccf1beb73 100644 --- a/bip-0341.mediawiki +++ b/bip-0341.mediawiki @@ -245,10 +245,10 @@ TapTweak = tagged_hash("TapTweak", p + ABCDE) '''Spending using the key path''' A Taproot output can be spent with the secret key corresponding to the internal_pubkey. To do so, a witness stack consists of a single element: a [[bip-0340.mediawiki|BIP340]] signature on the signature hash as defined above, with the secret key tweaked by the same h as in the above snippet. See the code below: -def taproot_sign_key(script_tree, internal_seckey, hash_type): +def taproot_sign_key(script_tree, internal_seckey, hash_type, bip340_aux_rand): _, h = taproot_tree_helper(script_tree) output_seckey = taproot_tweak_seckey(internal_seckey, h) - sig = schnorr_sign(sighash(hash_type), output_seckey) + sig = schnorr_sign(sighash(hash_type), output_seckey, bip340_aux_rand) if hash_type != 0: sig += bytes([hash_type]) return [sig] From 9df0b19c243362e798186d82e4484a677dc6f854 Mon Sep 17 00:00:00 2001 From: scgbckbone Date: Tue, 22 Nov 2022 01:45:26 +0100 Subject: [PATCH 025/454] update bip-0129.mediawiki --- bip-0129.mediawiki | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/bip-0129.mediawiki b/bip-0129.mediawiki index 8719fe420f..d2c29d9400 100644 --- a/bip-0129.mediawiki +++ b/bip-0129.mediawiki @@ -47,11 +47,14 @@ Concerns #4 and #5 should be handled by Signers and are out of scope of this pro ==Specification== ===Prerequisites=== -This proposal assumes the parties in the multisig support [https://github.com/bitcoin/bips/blob/master/bip-0032.mediawiki BIP-0032], [https://github.com/bitcoin/bips/blob/master/bip-0322.mediawiki BIP-0322], [https://github.com/bitcoin/bitcoin/blob/master/doc/descriptors.md the descriptor language] and [https://tools.ietf.org/html/rfc3686 AES encryption]. +This proposal assumes the parties in the multisig support [https://github.com/bitcoin/bips/blob/master/bip-0032.mediawiki BIP-0032], [https://github.com/bitcoin/bips/blob/master/bip-0322.mediawiki BIP-0322], [https://github.com/bitcoin/bips/blob/master/bip-0380.mediawiki BIP-0380 Output Script Descriptors] ([https://github.com/bitcoin/bips/blob/master/bip-0381.mediawiki BIP-0381],[https://github.com/bitcoin/bips/blob/master/bip-0382.mediawiki BIP-0382],[https://github.com/bitcoin/bips/blob/master/bip-0383.mediawiki BIP-0383]) and [https://tools.ietf.org/html/rfc3686 AES encryption]. ===File Extensions=== All descriptor and key records should have a .bsms file extension. Encrypted data should have a .dat extension. +===Newline=== +This specification uses line feed (LF) control character \n. + ===Roles=== ====Coordinator==== @@ -141,7 +144,7 @@ Whereas: * Password = "No SPOF" * Salt = TOKEN * c = 2048 -* dkLen = 256 +* dkLen = 256 bits (32 bytes) * DKey = Derived ENCRYPTION_KEY ====Encryption Scheme==== From 7aaaa01a9c1782e5674b250db337e630e442c392 Mon Sep 17 00:00:00 2001 From: scgbckbone Date: Sat, 9 Jul 2022 16:56:53 +0200 Subject: [PATCH 026/454] BIP-85 Passwords --- bip-0085.mediawiki | 80 ++++++++++++++++++++++++++++++++++++++++++++-- 1 file changed, 78 insertions(+), 2 deletions(-) diff --git a/bip-0085.mediawiki b/bip-0085.mediawiki index 6e7dd0e95e..06277555d9 100644 --- a/bip-0085.mediawiki +++ b/bip-0085.mediawiki @@ -106,7 +106,7 @@ OUTPUT * AirGap Vault: [https://github.com/airgap-it/airgap-vault/commit/d64332fc2f332be622a1229acb27f621e23774d6] -btc_hd_wallet: [https://github.com/scgbckbone/btc-hd-wallet] +* btc_hd_wallet: [https://github.com/scgbckbone/btc-hd-wallet] ==Applications== @@ -244,7 +244,7 @@ INPUT: OUTPUT * DERIVED ENTROPY=ead0b33988a616cf6a497f1c169d9e92562604e38305ccd3fc96f2252c177682 -* DERIVED WIF=xprv9s21ZrQH143K2srSbCSg4m4kLvPMzcWydgmKEnMmoZUurYuBuYG46c6P71UGXMzmriLzCCBvKQWBUv3vPB3m1SATMhp3uEjXHJ42jFg7myX +* DERIVED XPRV=xprv9s21ZrQH143K2srSbCSg4m4kLvPMzcWydgmKEnMmoZUurYuBuYG46c6P71UGXMzmriLzCCBvKQWBUv3vPB3m1SATMhp3uEjXHJ42jFg7myX ===HEX=== Application number: 128169' @@ -262,6 +262,82 @@ INPUT: OUTPUT * DERIVED ENTROPY=492db4698cf3b73a5a24998aa3e9d7fa96275d85724a91e71aa2d645442f878555d078fd1f1f67e368976f04137b1f7a0d19232136ca50c44614af72b5582a5c +===PWD BASE64=== +Application number: 707764' + +The derivation path format is: m/83696968'/707764'/{pwd_len}'/{index}' + +`20 <= pwd_len <= 86` + +[https://datatracker.ietf.org/doc/html/rfc4648 Base64] encode the all 64 bytes of entropy. +Remove any spaces or new lines inserted by Base64 encoding process. Slice base64 result string +on index 0 to `pwd_len`. This slice is the password. As `pwd_len` is limited to 86, passwords will not contain padding. + +Entropy calculation:
+R = 64 (base64 - do not count padding)
+L = pwd_len
+Entropy = log2(R ** L)
+ +{| class="wikitable" style="margin:auto" +! pwd_length !! (cca) entropy +|- +| 20 || 120.0 +|- +| 24 || 144.0 +|- +| 32 || 192.0 +|- +| 64 || 384.0 +|- +| 86 || 516.0 +|} + +INPUT: +* MASTER BIP32 ROOT KEY: xprv9s21ZrQH143K2LBWUUQRFXhucrQqBpKdRRxNVq2zBqsx8HVqFk2uYo8kmbaLLHRdqtQpUm98uKfu3vca1LqdGhUtyoFnCNkfmXRyPXLjbKb +* PATH: m/83696968'/707764'/21'/0' + +OUTPUT +* DERIVED ENTROPY=d7ad61d4a76575c5bad773feeb40299490b224e8e5df6c8ad8fe3d0a6eed7b85ead9fef7bcca8160f0ee48dc6e92b311fc71f2146623cc6952c03ce82c7b63fe +* DERIVED PWD=dKLoepugzdVJvdL56ogNV + +===PWD BASE85=== +Application number: 707785' + +The derivation path format is: m/83696968'/707785'/{pwd_len}'/{index}' + +`10 <= pwd_len <= 80` + +Base85 encode the all 64 bytes of entropy. +Remove any spaces or new lines inserted by Base64 encoding process. Slice base85 result string +on index 0 to `pwd_len`. This slice is the password. `pwd_len` is limited to 80 characters. + +Entropy calculation:
+R = 85
+L = pwd_len
+Entropy = log2(R ** L)
+ +{| class="wikitable" style="margin:auto" +! pwd_length !! (cca) entropy +|- +| 10 || 64.0 +|- +| 15 || 96.0 +|- +| 20 || 128.0 +|- +| 30 || 192.0 +|- +| 20 || 512.0 +|} + +INPUT: +* MASTER BIP32 ROOT KEY: xprv9s21ZrQH143K2LBWUUQRFXhucrQqBpKdRRxNVq2zBqsx8HVqFk2uYo8kmbaLLHRdqtQpUm98uKfu3vca1LqdGhUtyoFnCNkfmXRyPXLjbKb +* PATH: m/83696968'/707785'/12'/0' + +OUTPUT +* DERIVED ENTROPY=f7cfe56f63dca2490f65fcbf9ee63dcd85d18f751b6b5e1c1b8733af6459c904a75e82b4a22efff9b9e69de2144b293aa8714319a054b6cb55826a8e51425209 +* DERIVED PWD=_s`{TW89)i4` + ===RSA=== Application number: 828365' From 3e10085c09f1322691cb6a22355f30ae54c1eab5 Mon Sep 17 00:00:00 2001 From: D++ <82842780+dplusplus1024@users.noreply.github.com> Date: Sun, 18 Dec 2022 21:49:26 -0600 Subject: [PATCH 027/454] Update Anchor Link Fixed the link to the #simpler-syntax portion of the BIP. --- bip-0021.mediawiki | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/bip-0021.mediawiki b/bip-0021.mediawiki index 0fba9bcf9a..cdc37baae7 100644 --- a/bip-0021.mediawiki +++ b/bip-0021.mediawiki @@ -37,7 +37,7 @@ Elements of the query component may contain characters outside the valid range. === ABNF grammar === -(See also [[#Simpler syntax|a simpler representation of syntax]]) +(See also [[#simpler-syntax|a simpler representation of syntax]]) bitcoinurn = "bitcoin:" bitcoinaddress [ "?" bitcoinparams ] bitcoinaddress = *base58 From 3d243d8a49cefd16d628b85cc3ef0f54bd71f107 Mon Sep 17 00:00:00 2001 From: Jonas Nick Date: Fri, 12 Aug 2022 08:24:30 +0000 Subject: [PATCH 028/454] BIP 341: allow taproot_sign_key with no script tree In contrast to taproot_output_script, taproot_sign_key was not able to deal with a script_tree that is None. This commit fixes taproot_sign_key such that it can sign for such outputs. This commit avoids changing the behavior of the functions except taproot_sign_key at the cost of having some code duplication. Alternatively, one could let taproot_tree_helper deal with a None script_tree directly. --- bip-0341.mediawiki | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/bip-0341.mediawiki b/bip-0341.mediawiki index 9bc8723b76..8d2af3ccc6 100644 --- a/bip-0341.mediawiki +++ b/bip-0341.mediawiki @@ -249,7 +249,10 @@ TapTweak = tagged_hash("TapTweak", p + ABCDE) def taproot_sign_key(script_tree, internal_seckey, hash_type, bip340_aux_rand): - _, h = taproot_tree_helper(script_tree) + if script_tree is None: + h = bytes() + else: + _, h = taproot_tree_helper(script_tree) output_seckey = taproot_tweak_seckey(internal_seckey, h) sig = schnorr_sign(sighash(hash_type), output_seckey, bip340_aux_rand) if hash_type != 0: From 32af2c9dc2d88df12b02409a023d647ee1de4c8a Mon Sep 17 00:00:00 2001 From: dhruv <856960+dhruv@users.noreply.github.com> Date: Fri, 7 Oct 2022 11:59:24 -0700 Subject: [PATCH 029/454] Add BIP324 --- README.mediawiki | 9 +- bip-0151.mediawiki | 1 + bip-0324.mediawiki | 601 ++++++++++++++++++++++ bip-0324/garbage_terminator.png | Bin 0 -> 267163 bytes bip-0324/packet_encoding_test_vectors.csv | 8 + bip-0324/reference.py | 575 +++++++++++++++++++++ bip-0324/run_test_vectors.py | 53 ++ bip-0324/xelligatorswift_test_vectors.csv | 17 + bip-0324/xswiftec_test_vectors.csv | 33 ++ 9 files changed, 1296 insertions(+), 1 deletion(-) create mode 100644 bip-0324.mediawiki create mode 100644 bip-0324/garbage_terminator.png create mode 100644 bip-0324/packet_encoding_test_vectors.csv create mode 100644 bip-0324/reference.py create mode 100644 bip-0324/run_test_vectors.py create mode 100644 bip-0324/xelligatorswift_test_vectors.csv create mode 100644 bip-0324/xswiftec_test_vectors.csv diff --git a/README.mediawiki b/README.mediawiki index a2a5241976..f4a9ac027b 100644 --- a/README.mediawiki +++ b/README.mediawiki @@ -825,7 +825,7 @@ Those proposing changes should consider that ultimately consent may rest with th | Peer-to-Peer Communication Encryption | Jonas Schnelli | Standard -| Withdrawn +| Replaced |- style="background-color: #cfffcf" | [[bip-0152.mediawiki|152]] | Peer Services @@ -980,6 +980,13 @@ Those proposing changes should consider that ultimately consent may rest with th | Karl-Johan Alm | Standard | Draft +|- +| [[bip-0324.mediawiki|324]] +| Peer Services +| Version 2 P2P Encrypted Transport Protocol +| Dhruv Mehta, Tim Ruffing, Jonas Schnelli, Pieter Wuille +| Standard +| Draft |- style="background-color: #ffffcf" | [[bip-0325.mediawiki|325]] | Applications diff --git a/bip-0151.mediawiki b/bip-0151.mediawiki index 005c5527c2..9b91365642 100644 --- a/bip-0151.mediawiki +++ b/bip-0151.mediawiki @@ -9,6 +9,7 @@ Type: Standards Track Created: 2016-03-23 License: PD + Superseded-By: 324
== Abstract == diff --git a/bip-0324.mediawiki b/bip-0324.mediawiki new file mode 100644 index 0000000000..8a8861a5ce --- /dev/null +++ b/bip-0324.mediawiki @@ -0,0 +1,601 @@ +
+  BIP: 324
+  Layer: Peer Services
+  Title: Version 2 P2P Encrypted Transport Protocol
+  Author: Dhruv Mehta 
+          Tim Ruffing 
+          Jonas Schnelli 
+          Pieter Wuille 
+  Comments-URI: https://github.com/bitcoin/bips/wiki/Comments:BIP-0324
+  Status: Draft
+  Type: Standards Track
+  Created: 2019-03-08
+  License: BSD-3-Clause
+  Replaces: 151
+
+ +== Introduction == + +=== Abstract === +This document proposes a new Bitcoin P2P transport protocol, which features opportunistic encryption, a mild bandwidth reduction, and the ability to negotiate upgrades before exchanging application messages. + +=== Copyright === +This document is licensed under the 3-clause BSD license. + +=== Motivation === +Bitcoin is a permissionless network whose purpose is to reach consensus over public data. Since all data relayed in the Bitcoin P2P network is inherently public, and the protocol lacks a notion of cryptographic identities, peers talk to each other over unencrypted and unauthenticated connections. Nevertheless, this plaintext nature of the current P2P protocol (referred to as v1 in this document) has severe drawbacks in the presence of attackers: + +* While the relayed data itself is public in nature, the associated metadata may reveal private information and hamper privacy of users. For example, a global passive attacker eavesdropping on all Bitcoin P2P connections can trivially identify the source and timing of a transaction. +* Since connections are unauthenticated, they can be tampered with at a low cost and often even with a low risk of detection. For example, an attacker can alter specific bytes of a connection (such as node flags) on-the-fly without the need to keep any state. +* The protocol is self-revealing. For example, deep packet inspection can identify a P2P connection trivially because connections start with a fixed sequence of magic bytes. The ability to detect connections enables censorship and facilitates the aforementioned attacks as well as other attacks which require the attacker to control the connections of victims, e.g., eclipse attacks targeted at miners. + +This proposal for a new P2P protocol version (v2) aims to improve upon this by raising the costs for performing these attacks substantially, primarily through the use of unauthenticated, opportunistic transport encryption. In addition, the bytestream on the wire is made pseudorandom (i.e., indistinguishable from uniformly random bytes) to a passive eavesdropper. + +* Encryption, even when it is unauthenticated and only used when both endpoints support v2, impedes eavesdropping by forcing the attacker to become active: either by performing a persistent man-in-the-middle (MitM) attack, by downgrading connections to v1, or by spinning up their own nodes and getting honest nodes to make connections to them. Active attacks at scale are more resource intensive in general, but in case of manual, deliberate connections (as opposed to automatic, random ones) they are also in principle detectable: even very basic checks, e.g., operators manually comparing protocol versions and session IDs (as supported by the proposed protocol), will expose the attacker. +* Tampering, while already an inherently active attack, is costlier if the attacker is forced to maintain the state necessary for a full MitM interception. +* A pseudorandom bytestream excludes identification techniques based on pattern matching, and makes it easier to shape the bytestream in order to mimic other protocols used on the Internet. This raises the cost of a connection censoring firewall, forcing them to either resort to a full MitM attack, or operate on a more obvious allowlist basis, rather than a blocklist basis. + +''' Why encrypt without authentication?''' + +As we have argued above, unauthenticated encryption'''What does ''authentication'' mean in this context?''' Unfortunately, the term authentication in the context of secure channel protocols is ambiguous. It can refer to: +* The encryption scheme guaranteeing that a message obtained via successful decryption was encrypted by someone having access to the (symmetric) encryption key, and not modified after encryption by a third party. The proposal in this document achieves that property through the use of an AEAD. +* The communication protocol establishing that the communication partner's identity matches who we expect them to be, through some public key mechanism. The proposal in this document does '''not''' include such a mechanism. provides strictly better security than no encryption. Thus all connections should use encryption, even if they are unauthenticated. + +When it comes to authentication, the situation is not as clear as for encryption. Due to Bitcoin's permissionless nature, authentication will always be restricted to specific scenarios (e.g., connections between peers belonging to the same operator), and whether some form of (possibly partially anonymous) authentication is desired depends on the specific requirements of the involved peers. As a consequence, we believe that authentication should be addressed separately (if desired), and this proposal aims to provide a solid technical basis for future protocol upgrades, including the addition of optional authentication (see [https://github.com/sipa/writeups/tree/main/private-authentication-protocols Private authentication protocols]). + +''' Why have a pseudorandom bytestream when traffic analysis is still possible? ''' + +Traffic analysis, e.g., observing packet lengths and timing, as well as active attacks can still reveal that the Bitcoin v2 P2P protocol is in use. Nevertheless, a pseudorandom bytestream raises the cost of fingerprinting the protocol substantially, and may force some intermediaries to attack any protocol they cannot identify, causing collateral cost. + +A pseudorandom bytestream is not self-identifying. Moreover, it is unopinionated and thus a canonical choice for similar protocols. As a result, Bitcoin P2P traffic will be indistinguishable from traffic of other protocols which make the same choice (e.g., [https://gitlab.com/yawning/obfs4 obfs4] and a recently proposed [https://datatracker.ietf.org/doc/draft-cpbs-pseudorandom-ctls/ cTLS extension]). Moreover, traffic shapers and protocol wrappers (for example, making the traffic look like HTTPS or SSH) can further mitigate traffic analysis and active attacks but are out of scope for this proposal. + +''' Why not use a secure tunnel protocol? ''' + +Our goal includes making opportunistic encryption ubiquitously available, as that provides the best defense against large-scale attacks. That implies protecting both the manual, deliberate connections node operators instruct their software to make, as well as the the automatic connections Bitcoin nodes make with each other based on IP addresses obtained via gossip. While encryption per se is already possible with proxy networks or VPN networks, these are not desirable or applicable for automatic connections at scale: +* Proxy networks like Tor or I2P introduce a separate address space, independent from network topology, with a very low cost per address making eclipse attacks cheaper. In comparison, clearnet IPv4 and IPv6 networks make obtaining multiple network identities in distinct, well-known network partitions carry a non-trivial cost. Thus, it is not desirable to have a substantial portion of nodes be exclusively connected this way, as this would significantly reduce Eclipse attack costs.'''Why is it a bad idea to have nodes exclusively connected over Tor?''' See the [https://arxiv.org/abs/1410.6079 Bitcoin over Tor isn't a Good Idea] paper Additionally, Tor connections come with significant bandwidth and latency costs that may not be desirable for all network users. +* VPN networks like WireGuard or OpenVPN inherently define a private network, which requires manual configuration and therefore is not a realistic avenue for automatic connections. + +Thus, to achieve our goal, we need a solution that has minimal costs, works without configuration, and is always enabled – on top of any network layer rather than be part of the network layer. + +''' Why not use a general-purpose transport encryption protocol? ''' + +While it would be possible to rely on an off-the-shelf transport encryption protocol such as TLS or Noise, the specific requirements of the Bitcoin P2P network laid out above make these protocols an unsuitable choice. + +The primary requirement which existing protocols fail to meet is a sufficiently modular treatment of encryption and authentication. As we argue above, whether and which form of authentication is desired in the Bitcoin P2P network will depend on the specific requirements of the involved peers (resulting in a mix of authenticated and unauthenticated connections), and thus the question of authentication should be decoupled from encryption. However, native support for a handful of standard authentication scenarios (e.g., using digital signatures and certificates) is at core of the design of existing general-purpose transport encryption protocols. This focus on authentication would not provide clear benefits for the Bitcoin P2P network but would come with a large amount of additional complexity. + +In contrast, our proposal instead aims for simple modular design that makes it possible to address authentication separately. Our proposal provides a foundation for authentication by exporting a ''session ID'' that uniquely identifies the encrypted channel. After an encrypted channel has been established, the two endpoints are able to use any authentication protocol to confirm that they have the same session ID. (This is sometimes called ''channel binding'' because the session ID binds the encrypted channel to the authentication protocol.) Since in our proposal, any authentication needs to run after an encrypted connection has been established, the price we pay for this modularity is a possibly higher number of roundtrips as opposed to other protocols that perform authentication alongside with the Diffie-Hellman key exchange.'''Do other protocols not support exporting a session ID?''' While [https://noiseprotocol.org/noise.html#channel-binding Noise] and [https://datatracker.ietf.org/doc/draft-ietf-kitten-tls-channel-bindings-for-tls13/ TLS (as a draft)] offer similar protocol extensions for exporting session IDs, using channel binding for authentication is not at the focus of their design and would not avoid the bulk of additional complexity due to the native support of authentication methods. However, the resulting increase in connection establishment latency is a not a concern for Bitcoin's long-lived connections, [https://www.dsn.kastel.kit.edu/bitcoin/ which typically live for hours or even weeks]. + +Besides this fundamentally different treatment of authentication, further technical issues arise when applying TLS or Noise to our desired use case: + +* Neither offers a pseudorandom bytestream. +* Neither offers native support for elliptic curve cryptography on the curve secp256k1 as otherwise used in Bitcoin. While using secp256k1 is not strictly necessary, it is the obvious choice is for any new asymmetric cryptography in Bitcoin because it minimizes the cryptographic hardness assumptions as well as the dependencies that Bitcoin software will need. +* Neither offers shapability of the bytestream. +* Both provide a stream-based interface to the application layer whereas Bitcoin requires a packet-based interface, resulting in the need for an additional thin layer to perform packet serialization and deserialization. + +While existing protocols could be amended to address all of the aforementioned issues, this would negate the benefits of using them as off-the-shelf solution, e.g., the possibility to re-use existing implementations and security analyses. + +== Goals == + +This proposal aims to achieve the following properties: + +* Confidentiality against passive attacks: A passive attacker having recorded a v2 P2P bytestream (without timing and fragmentation information) must not be able to determine the plaintext being exchanged by the nodes. +* Observability of active attacks: A session ID identifying the encrypted channel uniquely is derived deterministically from a Diffie-Hellman negotiation. An active man-in-the-middle attacker is forced to incur a risk of being detected as peer operators can compare session IDs manually, or using optional authentication methods possibly introduced in future protocol versions. +* Pseudorandom bytestream: A passive attacker having recorded a v2 P2P bytestream (without timing information and fragmentation information) must not be able to distinguish it from a uniformly random bytestream. +* Shapable bytestream: It should be possible to shape the bytestream to increase resistance to traffic analysis (for example, to conceal block propagation), or censorship avoidance.'''How can shapability help circumvent fragmentation-pattern based censoring?''' See [https://gitlab.torproject.org/legacy/trac/-/issues/20348#note_2229522 this Tor issue] as an example. +* Forward secrecy: An eavesdropping attacker who compromises a peer's sessions secrets should not be able to decrypt past session traffic, except for the latest few packets. +* Upgradability: The proposal provides an upgrade path using transport versioning which can be used to add features like authentication, PQC handshake upgrade, etc. in the future. +* Compatibility: v2 clients will allow inbound v1 connections to minimize risk of network partitions. +* Low overhead: the introduction of a new P2P transport protocol should not substantially increase computational cost or bandwidth for nodes that implement it, compared to the current protocol. + +== Specification == + +The specification consists of three parts: + +* The '''Transport layer''' concerns how to set up an encrypted connection between two nodes, capable of transporting application-level messages between them. +* The '''Application layer''' concerns how to encode Bitcoin P2P messages and commands for transport by the Transport Layer. +* The '''Signaling''' concerns how v2 nodes advertise their support for the v2 protocol to potential peers. + +=== Transport layer specification === + +In this section we define the encryption protocol for messages between peers. + +==== Overview and design ==== + +We first give an informal overview of the entire protocol flow and packet encryption. + +'''Protocol flow overview''' + +Given a newly-established connection (typically TCP/IP) between two v2 P2P nodes, there are 3 phases the connection goes through. The first starts immediately, i.e. there are no v1 messages or any other bytes exchanged on the link beforehand. The two parties are called the '''initiator''' (who established the connection) and the '''responder''' (who accepted the connection). + +# The '''Key exchange phase''', where nodes exchange data to establish shared secrets. +#* The initiator: +#** Generates a random ephemeral secp256k1 private key and sends a corresponding 64-byte ElligatorSwift'''What is ElligatorSwift and why use it?''' The [https://eprint.iacr.org/2022/759.pdf SwiftEC paper] describes a method called ElligatorSwift which allows encoding elliptic curve points in a way that is indistinguishable from a uniformly distributed bitstream. While a random 256-bit string has about 50% chance of being a valid X coordinate on the secp256k1 curve, every 512-bit string is a valid ElligatorSwift encoding of a curve point, making the encoded point indistinguishable from random when using an encoder that can sample uniformly.'''How fast is ElligatorSwift?''' Our benchmarks show that ElligatorSwift encoded ECDH is about 50% more expensive than unencoded ECDH. Given the fast performance of ECDH and the low frequency of new connections, we found the performance trade-off acceptable for the pseudorandom bytestream and future censorship resistance it can enable.-encoded public key to the responder. +#** May send up to 4095'''How was the limit of 4095 bytes garbage chosen?''' It is a balance between having sufficient freedom to hide information, and allowing it to be large enough so that the necessary 64 bytes of public key is small compared to it on the one hand, and bandwidth waste on the other hand. bytes of arbitrary data after their public key, called '''garbage''', providing a form of shapability and avoiding a recognizable pattern of exactly 64 bytes.'''Why does the affordance for garbage exist in the protocol?''' The garbage strings after the public keys are needed for shapability of the handshake. Neither peer can send decoy packets before having received at least the other peer's public key, i.e., neither peer can send more than 64 bytes before having received 64 bytes. +#* The responder: +#** Waits until one byte is received which does not match the 12 bytes consisting of the network magic followed by "version\x00". If the first 12 bytes do match, the connection is treated as using the v1 protocol instead.'''What if a v2 initiator's public key starts accidentally with these 12 bytes?''' This is so unlikely (probability of ''2-96'') to happen randomly in the v2 protocol that the initiator does not need to specifically avoid it.Bitcoin Core versions <=0.4.0 and >=22.0 ignore valid P2P messages that are received prior to a VERSION message. Bitcoin Core versions between 0.4.0 and 22.0 assign a misbehavior score to the peer upon receiving such messages. v2 clients implementing this proposal will interpret any message other than VERSION received as the first message to be the initiation of a v2 connection, and will result in disconnection for v1 initiators that send any message type other than VERSION as the first message. We are not aware of any implementations where this could pose a problem. +#** Similarly generates a random ephemeral private key and sends a corresponding 64-byte ElligatorSwift-encoded public key to the initiator. +#** Similarly may send up to 4095 bytes of garbage data after their public key. +#* Both parties: +#** Receive (the remainder of) the full 64-byte public key from the other side. +#** Use X-only'''Why use X-only ECDH?''' Using only the X coordinate provides the same security as using a full encoding of the secret curve point but allows for more efficient implementation by avoiding the need for square roots to compute Y coordinates. ECDH to compute a shared secret from their private key and the exchanged public keys'''Why is the shared secret computation a function of the exact 64-byte public encodings sent?''' This makes sure that an attacker cannot modify the public key encoding used without modifying the rest of the stream. If a third party wants the ability to modify stream bytes, they need to perform a full MitM attack on the connection., and deterministically derive from the secret 4 '''encryption keys''' (two in each direction: one for packet lengths, one for content encryption), a '''session id''', and two 16-byte '''garbage terminators''''''What length is sufficient for garbage terminators?''' The length of the garbage terminators determines the probability of accidental termination of a legitimate v2 connection due to garbage bytes (sent prior to ECDH) inadvertently including the terminator. 16 byte terminators with 4095 bytes of garbage yield a negligible probability of such collision which is likely orders of magnitude lower than random connection failure on the Internet.'''What does a garbage terminator in the wild look like?'''
[[File:bip-0324/garbage_terminator.png|none|256px|A garbage terminator model TX-v2 in the wild... sent by the responder]]
+
(one in each direction) using HKDF-SHA256. +#** Send their 16-byte garbage terminator'''Why does the protocol need a garbage terminator?''' While it is in principle possible to use the garbage authentication packet directly as a terminator (scan until a valid authentication packet follows), this would be significantly slower than just scanning for a fixed byte sequence, as it would require recomputing a Poly1305 tag after every received byte. followed by a '''garbage authentication packet''''''Why does the protocol require a garbage authentication packet?''' Otherwise the garbage would be modifiable by a third party without consequences. We want to force any active attacker to have to maintain a full protocol state. In addition, such malleability without the consequence of connection termination could enable protocol fingerprinting., an '''encrypted packet''' (see further) with arbitrary '''contents''', and '''associated data''' equal to the garbage. +#** Receive up to 4111 bytes, stopping when encountering the garbage terminator. +#** Receive an encrypted packet, verify that it decrypts correctly with associated data set to the garbage received, and then ignore its contents. +#* At this point, both parties have the same keys, and all further communication proceeds in the form of encrypted packets. Packets have an '''ignore bit''', which makes them '''decoy packets''' if set. Decoy packets are to be ignored by the receiver apart from verifying they decrypt correctly. Either peer may send such decoy packets at any point after this. These form the primary shapability mechanism in the protocol. How and when to use them is out of scope for this document. +# The '''Version negotiation phase''', where parties negotiate what transport version they will use, as well as data defined by that version.'''What features could be added in future protocol versions?''' Examples of features that could be added in future versions include post-quantum cryptography upgrades to the handshake, and optional authentication. +#* The responder: +#** Sends a '''version packet''' with empty content, to indicate support for the v2 P2P protocol proposed by this document. Any other value for content is reserved for future versions. +#* The initiator: +#** Receives a packet, ignores its contents. The idea is that features added by future versions get negotiated based on what is supported by both parties. Since there is just one version so far, the contents here can simply be ignored. But in the future, receiving a non-empty contents here may trigger other behavior; we defer specifying the encoding for such version content until there is a need for it.'''How will future versions encode version numbers in the version packet?''' Future versions could, for example, specify that the contents of the version packet is to be interpreted as an integer version number (with empty representing 0), and if the minimum of both numbers is N, that being interpreted as choosing a "v2.N" protocol version. Alternatively, certain bytes of the version packet contents could be interpreted as a bitvector of optional features. +#** Sends a '''version packet''' with empty content as well, to indicate support for the v2 P2P protocol. +#* The responder: +#** Receives a packet, ignores its contents. +# The '''Application phase''', where the packets exchanged have contents to be interpreted as application data. +#* Whenever either peer has a message to send, it sends a packet with that application message as '''contents'''. + +In order to provide a means of avoiding the recognizable pattern of first messages being at least 64 bytes, a future backwards-compatible upgrade to this protocol may allow both peers to send their public key + garbage + garbage terminator in multiple rounds, slicing those bytes up into messages arbitrarily, as long as progress is guaranteed.'''How can progress be guaranteed in a backwards-compatible way?''' In order to guarantee progress, it must be ensured that no deadlock occurs, i.e., no state is reached in which each party waits for the other party indefinitely. For example, any upgrade that adheres to the following conditions will guarantee progress: + +* The initiator must start by sending at least as many bytes as necessary to mismatch the magic/version 12 bytes prefix. +* The responder must start sending after having received at least one byte that mismatches that 12-byte prefix. +* As soon as either party has received the other peer's garbage terminator, or has received 4095 bytes of garbage, they must send their own garbage terminator. (When either of these conditions is met, the other party has nothing to respond with anymore that would be needed to guarantee progress otherwise.) +* Whenever either party receives any nonzero number of bytes, while not having sent their garbage terminator completely yet, they must send at least one byte in response without waiting for more bytes. +* After either party has sent their garbage terminator, they must also send the garbage authentication packet without waiting for more bytes, and transition to the version negotiation phase. + +Since the protocol as specified here adheres to these conditions, any upgrade which also adheres to these conditions will be backwards-compatible. + +Note that the version negotiation phase does not need to wait for the key exchange phase to complete; version packets can be sent immediately after sending the garbage authentication packet. So the first two phases together, jointly called '''the handshake''', comprise just 1.5 roundtrips: + +* the initiator sends public key + garbage +* the responder sends public key + garbage + garbage terminator + garbage authentication packet + version packet +* the initiator sends garbage terminator + garbage authentication packet + version packet + +'''Packet encryption overview''' + +All data on the wire after the garbage terminators takes the form of encrypted packets. Every packet encodes an encrypted variable-length byte array, called the '''contents''', as well as an '''ignore bit''' as mentioned before. The total size of a packet is 20 bytes plus the length of its contents. + +Each packet consists of: +* A 3-byte encrypted '''length''' field, encoding the length of the '''contents''' (between ''0'' and ''224-1'''''Is ''224-1'' bytes sufficient as maximum content size?''' The current Bitcoin P2P protocol has no messages which support more than 4000000 bytes of application payload. By supporting up to ''224-1'' we can accommodate future evolutions needing more than 4 times that value. Hypothetical protocol changes that have even more data to exchange than that should probably use multiple separate messages anyway, because of the per-peer receive buffer sizes involved, and the inability to start processing a message before it is fully received. Of course, future versions of the transport protocol could change the size of the length field, if this were really needed., inclusive). +* An authenticated encryption of the '''plaintext''', which consists of: +** A 1-byte '''header''' which consists of transport layer protocol flags. Currently only the highest bit is defined as the '''ignore bit'''. The other bits are ignored, but this may change in future versions'''Why is the header a part of the plaintext and not included alongside the length field?''' The packet length field is the minimum information that must be available before we can leverage the standard RFC8439 AEAD. Any other data, including metadata like the header being in the content encryption makes it easier to reason about the protocol security w.r.t. data being used before it is authenticated. If the ignore bit was not part of the content, another mechanism would be needed to authenticate it; for example, it could be fed as AAD to the AEAD cipher. We feel the complexity of such an approach outweighs the benefit of saving one byte per message.. +** The variable-length '''contents'''. + +The encryption of the plaintext uses '''[https://en.wikipedia.org/wiki/ChaCha20-Poly1305 ChaCha20Poly1305]''''''Why is ChaCha20Poly1305 chosen as basis for packet encryption?''' It is a very widely used authenticated encryption cipher (used amongst others in SSH, TLS 1.2, TLS 1.3, [https://en.wikipedia.org/wiki/QUIC QUIC], Noise, and [https://www.wireguard.com/protocol/ WireGuard]; in the latter it is currently even the only supported cipher), with very good performance in general purpose software implementations. While AES-based ciphers (including the winners in the [https://competitions.cr.yp.to/caesar.html CAESAR] competition in non-lightweight categories) perform significantly better on systems with AES hardware acceleration, they are also significantly slower in pure software implementations. We choose to optimize for the weakest hardware., an [https://en.wikipedia.org/wiki/Authenticated_encryption authenticated encryption with associated data] (AEAD) cipher specified in [https://datatracker.ietf.org/doc/html/rfc8439 RFC 8439]. Every packet's plaintext is treated as a separate AEAD message, with a different nonce for each. + +The length must be dealt with specially, as it is needed to determine packet boundaries before the whole packet is received and authenticated. As we want a stream that is pseudorandom to a passive attacker, it still needs encryption. We use unauthenticated'''Why is the length encryption not separately authenticated?''' Informally, the relevant security goal we aim for is to hide the number of packets and their lengths (i.e., the packet boundaries) against a passive attacker that receives the bytestream without timing or fragmentation information. (A formal definition can be found for example in [https://himsen.github.io/pdf/thesis.pdf Hansen 2016 (Definition 22)] under the name "boundary hiding against chosen-plaintext attacks (BH-CPA)".) However, we do not aim to hide packet boundaries against active attackers because active attackers can always exploit the fact that the Bitcoin P2P protocol is largely query-response based: they can trickle the bytes on the stream one-by-one unmodified and observe when a response comes (see [https://himsen.github.io/pdf/thesis.pdf Hansen 2016 (Section 3.9)] for a in-depth discussion). With that in mind, we accept that an active (non-MitM) attacker is able to figure out some information about packet boundaries by flipping certain bits in the unauthenticated length field, and observing the other side disconnecting immediately or later. Thus, we choose to use unauthenticated encryption for the length data, which is sufficient to achieve boundary hiding against passive attackers, and saves 16 bytes of bandwidth per packet. '''ChaCha20''' encryption for this, with an independent key. Note that the plaintext length is still implicitly authenticated by the encryption of the plaintext, but this can only be verified after receiving the whole packet. This design is inspired by that of the ChaCha20Poly1305 cipher suite in [http://bxr.su/OpenBSD/usr.bin/ssh/PROTOCOL.chacha20poly1305 OpenSSH].'''How does packet encryption differ from the OpenSSH design?''' The differences are: +* The length field is only 3 bytes instead of 4, as that is sufficient for our purposes. +* Length encryption keeps drawing pseudorandom bytes from the same ChaCha20 cipher for multiple packets, rather than incrementing the nonce for every packet. +* The Poly1305 authentication tag only covers the encrypted plaintext, and not the encrypted length field. This means that plaintext encryption uses the standard ChaCha20Poly1305 construction without any modifications, maximizing applicability of analysis and review of that cipher. The length encryption can be seen as a separate layer, using a separate key, and thus cannot affect any of the confidentiality or integrity guarantees of the plaintext encryption. On the other hand, this change w.r.t. OpenSSH also does not worsen any properties, as incorrect lengths will still trigger authentication failure for the overall packet (the plaintext length is implicitly authenticated by ChaCha20Poly1305). +* A hash step is performed every 224'''How was the rekeying interval 224 chosen?''' Assuming a node sends only ping messages every 20 minutes (the timeout interval for post-[https://github.com/bitcoin/bips/blob/master/bip-0031.mediawiki BIP31] connections) on a connection, the node will transmit 224 packets in about 3.11 days. This means ''soft rekeying'' after a fixed number of packets automatically translates to an upper-bound of time interval for rekeying, while being much simpler to coordinate than an actual time-based rekeying regime. At the same time, doing it once every 224 messages is sufficiently infrequent that it has only negligible impact on performance. Furthermore, 224 times 3 bytes (the number of bytes consumed by each length encryption) is 672, which is a multiple of 64 minus 32. This means that at the end of 224 length encryptions, exactly 32 bytes of keystream data remain that can be used as next key. messages to rekey the the encryption ciphers, in order to provide forward security. + Because only fixed-length chunks (3-byte length fields) are encrypted, we do not need to treat all length chunks as separate messages. Instead, a single cipher (with the same nonce) is used for multiple consecutive length fields. This avoids wasting 61 pseudorandom bytes per packet, and makes the cost of having a separate cipher for length encryption negligible.'''Is it acceptable to use a less standard construction for length encryption?''' The fact that multiple (non-overlapping) bytes generated by a single ChaCha20 cipher are used for the encryption of multiple consecutive length fields is uncommon. We feel the performance cost gained by this deviation is worth it (especially for small packets, which are very common in Bitcoin's P2P protocol), given the low guarantees that are feasible for length encryption in the first place, and the result is still sufficient to provide pseudorandomness from the view of passive attackers. For plaintext encryption, we independently use a very standard construction, as the stakes for confidentiality and integrity there are much higher. + +In order to provide forward security'''What value does forward security provide?''' Re-keying ensures [https://eprint.iacr.org/2001/035.pdf forward secrecy within a session], i.e., an attacker compromising the current session secrets cannot derive past encryption keys in the same session.'''Why have a cipher with forward secrecy but no periodical refresh of the ECDH key exchange?''' Our cipher ratchets encryption keys forward in order to protect messages encrypted under ''past'' encryption keys. In contrast, re-performing ECDH key exchange would protect messages encrypted under ''future'' encryption keys, i.e., it would re-establish security after the attacker had compromised one of the peers ''temporarily'' (e.g., the attacker obtains a memory dump). We do not believe protecting against that is a priority: an attacker that, for whatever reason, is capable of an attack that reveals encryption keys (or other session secrets) of a peer once is likely capable of performing the same attack again after peers have re-performed the ECDH key exchange. Thus, we do not believe the benefits of re-performing key exchange outweigh the additional complexity that comes with the necessary coordination between the peers. We note that the initiator could choose to close and re-open the entire connection in order to force a refresh of the ECDH key exchange, but that introduces other issues: a connection slot needs to be kept open at the responder side, it is not cryptographically guaranteed that really the same initiator will use it, and the observable TCP reset and handshake may create a detectable pattern., the encryption keys for both plaintext and length encryption are cycled every 224 messages, by switching to a new key that is generated by the key stream using the old key. + +==== Handshake: key exchange and version negotiation ==== + +Next we specify the handshake of a connection in detail. + +As explained before, these messages are sent to set up the connection: + +
+ ----------------------------------------------------------------------------------------------------
+ | Initiator                         Responder                                                      |
+ |                                                                                                  |
+ | x, ellswift_X = ellswift_create(initiating=True)                                                 |
+ |                                                                                                  |
+ |           --- ellswift_X + initiator_garbage (initiator_garbage_len bytes; max 4095) --->        |
+ |                                                                                                  |
+ |                                   y, ellswift_Y = ellswift_create(initiating=False)              |
+ |                                   ecdh_secret = v2_ecdh(                                         |
+ |                                                     y, ellswift_X, ellswift_Y, initiating=False) |
+ |                                   v2_initialize(initiator, ecdh_secret, initiating=False)        |
+ |                                                                                                  |
+ |           <-- ellswift_Y + responder_garbage (responder_garbage_len bytes; max 4095) +           |
+ |                    responder_garbage_terminator (16 bytes) +                                     |
+ |                    v2_enc_packet(initiator, b'', aad=responder_garbage) +                        |
+ |                    v2_enc_packet(initiator, RESPONDER_TRANSPORT_VERSION) ---                     |
+ |                                                                                                  |
+ | ecdh_secret = v2_ecdh(x, ellswift_Y, ellswift_X, initiating=True)                                |
+ | v2_initialize(responder, ecdh_secret, initiating=True)                                           |
+ |                                                                                                  |
+ |            --- initiator_garbage_terminator (16 bytes) +                                         |
+ |                    v2_enc_packet(responder, b'', aad=initiator_garbage) +                        |
+ |                    v2_enc_packet(responder, INITIATOR_TRANSPORT_VERSION) --->                    |
+ |                                                                                                  |
+ ----------------------------------------------------------------------------------------------------
+
+ +===== Shared secret computation ===== + +The peers derive their shared secret through X-only ECDH, hashed together with the exactly 64-byte public keys' encodings sent over the wire. + +
+def v2_ecdh(priv, ellswift_theirs, ellswift_ours, initiating):
+    ecdh_point_x32 = ellswift_ecdh_xonly(ellswift_theirs, priv)
+    if initiating:
+        # Initiating, place our public key encoding first.
+        return sha256_tagged("bip324_ellswift_xonly_ecdh", ellswift_ours + ellswift_theirs + ecdh_point_x32)
+    else:
+        # Responding, place their public key encoding first.
+        return sha256_tagged("bip324_ellswift_xonly_ecdh", ellswift_theirs + ellswift_ours + ecdh_point_x32)
+
+ +Here, sha256_tagged(tag, x) returns a tagged hash value SHA256(SHA256(tag) || SHA256(tag) || x) as in [https://github.com/bitcoin/bips/blob/master/bip-0340.mediawiki#specification BIP340]. + +===== ElligatorSwift encoding of curve X coordinates ===== + +The functions ellswift_create and ellswift_ecdh_xonly encapsulate the construction of ElligatorSwift-encoded public keys, and the computation of X-only ECDH with +ElligatorSwift-encoded public keys. + +First we define a constant: +* Let ''c = 0xa2d2ba93507f1df233770c2a797962cc61f6d15da14ecd47d8d27ae1cd5f852''.'''What is the ''c'' constant used in ''XSwiftEC''?''' The algorithm requires a constant ''√-3 (mod p)''; in other words, a number ''c'' such that ''-c2 mod p = 3''. There are two solutions to this equation, one which is itself a square modulo ''p'', and its negation. We choose the square one. + +To define the needed functions, we first introduce a helper function, matching the XSwiftEC function from the [https://eprint.iacr.org/2022/759.pdf SwiftEC] paper, instantiated for the secp256k1 curve, with minor modifications. It maps pairs of integers ''(u, t)'' (both in range ''0..p-1'') to valid X coordinates on the curve. Note that the specification here does not attempt to be constant time, as it does not operate on secret data. In what follows, we use the notation from [https://github.com/bitcoin/bips/blob/master/bip-0340.mediawiki#specification BIP340]. + +* ''XSwiftEC(u, t)'': +** Alter the inputs to guarantee an X coordinate on the curve:'''Why do the inputs to the XSwiftEC algorithm need to be altered?''' This step deviates from the paper, which maps a negligibly small subset of inputs (around ''3/2256'') to the point at infinity. To avoid the need to deal with the case where a peer could craft encodings that intentionally trigger this edge case, we remap them to inputs that yield a valid X coordinate. +*** If ''u mod p = 0'', let ''u = 1'' instead. +*** If ''t mod p = 0'', let ''t = 1'' instead. +*** If ''(u3 + t2 + 7) mod p = 0'', let ''t = 2t (mod p)'' instead. +** Let ''X = (u3 + 7 - t2)/(2t) (mod p).'''''What does the division (/) sign in modular arithmetic refer to?''' Note that the division in these expressions corresponds to multiplication with the modular inverse modulo ''p'', i.e. ''a / b (mod p)'' with nonzero ''b'' is the unique solution ''x'' for which ''bx = a (mod p)''. It can be computed as ''abp-2 (mod p)'', but more efficient algorithms exist. +** Let ''Y = (X + t)/(cu) (mod p)''. +** For every ''x'' in ''{u + 4Y2, (-X/Y - u)/2, (X/Y - u)/2}'' (all ''mod p''; the order matters): +*** If ''lift_x(x)'' succeeds, return ''x''. There is at least one such ''x''. + +To find encodings of a given X coordinate ''x'', we first need the inverse of ''XSwiftEC''. The function ''XSwiftECInv(x, u, case)'' either returns ''t'' such that ''XSwiftEC(u, t) = x'', or ''None''. The ''case'' variable is an integer in range 0 to 7 inclusive, which selects which of the up to 8 valid such ''t'' values to return: + +* ''XSwiftECInv(x, u, case)'': +** If ''case & 2 = 0'': +*** If ''lift_x(-x - u)'' succeeds, return ''None''. +*** Let ''v = x'' if ''case & 1 = 0''; let ''v = -x - u (mod p)'' otherwise. +*** Let ''s = -(u3 + 7)/(u2 + uv + v2) (mod p)''. +** If ''case & 2 = 2'': +*** Let ''s = x - u (mod p)''. +*** If ''s = 0'', return ''None''. +*** Let ''r'' be the square root of ''-s(4(u3 + 7) + 3u2s) (mod p).'''''How to compute a square root mod ''p''?''' Due to the structure of ''p'', a candidate for the square root of ''a'' mod ''p'' can be computed as ''x = a(p+1)/4 mod p''. If ''a'' is not a square mod ''p'', this formula returns the square root of ''-a mod p'' instead, so it is necessary to verify that ''x2 mod p = a''. If that is the case ''-x mod p'' is a solution too, but we define "the" square root to be equal to that expression (the square root will therefore always be a square itself, as ''(p+1)/4'' is even). This algorithm is a specialization of the [https://en.wikipedia.org/wiki/Tonelli%E2%80%93Shanks_algorithm Tonelli-Shanks algorithm]. Return ''None'' if it does not exist. +*** If ''case & 1 = 1'': +**** If ''r = 0'', return ''None''. +**** let ''r = -r (mod p)''. +*** Let ''v = (-u + r/s)/2''. +** Let ''w'' be the square root of ''s (mod p)''. Return ''None'' if it does not exist. +** If ''case & 4 = 4'', let ''w = -w (mod p)''. +** Return ''w(u(c - 1)/2 - v)''. + +The overall ''XElligatorSwift'' algorithm, matching the name used in the paper, then uses this inverse to randomly'''''Can the ElligatorSwift encoding be used to construct public key encodings that satisfy a certain structure (and not pseudorandom)?''' The algorithm chooses the first 32 bytes (i.e., the value ''u'') and then computes a corresponding ''t'' such that the mapping to the curve point holds. In general, picking ''u'' from a uniformly random distribution provides pseudorandomness. But we can also fix any of the 32 bytes in ''u'', and the algorithm will still find a corresponding ''t''. The fact that it is possible to fix the first 32 bytes, combined with the garbage bytes in the handshake, provides a limited but very simple method of parroting other protocols such as [https://tls13.xargs.org/ TLS 1.3], which can be deployed by one of the peers without explicit support from the other peer. More general methods of parroting, e.g., introduced by defining new protocol or a protocol upgrade, are not precluded. sample encodings of ''x'': + +* ''XElligatorSwift(x)'': +** Loop: +*** Let ''u'' be a random non-zero integer in range ''1..p-1'' inclusive. +*** Let ''case'' be a random integer in range ''0..7'' inclusive. +*** Compute ''t = XSwiftECInv(x, u, case)''. +*** If ''t'' is not ''None'', return ''(u, t)''. Otherwise, restart loop. + +This is used to define the ellswift_create algorithm used in the previous section; it generates a random private key, along with a uniformly sampled 64-byte ElligatorSwift-encoded public key corresponding to it: + +* ''ellswift_create()'': +** Generate a random private key ''priv'' in range ''1..p-1''. +** Let ''P = priv⋅G'', the corresponding public key point to ''priv''. +** Let ''(u, t) = XElligatorSwift(x(P))'', an encoding of ''x(P)''. +** ''ellswift_pub = bytes(u) || bytes(t)'', its encoding as 64 bytes. +** Return ''(priv, ellswift_pub)''. + +Finally the ellswift_ecdh_xonly algorithm is: + +* ''ellswift_ecdh_xonly(ellswift_theirs, priv)'': +** Let ''u = int(ellswift_theirs[:32]) mod p''. +** Let ''t = int(ellswift_theirs[32:]) mod p''. +** Return ''bytes(x(priv⋅lift_x(XSwiftEC(u, t))))''.'''Does it matter which point ''lift_x'' maps to?''' Either point is valid, as they are negations of each other, and negations do not affect the output X coordinate. + +===== Keys and session ID derivation ===== + +The authenticated encryption construction proposed here requires two 32-byte keys per communication direction. These (in addition to a session ID) are computed using HKDF'''Why use HKDF for deriving key material?''' The shared secret already involves a hash function to make sure the public key encodings contribute to it, which negates some of the need for HKDF already. We still use it as it is the standard mechanism for deriving many keys from a single secret, and its computational cost is low enough to be negligible compared to the rest of a connection setup. as specified in [https://tools.ietf.org/html/rfc5869 RFC 5869] with SHA256 as the hash function: + +
+def initialize_v2_transport(peer, ecdh_secret, initiating):
+    # Include NETWORK_MAGIC to ensure a connection between nodes on different networks will immediately fail
+    prk = HKDF_Extract(Hash=sha256, salt=b'bitcoin_v2_shared_secret' + NETWORK_MAGIC, ikm=ecdh_secret)
+
+    peer.session_id = HKDF_Expand(Hash=sha256, PRK=prk, info=b'session_id', L=32)
+
+    # Initialize the packet encryption ciphers.
+    initiator_L = HKDF_Expand(Hash=sha256, PRK=prk, info=b'initiator_L', L=32)
+    initiator_P = HKDF_Expand(Hash=sha256, PRK=prk, info=b'initiator_P', L=32)
+    responder_L = HKDF_Expand(Hash=sha256, PRK=prk, info=b'responder_L', L=32)
+    responder_P = HKDF_Expand(Hash=sha256, PRK=prk, info=b'responder_P', L=32)
+    garbage_terminators = HKDF_Expand(Hash=sha256, PRK=prk, info=b'garbage_terminators', L=32)
+    initiator_garbage_terminator = garbage_terminators[:16]
+    responder_garbage_terminator = garbage_terminators[16:]
+
+    if initiating:
+        peer.send_L = FSChaCha20(initiator_L)
+        peer.send_P = FSChaCha20Poly1305(initiator_P)
+        peer.send_garbage_terminator = initiator_garbage_terminator
+        peer.recv_L = FSChaCha20(responder_L)
+        peer.recv_P = FSChaCha20Poly1305(responder_P)
+        peer.recv_garbage_terminator = responder_garbage_terminator
+    else:
+        peer.send_L = FSChaCha20(responder_L)
+        peer.send_P = FSChaCha20Poly1305(responder_P)
+        peer.send_garbage_terminator = responder_garbage_terminator
+        peer.recv_L = FSChaCha20(initiator_L)
+        peer.recv_P = FSChaCha20Poly1305(initiator_P)
+        peer.recv_garbage_terminator = initiator_garbage_terminator
+
+    # To achieve forward secrecy we must wipe the key material used to initialize the ciphers:
+    memory_cleanse(ecdh_secret, prk, initiator_L, initiator_P, responder_L, responder_K)
+
+ +The session ID uniquely identifies the encrypted channel. v2 clients supporting this proposal may present the entire session ID (encoded as a hex string) to the node operator to allow for manual, out of band comparison with the peer node operator. Future transport versions may introduce optional authentication methods that compare the session ID as seen by the two endpoints in order to bind the encrypted channel to the authentication. + +===== Overall handshake pseudocode ===== + +To establish a v2 encrypted connection, the initiator generates an ephemeral secp256k1 keypair and sends an unencrypted ElligatorSwift encoding of the public key to the responding peer followed by unencrypted pseudorandom bytes initiator_garbage of length garbage_len < 4096. + +
+def initiate_v2_handshake(peer, garbage_len):
+    peer.privkey_ours, peer.ellswift_ours = ellswift_create(initiating=True)
+    peer.sent_garbage = rand_bytes(garbage_len)
+    send(peer, peer.ellswift_ours + peer.sent_garbage)
+
+ +The responder generates an ephemeral keypair for itself and derives the shared ECDH secret (using the first 64 received bytes) which enables it to instantiate the encrypted transport. It then sends 64 bytes of the unencrypted ElligatorSwift encoding of its own public key and its own responder_garbage also of length garbage_len < 4096. If the first 12 bytes received match the v1 prefix, the v1 protocol is used instead. + +
+TRANSPORT_VERSION = b''
+NETWORK_MAGIC = b'\xf9\xbe\xb4\xd9' # Mainnet network magic; differs on other networks.
+V1_PREFIX = NETWORK_MAGIC + b'version\x00'
+
+def respond_v2_handshake(peer, garbage_len):
+    peer.received_prefix = b""
+    while len(peer.received_prefix) < 12:
+        peer.received_prefix += receive(peer, 1)
+        if peer.received_prefix[-1] != V1_PREFIX[len(peer.received_prefix) - 1]:
+            peer.privkey_ours, peer.ellswift_ours = ellswift_create(initiating=False)
+            peer.sent_garbage = rand_bytes(garbage_len)
+            send(peer, ellswift_Y + peer.sent_garbage)
+            return
+    use_v1_protocol()
+
+ +Upon receiving the encoded responder public key, the initiator derives the shared ECDH secret and instantiates the encrypted transport. It then sends the derived 16-byte initiator_garbage_terminator followed by an authenticated, encrypted packet with empty contents'''Does the content of the garbage authentication packet need to be empty?''' The receiver ignores the content of the garbage authentication packet, so its content can be anything, and it can in principle be used as a shaping mechanism too. There is however no need for that, as immediately afterwards the initiator can start using decoy packets as (much more flexible) shaping mechanism instead. to authenticate the garbage, and its own version packet. It then receives the responder's garbage and garbage authentication packet (delimited by the garbage terminator), and checks if the garbage is authenticated correctly. The responder performs very similar steps, but includes the earlier received prefix bytes in the public key. As mentioned before, the encrypted packets for the '''version negotiation phase''' can be piggybacked with the garbage authentication packet to minimize roundtrips. + +
+def complete_handshake(peer, initiating):
+    received_prefix = b'' if initiating else peer.received_prefix
+    ellswift_theirs = receive(peer, 64 - len(received_prefix))
+    ecdh_secret = v2_ecdh(peer.privkey_ours, ellswift_theirs, peer.ellswift_ours,
+                          initiating=initiating)
+    initialize_v2_transport(peer, ecdh_secret, initiating=True)
+    # Send garbage terminator + garbage authentication packet + version packet.
+    send(peer, peer.send_garbage_terminator +
+               v2_enc_packet(peer, b'', aad=peer.sent_garbage) +
+               v2_enc_packet(peer, TRANSPORT_VERSION))
+    # Skip garbage, until encountering garbage terminator.
+    received_garbage = recv(peer, 16)
+    for i in range(4096):
+        if received_garbage[-16:] == peer.recv_garbage_terminator:
+            # Receive, decode, and ignore garbage authentication packet (decoy or not)
+            v2_receive_packet(peer, aad=received_garbage, skip_decoy=False)
+            # Receive, decode, and ignore version packet, skipping decoys
+            v2_receive_packet(peer)
+            return
+        else:
+            received_garbage += recv(peer, 1)
+    # Garbage terminator was not seen after 4 KiB of garbage.
+    disconnect(peer)
+
+ +==== Packet encryption ==== + +Lastly, we specify the packet encryption cipher in detail. + +===== Existing cryptographic primitives ===== + +Packet encryption is built on two existing primitives: + +* '''ChaCha20Poly1305''' is specified as AEAD_CHACHA20_POLY1305 in [https://datatracker.ietf.org/doc/html/rfc8439#section-2.8 RFC 8439 section 2.8]. It is an authenticated encryption protocol with associated data (AEAD), taking a 256-bit key, 96-bit nonce, and an arbitrary-length byte array of associated authenticated data (AAD). Due to the built-in authentication tag, ciphertexts are 16 bytes longer than the corresponding plaintext. In what follows: +** aead_chacha20_poly1305_encrypt(key, nonce, aad, plaintext) refers to a function that takes as input a 32-byte array ''key'', a 12-byte array ''nonce'', an arbitrary-length byte array ''aad'', and an arbitrary-length byte array ''plaintext'', and returns a byte array ''ciphertext'', 16 bytes longer than the plaintext. +** aead_chacha20_poly1305_decrypt(key, nonce, aad, ciphertext) refers to a function that takes as input a 32-byte array ''key'', a 12-byte array ''nonce'', an arbitrary-length byte array ''aad'', and an arbitrary-length byte array ''ciphertext'', and returns either a byte array ''plaintext'' (16 bytes shorter than the ciphertext), or ''None'' in case the ciphertext was not a valid ChaCha20Poly1305 encryption of any plaintext with the specified ''key'', ''nonce'', and ''aad''. +* The '''ChaCha20 Block Function''' is specified in [https://datatracker.ietf.org/doc/html/rfc8439#section-2.8 RFC 8439 section 2.3]. It is a pseudorandom function (PRF) taking a 256-bit key, 96-bit nonce, and 32-bit counter, and outputs 64 pseudorandom bytes. It is the underlying building block on which ChaCha20 (and ultimately, ChaCha20Poly1305) is built. In what follows: +** chacha20_block(key, nonce, count) refers to a function that takes as input a 32-byte array ''key'', a 12-byte array ''nonce'', and an integer ''count'' in range ''0..232-1'', and returns a byte array of length 64. + +These will be used for plaintext encryption and length encryption, respectively. + +===== Rekeying wrappers: FSChaCha20Poly1305 and FSChaCha20 ===== + +To provide re-keying every 224 packets, we specify two wrappers. + +The first is '''FSChaCha20Poly1305''', which represents a ChaCha20Poly1305 AEAD, which automatically changes the nonce after every message, and rekeys every 224 messages by encrypting 32 zero bytes'''Why is rekeying implemented in terms of an invocation of the AEAD?''' This means the FSChaCha20Poly1305 wrapper can be thought of as a pure layer around the ChaCha20Poly1305 AEAD. Actual implementations can take advantage of the fact that this formulation is equivalent to using byte 64 through 95 of the keystream output of the underlying ChaCha20 cipher as new key, avoiding the need for Poly1305 in the process., and using the first 32 bytes of the result. Each message will be used for one packet. Note that in our protocol, any FSChaCha20Poly1305 instance is always either exclusively encryption or exclusively decryption, as separate instances are used for each direction of the protocol. The nonce used for a message is composed of the 32-bit little endian encoding of the number of messages with the current key, followed by the 64-bit little endian encoding of the number of rekeyings performed. For rekeying, the first 32-bit integer is set to ''0xffffffff''. + +
+REKEY_INTERVAL = 224
+
+class FSChaCha20Poly1305:
+    """Rekeying wrapper AEAD around ChaCha20Poly1305."""
+
+    def __init__(self, initial_key):
+        self.key = initial_key
+        self.packet_counter = 0
+
+    def crypt(self, aad, text, is_decrypt):
+        nonce = ((self.packet_counter % REKEY_INTERVAL).to_bytes(4, 'little') +
+                 (self.packet_counter // REKEY_INTERVAL).to_bytes(8, 'little'))
+        if is_decrypt:
+            ret = aead_chacha20_poly1305_decrypt(self.key, nonce, aad, text)
+        else:
+            ret = aead_chacha20_poly1305_encrypt(self.key, nonce, aad, text)
+        if (self.packet_counter + 1) % REKEY_INTERVAL == 0:
+            rekey_nonce = b"\xFF\xFF\xFF\xFF" + nonce[4:]
+            self.key = aead_chacha20_poly1305_encrypt(self.key, rekey_nonce, b"", b"\x00" * 32)[:32]
+        self.packet_counter += 1
+        return ret
+
+    def decrypt(self, aad, ciphertext):
+        return self.crypt(aad, ciphertext, True)
+
+    def encrypt(self, aad, plaintext):
+        return self.crypt(aad, plaintext, False)
+
+ +The second is '''FSChaCha20''', a (single) stream cipher which is used for the lengths of all packets. Encryption and decryption are identical here, so a single function crypt is exposed. It XORs the input with bytes generated using the ChaCha20 block function, rekeying every 224 chunks using the next 32 bytes of the block function output as new key. A ''chunk'' refers here to a single invocation of crypt. As explained before, the same cipher is used for 224 consecutive chunks, to avoid wasting cipher output. The nonce used for these batches of 224 chunks is composed of 4 zero bytes followed by the 64-bit little endian encoding of the number of rekeyings performed. The block counter is reset to 0 after every rekeying. + +
+class FSChaCha20:
+    """Rekeying wrapper stream cipher around ChaCha20."""
+
+    def __init__(self, initial_key):
+        self.key = initial_key
+        self.block_counter = 0
+        self.chunk_counter = 0
+        self.keystream = b''
+
+    def get_keystream_bytes(self, nbytes):
+        while len(self.keystream) < nbytes:
+            nonce = ((0).to_bytes(4, 'little') +
+                     (self.chunk_counter // REKEY_INTERVAL).to_bytes(8, 'little'))
+            self.keystream += chacha20_block(self.key, nonce, self.block_counter)
+            self.block_counter += 1
+        ret = self.keystream[:nbytes]
+        self.keystream = self.keystream[nbytes:]
+        return ret
+
+    def crypt(self, chunk):
+        ks = self.get_keystream_bytes(len(chunk))
+        ret = bytes([ks[i] ^ chunk[i] for i in range(len(chunk))])
+        if ((self.chunk_counter + 1) % REKEY_INTERVAL) == 0:
+            self.key = self.get_keystream_bytes(32)
+            self.block_counter = 0
+        self.chunk_counter += 1
+        return ret
+
+ +===== Overall packet encryption and decryption pseudocode ===== + +Encryption and decryption of packets then follow by composing the ciphers from the previous section as building blocks. + +
+LENGTH_FIELD_LEN = 3
+HEADER_LEN = 1
+IGNORE_BIT_POS = 7
+
+def v2_enc_packet(peer, contents, aad=b'', ignore=False):
+    assert len(contents) <= 2**24 - 1
+    header = (ignore << IGNORE_BIT_POS).to_bytes(HEADER_LEN, 'little')
+    plaintext = header + contents
+    aead_ciphertext = peer.send_P.encrypt(aad, plaintext)
+    enc_contents_len = peer.send_L.encrypt(len(contents).to_bytes(LENGTH_FIELD_LEN, 'little'))
+    return enc_contents_len + aead_ciphertext
+
+ +
+CHACHA20POLY1305_EXPANSION = 16
+
+def v2_receive_packet(peer, aad=b'', skip_decoy=True):
+    while True:
+        enc_contents_len = receive(peer, LENGTH_FIELD_LEN)
+        contents_len = int.from_bytes(peer.recv_L.crypt(enc_contents_len), 'little')
+        aead_ciphertext = receive(peer, HEADER_LEN + contents_len + CHACHA20POLY1305_EXPANSION)
+        plaintext = peer.recv_P.decrypt(aead_ciphertext)
+        if plaintext is None:
+            disconnect(peer)
+            break
+        header = plaintext[:HEADER_LEN]
+        if not (skip_decoy and header[0] & (1 << IGNORE_BIT_POS)):
+            return plaintext[HEADER_LEN:]
+
+ +==== Performance ==== + +Each v1 P2P message uses a double-SHA256 checksum truncated to 4 bytes. Roughly the same amount of computation power is required for encrypting and authenticating a v2 P2P message as proposed. + +=== Application layer specification === +==== v2 Bitcoin P2P message structure ==== +v2 Bitcoin P2P transport layer packets use the encrypted message structure shown above. An unencrypted application layer '''contents''' is composed of: + +{|class="wikitable" +! Field !! Size in bytes !! Comments +|- +| message_type || ''1..13'' || either a one byte ID or an ASCII string prefixed with a length byte +|- +| message_payload || message_length || message payload +|} + +If the first byte of message_type is in the range ''1..12'', it is interpreted as the number of ASCII bytes that follow for the message type. If it is in the range ''13..255'', it is interpreted as a message type ID. This structure results in smaller messages than the v1 protocol as most messages sent/received will have a message type ID.'''How do the length between v1 and v2 compare?''' For messages that use the 1-byte short message type ID, v2 packets use 3 bytes less per message than v1. + +The following table lists currently defined message type IDs: + +{| class="wikitable" +|- +! +!0 +!1 +!2 +!3 +|- +!+0 +|(undefined)||(1 byte string)||(2 byte string)||(3 byte string) +|- +!+4 +|(4 byte string)||(5 byte string)||(6 byte string)||(7 byte string) +|- +!+8 +|(8 byte string)||(9 byte string)||(10 byte string)||(11 byte string) +|- +!+12 +|(12 byte string)||ADDR||BLOCK||BLOCKTXN +|- +!+16 +|CMPCTBLOCK||FEEFILTER||FILTERADD||FILTERCLEAR +|- +!+20 +|FILTERLOAD||GETADDR||GETBLOCKS||GETBLOCKTXN +|- +!+24 +|GETDATA||GETHEADERS||HEADERS||INV +|- +!+28 +|MEMPOOL||MERKLEBLOCK||NOTFOUND||PING +|- +!+32 +|PONG||SENDCMPCT||SENDHEADERS||TX +|- +!+36 +|VERACK||VERSION||GETCFILTERS||CFILTER +|- +!+40 +|GETCFHEADERS||CFHEADERS||GETCFCHECKPT||CFCHECKPT +|- +!+44 +|WTXIDRELAY||ADDRV2||SENDADDRV2||SENDTXRCNCL +|- +!+48 +|REQRECON||SKETCH||REQSKETCHEXT||RECONCILDIFF +|- +!≥52 +|| colspan="4" | (undefined) +|} + + +The message types may be updated separately after BIP finalization. + +=== Signaling specification === +==== Signaling v2 support ==== +Peers supporting the v2 transport protocol signal support by advertising the NODE_P2P_V2 = (1 << 11) service flag in addr relay. If met with immediate disconnection when establishing a v2 connection, clients implementing this proposal are encouraged to retry connecting using the v1 protocol.'''Why are v2 clients met with immediate disconnection encouraged to retry with a v1 connection?''' Service flags propagated through untrusted intermediaries using ADDR and ADDRV2 P2P messages and are OR'ed when received from multiple sources. An untrusted intermediary could falsely advertise a potential peer as supportive of v2 connections. Connection downgrades to v1 mitigate the risk of a network participant being blackholed via false advertising. + + +== Test Vectors == + +For development and testing purposes, we provide a collection of test vectors in CSV format, and a naive, highly inefficient, [[bip-0324/reference.py|reference implementation]] of the relevant algorithms. This code is for demonstration purposes only: +* [[bip-0324/xelligatorswift_test_vectors.csv|XElligatorSwift vectors]] give examples of ElligatorSwift-encoded public keys, and the X coordinate they map to. +* [[bip-0324/xswiftec_test_vectors.csv|XSwiftEC vectors]] give examples of ''(u, x)'' pairs, and the various ''t'' values that ''xswiftec_inv'' maps them to. +* [[bip-0324/packet_encoding_test_vectors.csv|Packet encoding vectors]] illustrate the lifecycle of the authenticated encryption scheme proposed in this document. + +== Rationale and References == + + +== Acknowledgements == +Thanks to everyone (last name order) that helped invent and develop the ideas in this proposal: + +* Matt Corallo +* Lloyd Fournier +* Gregory Maxwell diff --git a/bip-0324/garbage_terminator.png b/bip-0324/garbage_terminator.png new file mode 100644 index 0000000000000000000000000000000000000000..536763e4a9ccc8931aad8e76bc8c017e07282ee0 GIT binary patch literal 267163 zcmV)WK(4=uP)lmzG|G`IFiEmNfWaj53<4Vr*kC_wgZ+^n7{lWu`oq}R zU`#g27RiV#5d=seL=aID0!c_3h0$m<@y<;r?cLqA*7rx{?%w;HbLUPFo|-%R?A@Wl zs#U)gYE>0|*>`-a3Y1l$1OV=Xpzyyme1??1ssiNRC~pj&rKy_}Pd}C(OMhF_klpj& zgyC>2Z$2v02nQz8RQ(@(u~#uYT8Me#bX3I$WTL?Z|X)eeqa&EM48C<(EgTYIJ199_96aFHR>!OC7&O3XsQS z1xQspR28`!L{O*9yT>9xE7V=qykFg0M^$x7JcL^z_eWRCRh)GsKT-!e=EJ$+w8@Bi zEd8xYxgz}#D9rySrXy+ie*%#spiZ`w;4wGiJitWIN(oHC{o{-P0+iq`lJnlE18i02 z9Xbh2O-g}BE6(Yf?^l+?LtWNmDN8zqr<>gtGOUwxB@%6vCm-2CFzXN{91&V#AL z!(duJtfOarVMkVD;(mGq7G#t?v3eS^3hI8C#icTTast3#RcH?0*)%N? zscL+8kjn`vaMaUB4e+DWK%E_bx!UQZ`c+wr6En~ia@@(A{}9?@PEFC0rLR`be;d=W zy6$+waouRx^!8?|Zn&#!zCU`>NyW|8YsJa>bcnXu?_AX$=mXBWP>Poc8iV|mR4f0a z#z%d)5HtwKpzZrxqbcA*Y8*+R$bK8|ufKU*`j0J=hX(y|Z2js%8k`SSeq9ak&XM#V zo7OsFkW@@&L~eNg_#=+S%sF}>ra?im_{8ay4XuI41t+Z8@zR82VuP>ZgbcCHP{;Z! zk3b5>K+!c1T{?c7C;9k_DtCoAFlM~`%eXQTlL4)DtEQh1obk_ z?V&SaABE{5B=Z0_C(B-E99<1II4KU$k#(444D||D*4D)03Xq#EsPfknJ`;l5DEXS! zRe3#AYVpKC1wqEwkEO@bvD2f3UmoUaIL~XGdDGlfL1Cd3I^KpsJ5siR;>tQhe?#>) zJfoOi`;*V=PrUvR;KL+{56U^FQU9={b-n}?n*G#68RR>KhFnyC{(d#iHRPxiTu4#< zh+Q~VrACfzI+oSx>CKBMJHt7?X+2M_%P*6yS(cB$s2q)`HTXJYzxdTvT1kn>2L-t~fXv{H z`vFaMn70VZdaN;Nu82Z^n{0w(wqmnY`G}KZT!GD32F)30S>wmnX`4E6c~iQogc{d< zZL_9g-E{4b_4x(`9})F3$vVKnC?|&UMu$YEkRg>Fkxcs|E%IC*tm&qqdqBf#(Xxo+ zkL)#&GOFhw$H|M~))9FgRhfw|4>MBH$T7J_Ura3x2BHR4JN&0mQiT##Wd_Nn9O!W) zMKIS(1{?dVr^<2Y^@u~>W9cDE$Cq&7;xU!bNnF}sem*F(i1asTb^iY5I*R%!Iqd-c;iBuF*Y5)fOWt<2}Z{lC2I%Walq(E<$c|_ zTi5n=pt2#K0eTJI-JBt&h?(D-)b7VGZZHKVOCSFnymch;!vj}kZeWwSQpl>nxJoqg z!xR;B+I~cSH*-Y@-GSrUd2&EkCKANNSoi@Xk9!^X;NW1Qpd?3L;1`} z%X-wNvF~DYwU1U;jw)-UN@sda2uc|vLQc=Y9zDk%eNvXQ-trM9?$FKYqclw$KhAbDK(bRdzsg?KLXRnt+)FZn89>vc<*D32jC~KgK zJPN36kl-efsPgN|di1AB3pGzUcCVAB z`K`&%$#TOj|972iUWX>*a`OtWEAh(H2IzI8kiu6Q-kNxQ0D&2eCfhZ5drZ>7lVh43 z3CdG-8P@kWiV+>7wnrARuGQ;qoivSwPy}&Jj~p|r^~B3AP%7BBBi@`;mmN1{V}YR6 zkX6z{ip&m(lTKQYX*?WHsC|@`JGz_SThf)1;mUJ95lEdBxz=T}xnjpr*(P;2n)*43 zfqA(lB+(#~$#)029P7zZZI4d0W<-wh^~&-;s&Wx2sBGr&jVa!WR9#2U>5kW7A7O;E zlT0-!b#M%38{CaWj4zI#e2~z;E`OT7JSGE1SBA2k;;jhquD7xlI#qqWR^az}P{f7z z3h?BZRo{UMK;1q-s;W?oLeeH)y?SXZ`QKa8!!Nq@B!!-osyT0J#=`kOWS>WN+!#%+ zEKLfGD@hM&hi$Nlj;i|Ash4`^boAVgxrMUA@?O@dE5-LQUX4l_NWF39`R9Ona=g3( zydJ~S7mo6Pn5=5%(_}V)D<2Nw+%z$>Ppbb+{S9!ItBljY4cmT**PZl zz$ksRC=dh9c1@bl{YDp$B>o2Lo%&wj z)c?{9L9*I_Cyr64 z4W@PZa}uLGE(`#9+9!}*Emj^6q|^pFWY9uWPx=d+PLG|a*d$|b)&@2|u%WCYAGiWj zW9s6OnT^$z1mILWR)*-0x_UFOIpZQ8?*(9VXgkFk6M@2JLc#MBUK{h!+A^m>*c$(UDRGJ6{3uqKVAnQk2TV@-eX{023D@_~mGUL2B+{^hq2{?Vp}M|pcfJJ&xI z-A;tbD4=jF?g$DXEG8plE+8$d_YhlQ=ljnzXwkozv`J4p{O>MIJ~C?drx%iLn#9uDcygA0y5B6u#ru#xc*W7 ze`ICA!%%^>MQmiP!v8>1u94x>SCq!)!h_7}y(>ADFyhq)b9kMg)e-d`4bI$$E3I>s zhu={!Ot3E@XyRJ3x_^Vp#Usb5iyt()&H`}H<)y4`(fSL2`_cf)#}+82df-74W?bB4 z5y$WUD@zXpYOO6|5^e_Mh=SV9Z9df1y}J1iNA=Xt^r#;7Oqt0;k!a8XqhdBF=aW}X zl-}E*CZp7m6CyrRcc@%uPIxMqo8q}GqY%(x&faOGAX0dt!JA$fa3hK?dyswjUY6nr zUDtnO1@R%O!=!CJzV(o%2jg_O!WynK<}(kShKn1Ra6Y*NlSQyP)bLLaU4#|W(C6c*u7Nn`Q(e65|tky&|oWwpinqP zD!TorO5ETY`P-1j3iXL#g+^cU5wk&x4AiR0F*?rtIF-DLX+s5$|E^2NwOVxgXWSO~ zn80&&-9isCd1lB*(un6g8-$B-NEQG*+QHX7m_=+;rbEWG4#YRtH+N0sJHkv`D>w;8 z44z*r8BdBjj}S_owE1gOp2fh!b|R}^3yKm{l_v&de1HZQiu7=gn#g?*Pr;kJZSwAs z1{fV>LkxiI(O_P!0p25ST|v%QmIy$MnOJjb-BdkkLq|MpN&Sbfi;KETd`{~SP$vam zZY`+8djg1Pa)EF0p29yoHVY=7)B@VlHq1Fu3FYrR4LCekk_HSmt?^`62lX9nlb!#d z@^h^RgEH!`tM_q!UKxW8Y&j|~X4jRV7;Mat`e2f60`Gf%P=Kf^_mC@yRV?uM$V)h`6G0K)m=p ztiPe+@}>n-sgx^8DfBwlb$zxu(X?cMk-Tt*f~H47z8Msh!T5eWG6ch&B1ns8vsVC6 zFuy#YxLS}7YBFJKM5#2%2Kn=wWI!|lgJlGrmI0GG^g6*v(OjC80XnYD^iN;&@Vsh4 zJeo3~0x%DY7_;fg`7M{)o*Tw{0j+ILA@euA^pK>7ySx+9cSD!xkaSm4ld(~}jsyP> zN>mPFuW`@3c+O@HgH+V=l|;;Ric~_b{5f)xH|O)TZE)TsMR|g8?zy78`h)Yx*AM>e1hx3) z^rLBn=G~g=mMW{mI=era_&ZJ)>BP^mJe!m+>6NL1uG)Baq#K?Hw!ZX7)&jsWM$f z20wHS`PaTq8c)4eF9XJXHE!C8(-81=Ft)4a7|@i3^`vDW@aiZ-oBAJ({?aHn|85K|u9PNhscp)pNh1+!{Pk zzCU7$X_9Q#1jn}q!)F~OjsR=QnT8PKCfx1y7Qlwg-+R+K{JH9-jK2@W{8)L#sJnB1 zdh~Y0WJT98?xY2GBtCDJ5HvaH1}t1^wAn@PuJDRxhL2t?9u+)p&XFmp*P66pgw5Cz zK$ndrIEh3+Fht7w1a$IK7S8pq{&=X&YoUQi@m-lX__b^nbfB$^Q=f;7s^Ow$qzu3O z=JMG_V&SA7jmmk@&C8~39Hy!NvO}(-IW@?m(CXJ^nY5FX2_Z<3(UiuzoT&Vn*LEn& zHoP!-W%R(>It}vFRC1Dv{&k%Y0Qu{Wn3BIfjq&tE^?aC-bQ11Rj`6XUoPQta6pt=R zFlOHke4LtEI%+qJbS=M3wEWne@3t|}d>~|V#tw`I!*mk;?Vc!4csZSNDT1p8T4i~yLqb5t5gf_0EEkjZ#h+BgvN7%8FyweLtx z6RT+dCy*$qC&)z$$SU!AFCc-8O%LS3xfgNP||O6L@tkK zLcx4K{Bo#@`BsI8Q)FNS?>s&SE~Y=owS4gBN~hl}AYe2NVb0~@9w}G*k32CNG))9S z8IcEsDp~H({dif*PqdlwICDiU+!E{1FJAPG6ZC6FCHC1C^Wso4_!Eu3jIWQu>rvMQ158}ks>!zkT4fJwHkPK4dr(}4v6OLlu9aoV zVo-R40yxwa$vH}Bz&t4oMuS40ZpDgtk*&oWIqIj{dB6-;G^9~{)X)rE=BpDC(>;(<) z#qYVcrCA(rjHnvdB1+s+SMoiT4i1hcFpXV6?=9(A;Pc*)*2#uPMViu$inLZ{e~tF1zKjT`pJ4 zWxHH;t5x51?W&dD+OAg-u~rqTaujA2X(%&uB+BWLkP1ws3d8J#6&nM9E2FAaWfW?v z%E<{+8LkW)Q#CbLRn;_AQ#Z3&)y(SItZwGbtZ8QRW;Scwm3me;wK0{cDqj$-^F=*hY;AAP zx3*@Bt;P2Ce6i&uhp8)LYA10#ZmPEo6e57YhUszu61`zzcg&2=8C~FI21R_PKqE(C z4XQ&f4sz7bobW?V-4tw^4TzG{%O8=$qf9FYY_ynSc*1+F1>n+9LOzzRddjghU71u8 zH`og_@o=;NqDNK3XJIW+rhaGWPw8$LE`IJWV|e7^qa2XVT^+SUf1MC8e6YuQK)8H| zH9tNne)kzTgirvgq5`qK?b>#AxZK~rytli%fBDkE-tOfK=l3pL-rwD84-fmUx4k8h zst_?$nV1Odft@N;2=SA_8yrk}=bKRHQc)&0M8+^P8)9ZM%2` zj!{yD9eD*RA{lT)RTOH)Ii1wHKPpyKR7FHsMO7fGP%sp#$*l5I%48JkjUL}JL`@zb zu~0?dLe&CRR0w+l0RaE$7)iXKWhN$5*KABx*QToKrm1GlY(8)1i}}`Kv2%Ls)b`ft zQ(N0Ri>>Y1VykLu!x*{Rq1WtckSx%aJjd?yL);6@}=F27xpe(+`V{d>2!H(#X6`=D-WQ`V2Y}` z14UIR45TvD7@pNtQ`K9udNG@y+FI-^7Vgvi+uB;}EM|-Od@*a9x~?lzSIo>c698uN z`gPFnQ>11jCj~!7m}riQFDG>uDhhTQGoTPvQHZJvL`0$1iYmma0$tZzmA37>zVAA_ zYP;oXb+GD|ZF{&}ExXlW+a9#5Rokxm?r^nQ_5G^rR&Cc=+jf0tr58sqwJPw%vL_EX zBDTUrEn0hs!m70_z|w2z88{My2vjjMo4Pht)y!wrY_>SH)65s!r%pAC#m?z7v#t5o zV!N8vO*1!DZP+lIVA>J9Y)}cRMXu)iU%>)Q-*dhWwD;y?bWBn4P`)Wuh{*LCJ`}`7 zCk7Qi>ct4lIS|&0WSe3EX6;JgaeBxQHmmFj6#C5%bo*vJ6X`#SPh@h502{(LfIOgZzL86k-NI><6be6N3JyBGPs3;o;%_ z-sSzvyL-Er4lZBby>Maw(xt=Q{q}HaJ8P{4NJW^LREZcOP#A#`5ZK8N!>CQw)MnAl zPH)Z5Y;Rw8`qbI2o$Jq>KD%@3%<09M?XCH&S~QKRs4)zv2`(KcMpVSAQ^iFAl@&zM zlBy`Va2!$<;V7NsE*FLJ8PF*B)I~zfrB}?oqntTkk>E@wB61?JassAOCe})cShs4X z83E*GiouSy?hV%zQK*s?RiNvwigs3dYnNT$w%tM39xhk=%hlfDa(}tp+dtf29qt`2 z_Yar*tMMk)wB6*-qcM~)wN;6hKY!nnWDQs=l!V1 zM=16xIZ>|8M6r-*Q(j09hLEPLGij5pY7ZSnfFxsrNY$>}3+N$E>)`vCkUd6_!Ntd* z|Kur0;|cn0(&^*99HEZ@b@xbAPo^F(uNDhEDP0SDz#w7CsS(h>Qd278-Y1w_Npm z%jNF=^3vYHrNhHZdwYA!!^`{o`>W;ta(UQxhi$v+`_5V`BH~@-s;Xco*c>p6sxU-^ zR;ntXHmC{!l)SHvn28u{42Y__BEwbFn5v%5=k=_aZEZEP`Fyce&u8=bRz081nt9y> zIZ;){_*rp3of6m&xwRX>-uF|8-UO1$A3BUANaf5W8jRv>+FXg?G!YQjd_n<`3!ev( zsQg}d%|bfT2*_WdoQWPwSCS^BYH@qhs|e_jJ2^M@}<4YmoHy<;Nk=4FFkPn;PP&Jxa?M~ zf>kUrL)EZxLWM*tB?3di%!X+`tGDO%HQU=aU32bGBD01|XOs;JVTIvY&=w6?1<8z%S3M9jt*u8gTFQ&&}8S4~}2 zb=5ScuIk!}hq|h2Q`J>nu`yLu8)MiQV+>bSRT*QP1Iw^sCT7D--tsUUl3^w=N0UHB z!Av5m>>Wk6Z8t6iTbCXj`cF!b{Ng4Y3J+l81COPXrz40u((-k9GlszA`FT)I5qOyq z9A6EQJYm3S+}Wlqi=qdH9SBg|pvKoKLXxi#J6oGT3})h>WQjuizFQtH_x3LDUbuMi z!uiV=E}TDiZvW!$a(}#sR=c6)2q7{kO61whvMX&6g^vO+|ibIDIR1j|0sllQ@8l4sxebUH`00Sh!cjO)CDEhl(I1TH*DA;q9 zO+}RK;BYOp!PgcF2)Zox#Y;>9n9x*cD(q|#Xht+=x(-B4tO|e?DoP^S_0o3T{^4?W z?{Ihj@WSQ2O9zJ+_V)G;4t5U@4_586Ygb*r>igE(-r5c#ssa^(3%GR?+KvMS>bx-` zPB2JIJrE;we5` zo7yb4W>wY9wzkY{(QGa1`Bt--bJJ{{KF!=b0%4#z(qx$8zi7!?$E@4K--`dE69quY z!FghLoansQV5F7yLC9?YM3kND5|^U70ZvNl)Jh+)!W`rBvZa#F`|2JRE2_3{mxud% zmoHwrbn$`97cX3T;M}Ei=l6H_yXB$nReBeDBjlX_N~~%?1ZGfW>bl~co!ND#wr;uh zy2sye?GvxR{&Ck`bN2M9#oWv)CRjj4t&(#=E1^{p1ce=dQ3c2VL|`9$q#41&ew`jV z+(6JMTE$Z$=-H%-LNEv8!MUw_0_F%jN#zYWMJPcmLq>{=weCa_{hPZ?!sHt(?GEc3xWa z){4TaxDX>%^3o#kNHW*RQ#=H}g$*;JwxtRt6{WP-h0_AO1x0{U_pJyMSrt>kiq5x9 zJzs2Jb7pboniE<8L!P>lG{|GD2&5i4cAiHX4UeTOOGCouF_y)sa_|(#cT^^0KW9M^ zQ6bIU(m{U>L3MHMf7%Ryl;e#6p+rzHoQ@A-g%zvq>fm7SVDI9E^XJZ8ICuZ0bLTH# zxVSnvY?mul>ARl6Dh^SE94;#uRDtHRYP*@8-PyY7?Aa&ZeA5$dy#DdmUwiH8#rC|Z z+4+Bc)Qf7Tx>8Y*xbl`e5ug(MSvl!*cn!Ev1}%BJ zEBDRNc-RF25#($Z>6-4wN?~}d6zY@Pb@<1kUY;&GlOQ*5G*rY>G1vUZfFGCb!7%~~ zqab*(IJ1AUmItFGWJ(BPjMTHVSc!XBWE3H$icvSTAR?NP&e^*d!?dnbK14;dx3+Ej zRofo4-NACTf3UoKaJav0-OR+nYPIazW!tX$Zq@Z|-?e?;_I=;mUZm@-i1Z>NZl+1B zU$hN{!jb~8c{h+`{h`j<1*sb)JqX(GqT4+mJP7nhpkk)t4YSN|jrx0S zbst0j2a(q5Q7)z42@0kgSBN3{#jw(;JhD;--i|Uwy>OrvIJKBu;H7`hfg;;>d3ks5 z{`>E`aQ{8$-gD2T`ybf9u)A9I(sim(QD!Dl2DyI?Duyw}G?m$2%+74hZ#sSUi8oyP zT!5URUM@S`*O+}E zaUjW%s!1phfGU2;I+7yZQhcQlCy3oS9_G^nzf|ngr6}{X>Q>JwtW{BU0mHpj5$Ub%t#rNZ`o8V@W!EiN-E!6LE!%_T>TtO_ zY}>BsA@s3P^mzJL;CtQF1<8Qq2DYx8s>YNvSowlm_Uimc`=L;m?d)1|vNckmfXWN>W6%AYIr%sWn)V z@jOl6Kp}oGm4-c=R{DlAFw5`RIiF@3<~u?D?7;}VQQT|VsUx3)bDimyYZ!J* zM~sS?if3Z${oU?Q?s(JB{LvrX{_gv)Xb#|t(j>}{)yy>t#C?CHt5G$r}_<)wo<%K)g|uW+ zmHNK7=uK_tlRy3i54QlwkzlIpCU|R8Mw_oZmX1!F26Ns`X*8F5zIv$4^x}bYxtwf_ zc@i?7PR@Z`sfii*4d?}`qzW=>mWRt<{i&bdYAPs1mjBnsedGs!;LY9M1+oey2D^=Y z6vQfEqatp_m#ZX$#d}TD3?doU+}$77uo9r7!8zo&%tb#<=dxuJYWk1}QI=As@8$U< zH*}&K;*z*QF@=U(rg4p9ed69kWdkUv1Stm^ea5^qY346x24x24siaA-)zA>pB>%=w z7mdxpIKMUOLjR`_)nPI9nq2bNX++6Va^%)ilm~$d$($g-trH1*RiRWMC^;s};X>qQ zm3_t>9?A?HCcqe@q9m;m`)~_@VIOW#79LAiISnCwUDDALK_!dvC;JPuzXaom!Rn<~I92P`_QCDcNeodqj8->=U?rry{zxVr1%@)*k{lEFr7cS3T zm{m1|M8#CKNKXVfN5654W#Up*?+YsGkb#t6ZNpJ{O0`L&ztD%{;4O8^Oq12(V)0Bw z=!v_f)|^!_yE`Ew29G7f%)EkbHCYn1gka8$DxC|LV!45@Usz}mC22+lKfN8Y)q!Bn>psvDvP>{~ zIJGn}hbH2U_ufeFM_$b4;hovQUO12;6*X6Q9>9ZB(~kk;W8FeMixv=~qbKuQgM4Dn z1J!ojt-pQgWDQI_9uJYw@*V;H&_F=JARBgkk6wGX5pfarP6%pY;sQ>4$>gg?i*Xot ze~04Uciws7-1(Y~TDkf3&eNWFtGRHmDwttKR4j-TmXyI^xMhoSDURZ(bY~HSiWsF$ zahzq<&G8>OmgOuMLNeW(!-z}2e~;$v3$T%ulJca?&5_$z8s0>y66W;H0#kKd<4}06 zfgUR*oQ?`90_eM zMt@vji_%Cf-bx*x2?-ZOFzD#WC6UWFQNEC1>7sA&fFBWBsE*B5)9*lUQc?vo*^?d# zc{M%0@Uw!PyKYy{mr^F;8 zV*Qzf5CB99aXSHfkYVC{Q?k;55XTv3mGieKt6-^#WYHrrzJH<#88Akl{fJKkfDADv ze2dpJWGs3rX+LQ^BwakyjYrzq2GHTN|G7~kM2X26{@Kiw^H+z})OPQDR z&2X3>cXBtdYuqNJMC`(|Hj<|alyj4!5N$!?1!!X)W1 z46p@7(kqC)1oHk%M%pBUNl&;E`08WhKvh5HO9~n&k(kP7vT?DaCJ}!$7ABr~FHM6c zkH^wPO6F|@(ZcZb*A!rXT$J0^mN{D}>v-F3!W`l*a_!HTR94mpwh#zR%w&mKl+<*4 zd+&bJn-`{{uHC8TfA6E8-|ikPOs#I#SCzqT&ovgeyfRrB5QSTa!vsmIO0yBf1i(!@ zhd{!D*AkR^H1Jawg-pzS8i`!w8&+hM^~hj|51+_;Y9l*lT6ux}P6UUX3cN4Z)s~|& z{MMpkl)p4F$|lC%#^LDZ+(TspV!IyF?755*?qRQ5Y6z<-Es+KRs~xHh2B&&d8tqUpRCw4+< z!_{N?@X0QCY9){gs1%jooFJk01D{7Q17i%OtB+<=12GUj=2$qz{50)IkQIU?N_r2p zk$_rIE3U8xLTq!qAF3Fm60!#P24=G?8i76s@vzh(FksyN4I%6J>8cicFUS%~#EJyT zSK;`cOw1JYfY2)%iOzKVtspkws3P-q%S>Fi^VC z?f>}y{<($W`D}J}>+E&gi)(fkXSQdH?b&=bs|g@w0)vezK}k7A`7pUL0Ab}^OA`v` z>SYk7nj>x;kS;tZ9e3`=w<<~i&F5hwn+`jM!c>IQ5yK_}MXv-PE2c^`>Y0| zb#wM)t~aL9RBE2c36#B(fA>yzB*i(xQQ6RP9K}=S5s2#f0pUoSY+-iz^p3&I&>(=q zWJ@8d9S#F=DmNoRRzv?<>?SIl>)xXk;5b&8VwHor>iS6i@$#Ha!sgTtuwF)d6+=?v z7J-f;U_d#rqxh|olLZ%lh%;>xQ%kQ~BL^T_RA%ax=rnlU2 z+imZG%bFBWW>kh|O*Nm*u06ed&GzEjQ>Sk@ed^ln#dW7oU4Q!2sjaP3vqjT1?#y%| z7wG6p;aB~|)868_i{xA4Bsnm1M zg+gxg*<3I3Qa=cO2eVN?Wbc=T6(x!drg6g#(XPSnEH!~UEr?Y8!D^bKCZZRLoInTy z32^am=-ts2AR!Rcf*9ymCyfH45o=vZin-(rGe}2R9Dz33SW97SL8~aIrV!K~$4i;) zh=L+s+pvql-@a6kx*&Sq-66u5GWE&}2CFczN?cV;)itM@-}t$gz4q%3CtFS5f@0W0J(FQSlx(qLt6*{TXvF01*nKbrQ*uergs{+!onTP!ELVxE47yn z-hJQRSX*VntfF~swinIze0FAM>(th%Gg~{SPi>#t**?89JF~rYYPPk#HCxPPO;y#V zGH$D1_qq}jIJz-Zp-MJXA|43hLD}ykk*o3mvI!8cG8f$u1~USowd{xzvjU7|Ib?x9 zt%m)XEI%pvPv)Y4F(uuSr
h`KvC^)v>XBT$j0E_dz7$e3o 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

j$ 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

{5v6dRw- zR_pgki2y*|KcKbV$JbK3?Avr}_Q+f>&lW$|)*DIm$vpHaq#Kof*CLZe=?0K<-hYId zuSy_JHXy`39yAEOh_zIq@G9Q>NmT`A$q>B8*;%*zec{F21>NuVHPT$Guip)`IT{JF zA0<<&RD*R11h5*Vt)-RC!Z1__miVzJo-b`V)!I1~5mLhnIAw*9UoPzSbohfm^5cK; zuYS+NPrt}TQE*{QQ4Wg!=3r^7zqDEoR(d^aESQZoFg@5_(I2d?ZfzYnba?CV!Ht8f z>jxZ>?U|#;4pah93}eu&--~A=K{edIJR0qdC%c2y!7X>+4`U~FEu^a(1^}x?#QO7Evrzo{1zFM!zU^2UAan4h+tC`feqL)F>br-p26y>MgtU) zC|Ob!A$3NMpStDtSHE`Uz=l_;>Zy}zb#3+JEw`D{C__~s688H^TR>*Zy)CtA11x9M zR$4Pa8qc(-7``%yVqY?GluG&I^VHN@e=;nUy*t!n&howwmFAmm?UOkZx%&wQ?R?SM zj>wCey89Gv*7iMK*`J2 z!(GDuq||r^MeIvxO&6(9So44?p%%YFpk^}XJ0sf-oPkaGOm-cR2p3| z@}A%O;9vji-}0XK|2~N=QP{#7t$fW^4S{-wEP*W-s@||6Lci!Q4F=-8Rb}Hni$YW! ziCj5@3<2MvkhC+sRVc6d@-l7LCo~GrnoL*4V%77+)R9Tdz+X^HF%Z9y>vrN7^JM%~=-`*c_hTPoy@L%4(Puj;5w<&PJEzrN!Jd zcQaQ%)VWAm)wEMen>k%*ACA*N0?-@ui3tiPQhDDX@wrCLv^$lE&U$XgrkFLOeJ>W` z#_OjW1=pXAv^eH8ALW_azjBS~yt#!l393_@hlv|j@}kmEeX_WUs;{MKt>9Hdjn^B@yu`FJT}h}&E|Q2UIgxM&ToP;s&l9wS1tlz_+|SpgcoTd!jZ3GdCL zigUo!XaQ;klZs(JsEA~mx5+}UO~?*!uK=spgB!Z9UzeZw$nXAvhO>HX7nTD+gKOc!;AJZ1={^VAGIQK$TbT&P2T z4W0>&6DAg@POF2htGCn1WO;4vu6thf@!jd(_IVgvPe%R0+PUY?IGLQd_g;gZ2bc_0 zl)%w-KeRn=rqh7_3_xmH;1wtoy0^D0&U55riqirxTdZ%aA3lCuqrWgnD9}kHE(Q=b zb4CmnP<7$_f~Xx@n}4(JjAnbLR%`@Kl|kfK_k>g$O~9(nu@?$r1}hUoSydpU@ETjE z0I4b~Bi{`%!^ld=X>$KG5A#ALQ_D1|)LD_;d~a62BNAEUyte=A_Yn7dlLg#s!ed=>R&5qB02=h~y_=<&7 zr@7G%+yJERO+W`G?GQ;Ih^S~Y+f!9lan1!JpthLmhU>_OcieOLBM(jLdOVs|pwY_u z+PP=W43?IT-*LC7D2FKk`6fEB>C3dDI+tC$vWfh3rgAyTkGE3$JFY{s)R?!fL-b9(=28dM zv=LL3WuWAnnyJlJx2Y<$?DyFiU)Lf!t}9w9k)eRLZjCh|W3qX!?o@cDEpuBHbjCLS zvj0?Iwu$?RmFrC=Ua7P|uH_;r&xcQ44J>HYTq~)q6(RU>apdxDzft22%0y7nx=MQq zMEI3f4CX44{Z9+qJ73Xj4b#Gr(oUAy5~yYO_C`aYIbSp%iFGy4+Ps=GFIH7$FvxpP zuDbW|(cgdi*{kBjlVP5YMnCqi|Ie+hwc+r}aDo9Xc?glfa7o4Mj-PtdEn9wX*Vcej z^{h517dEUQfI*gwHB_)EE%lApa2DKc373oyv8@N#v8br?E0KLD%}l>u$Z}cOHAhgFULEEIm~h zE?x!^85Z(@D$$DVf5ofsIa$~>?{~SdqT~Q2mT-ijC|H9diZZ~;WR0QH7+cpRO}z?} zdQyRS!yc+ysjIDp8V40ttgf$Y9yqXm;6Q153@-bHchy~Y-SLr!9?@#JyuN<&_FJx8 zy|{Df!eD82IvI_JL(?mt`@~aA{q^4Za&UqP5yIi1vm{qLqAq|#5W-$QOfaBoI-QQD zL}CI(83Nx`6L(p)dN=)ieGC%y_N8kPHzb@m76i~u5v&MeewmJha9RZPpnS_}$I_+wSygCboOoy^Fp%4{r*b%@K zMNyXFh@a7P+H3@o8n$@FwowlI2;l5j1GcEs*iNZA+f!EA>qrrx;dd!a}!sG zeQq4wDlPxzKl=G=ID`)q&xm5ma^%=LCGEfyQTWs<%99)U&_v1zQE6=f z(6omVQ8Zej{b&_cBH$Qsk@6Cnxk+pzB|-!;+YQ>Xo9Qj(FY6@g{>_$<3)|B>a(sNBo{WO5`odLKy;POe zV4}CgAZ7A$V5brWt=QuyPAm^f8d!1cgr?(Kr51Pq#!^lC(&ekij~uz_#Gy0i_n>BV zW8?U(x1WCUF(&d5lhMI0neWB2>o3j9xi9y>J zF0&z#so|2WJ$2V@y}>{r(S65LI$5aI{h9_NU1}68I-5>Ycy}v`<(@S}mPZ#Z{?GsVGhh9;{;Jx(k}^RE zD$o!vuNnA`8)+w4-%b=$)suaZ+EC(l_CuYnXeh9;2ek!ef>Bd&8&Xf^TzG@&dKn2# z$Rrul>-SVi1XssHB@Vi^v17$bBwAUdilRP=?Mp2S<#d*xV~(aPZlFc`WYQUV_?ead zO&#{Vv0r_3pP$#A8O+SLnnZby>~`l@GRwB>KuSy`VQNivT_f0t;)IyeR?%58sk^mh zw`Hl`5J1wPPQbu@$?bOdDo3-5|ah2hALC-r1fRh6$5f`R(Y zda^tnuX_}=cU--4%b>rpzN$Q!Ol{?LG;wt$-b1~CTJh|J zob$u&;jPC`F87Qn7^OLO>rGoX9d}S`dnyVc?{qwwKJl@K{bXW|As`)k)**_fLn*dD z1V`{>cU139)q7$dtPF0u@6N&Uide2y$V6lie0`7tZX595jOHx0q;W{fIIah@Y`q`0 zX^ktX!qLr>03wB`XU4mK!xgs zGwl9ZwpsY#+qpAjmRh1P`uXW|8V?UWrN2Ag1-n5!}@4c&KJmk@Kxw~h!Cw51A z+q!ny9lPjHUYOi-xw>nwy0dRr>Uw8quM+hhRSgvqA@3#rIfbXn$z(F=S#xl8tza(t zJ?L+3XbWKQ9w1L|*9YzEa!OqpI-q!+JUf(=* z|J`O#*6akLP|*}Rm&`T+FcSdM)^jA52MQM(XwfbVCRRp@=j{Nz*+FZO6U9AElmW1) z=^69BUw`L=@BOekF-%(5Ao~@6;!pn{|LxzeudR=EeNhxtyWyqn_rCRQ+h;Do1&1UK zn<0z(@b(-MI%9cxg@^&#n^qD7zcmuaexkaG*XRnewrp(#)_zOWZOtiv&rH*4?#p}u8iSc| zo$lDL7B5q(rs^#Gdl~P28Fk$c|KH#nqg!LHjsy34FRpeHP2zK~eqQV6U$rv?Gj+XA z<7OCP=I_Q5bx5n(o28vT&yP#8bvHi(OLS@!S0oczDXD`8!PK=8?=nDX#}&4ScI3+Al@n|HtJe(o1V z-xh_1_oUtsUp{~Skq>`FCsU%d6;$vNBTdl(?H(bjVws5O^7+eL@PR`IZ@uSkHU`!x zKqiDkGiRfagf=yiS(@WV1vJ}lGGx#+2+{nOG{P)rrpW;zu4O4D0i<9BP>UD#?|aAZ zJoLNoA263aTNKt5^u{;5@yGs;fAhz_;PZd^mwt9*FwjZ0w9=oBs&mhse%G)5;&A&) zh~I;<07O=iR8i7uIc#gs&`2~G0v(!31E^W`RwNyfwYb@V1^LA!FGG81F_59of7eM1 za;c^b0K;avDo~>3)wRGGyQ4~2lMJTR$WU6`OBl1GO^K6o@jov}XofjE+9~!2%{_SC z2Bt^SpuB8h{>cdc>y&r>B6G2{Z*H3Vr85^6sn&hPCsV_!3WhN(D$aZ7>kOzR3wik6 z{K{oy4w&Z<#>-9%pZg>Sg%*69eVew+iyA*W93EJ{5kjotLA#UzO=Qr+_z-Omn7azj-5Dh%dNKy8QUwN z>b!T}tI*Z+=N|vqC#do^_=hn`Tx4yUt&KQlC0|wE$>E!h9liM^3^|B|aAJuvBs@Z- zX(zpe@F}Ao?Tk%s-av!*sim-v&S=DD5X>4?bW#LLL`udh_X_jS`#+dgt7^_x;+hjV@khWf%stFasnW z3S#1RGTbawBQBpdfFd%khA8Xu%9cAc>e9&# zG`~?&X-3&8`-Y_PCojBScFMeg(H*b_Nw4t>=#1|^FGD2IM7-^BI{;L~xw>}L;;{YS z-Hh3c4(iO}7FP3mY2o-Z0^&NOr`P=1lup^V4(wP|0cz1D6o3!gXofkakP(dQ%B8;C zECw8QPE`o0k}AUkT#qO9cvS5UCp&wS;cz+~OEo2RUYs{Tk4wlF+`)Qsuo@q5<4reN zhhGw1V*@We5=&UOW`)RmAN?ye?B5O5paLLa>olc_t9qsF_4}$~3Tr_1Wbd}S?>uty zxPvQ}mzdbQnu+20^0|vofBZ>yQW{1)w>^1UMp3NWUKvq9jgZoN-am;}8Aehu`t8 zwO(14r3JAq?zrRjANlcr)$36uHTQ_?=^y*zFZ{dz;2$!`*OfK48rEl?cHaaS=$(l+dq>~}K@V^Bkc^TB=;B4Nm?X8Tx^9JX=cs;G4``>ywX`fQG^YR;1 zPi;<`y|Cb&8FtFnu{!+|&A;r@;ZdnaqwPBx)N-glLu>mr?*=Z+lyj{zUq&SIqOPR5 z?_Ex6;ZdhT!68MV;cFl{3et%@NUCZKxFCy-Q3|{IKvDoP!nSOc8&CYSLhay%#P^8Q z3D@2LTB}uB5<94=FJ%vXE?4Se4I78*wKccCS|2~KcX(}AbUYodtuIY$*Dp-Z^b9ye zaR@|3l|-17$SW@F>=c$AR8+_)2vs$`=QXcAa_qQzUn~un*o!wsp|xB(bLQ-`r?qAS zC`iIlX3083fGSuOs)lj*8}6?ClnaRS0H~FUi1w(aPZQf~yE$9qUaF~gX%^jTj*J?t zoqhpna?uW2nlz9q2~5w}(@#G0n{R!)^$KPt;i5c#^!UI1KmYCV!$;xOvcfPIrX+mR zw|wK@_?Ex5T=ZAg*7{2WH=0~J{lW*|`P({H%N*pF#7IdA>lR3_L;EdW3^4~>Fo;y( zr;|tj@T1Q>@#JW4SG|hHxM|g76hhQqv!W*c)MS24eKAYcGigSmq+v+1Fe=&nT`4X( z*nqt1^5#ZS77Us=nZ`xzsOFf^#tOSU7T1-rGry_RTW$YQHLa@3g%f{~t&O%W zHl1D!a4Y>-RKZ0xM%LkpiLQ}88ReV5=z5jPP-XV2Ih~)?G|)A*PTR~xr8ObKQ~(#Y z%2Y&KaI{8~^{!$tNI`~;FyLJ6r+#I5rC`6*x31S8EUotpu^Mmfs92iVV)ek`s~GPV zGVRIv$iJ5Nq44k~TD>3H--?Z9|Kx876JvTO-dq0F_eq^wDIEI}JtmBoITyF)^7lFTMD- zpZvKM@oWnw(!v}%vGpTA`a?GzKjEAN*Ly>RlGMTa`dj|?H(hz@%G-YVZN^Yp+G;#~ z^ur%qT3dd@7k{a-TsvW5fihVorC{DqoReIff}ICUTB|1q67sdY|2N<9#3P>o_||*x ze$5|w^YZ#;Sy~ZAyBb0rE>g5z2DEaq(Zq99+>&Q_KG&96*=?2E4s4!IuByaPEU&Eg z`u*Ydt|h&+Gd!_TSg%Z067-K8L9J+rku=go76C*`4Hcz<&mwN(TKUYz8g1Pvrv%NL zxTxvf`FrM}i?;t7QcJPrGyOT&yY2Wc(5kaP7uJs!-@KMSnD2^fl}QVFCNWuiM;o-C zTHUlsp+sI)#EA%6Ad;)bIX%{HA9F1sojO#rUvtgdue}Q}`dl;TUp702Gu^YFZb)UM z*-!Iq_B@3>6FB{1QjiGyUdhpE9Wc<8{P z&5f-C8};Q&{rZY9CREf*#op@Dt|@lc?WJ*Xrrvq!^7gYYoY~zOI_HeNSWTzK6#b>; zje{GmqepLy!Z{&H{g$WcMqZw?|r^k4xoR9#V8FM_ZygAer6;S?Yoz12pp24DR~{x?P? zYN9Mse|Jn3b3@qjZR3w0=VTJLdKTis@NjSVwx9T^zItOyg&JENI=ucvKlCr|zv}@w zWl@kYDMDDAA$4_W^q+k9KOUq0?O%DjDSE24tLlf|{qCjpwfkQ81~TG^;k^fu^Bhhw zjvh)aLxum;kWph4CGkTKe)!2heArK>O6K&(A35{n^KbduuReU@I2kC11NMXfiu;oi z;tD{VZc>iFGCIFb${9VoI)nT)_sNRNSyeURt8;{lU6e|;Neca33hu%A-sXgge@X7!yIDtQ;WdQm=0iW(K-DnQ*&mEXfE2+h1BD zD!h2G4wlN5jkN&dj54#&GYs|Po4zU$V(@}Rf8)H4jLT2<1comg{2^4 zM1_i#`Cdl#9>nifuoH|i6I(9X)WXb@gIMxs4H9a*o!yj;Gxa$ z{{MaFYhL$8FREUEXlF(|YCvlSgH{Lpo&WUPhNIDM|JtuxYgoA+*YEq)UzNIk)tf$_ ztWE_Cf;Ajg^AlcRlj_Gzq8v^!aPsg&55DtP-VRq0;Jg!88^ODN<(I$wFMi#DBgcq2 z*n=oaQgm9L0riEXx)1$k9oFf^IgHp5#to}+&_D{k>DJqye&SKDc+VqGzWLUz&6Q;t z3!ucoZOcGBC(XwR*9(M*M6XddqYPgh_yiaBQhia&Gm4;_d{}ERsaHZ;XL?k z2GHVt%#+ky>Qs~Rxm&04i-0}lk9Ld9hjt#y&lIBj-(6hW8%nd(6=)@fh>|FlmX;JE zB1E`49*Qw=(P+WR1JG8$@?d$XD3(_Ts~bzb)z#(obyF1e#Uc9rn&6k0%FW(nN3Q5( z$H>Kc_wmzD?{06OySjb#>ZqzJ%WNnFYYDLh8343EOTT8ox$)KAdN}brqbtXcu5KJ$ zT`H$lWsIrZ6jE=luU@&l;~AcanMs8W)cbyEU-gF9ed0q8?OwjZw)E2p5qnXL>Zd;T z@dy6M8_9$tEr|#!68u<1yfV)LxwxS)(jsqKwau`=oCrb$p)*`ZY33EDRDsn~js_(X z00~>kQP@|SEt_J={@FkppkVdJ9kH6=x3p1nq{ zY&tfZi{hfQHX=0*mkJS!cyEfMx7}n+DV{!d=HkEl)%X0l*T3rc#>O&PYsCn&hcyN& zjOMf+XgGBmYNB{b%N$`KLp*sS6|$l2$h9a7+HF3X8_l{;T+3_%eK5zJb9lA8=uLB9 zx-sxsb;2vsDoAEInw20O%-NAfI{W(B$MW%>k^Y%x4B|WC(iW&MDzpRMn|`G9JrqC! zZXy;Nt9CdmAS%qPL0vT7bXQh^Ov~h=_&Sq>x$c+|`ZM`k3hCy-+<cO(N86LV zQvKEKot~TMu7BPQpV_^1uAZJfcL{2gs3;9{Peh<#5E(;kq8v1&fETy7v+KO>UD?%> zhl!|~y20uaNwI!lRqOh4Rk1NdOiCgQX7ByVVCjzg@BYL?e>l0iYl=d>k|eYv{Yna2v_sw4X3d0;u$|TZ5 zE4?53zVH5r7q>t7kq;K7scWq!qu=@YxBk&T>u$UMwZ^J?A#ap?==zAN(yCAJ26EoN z>mBcy?(T(S2fPZ^;#t@k?=if5<+pzR7r*@LzhSV}_X3r$Ai)wOaXoG-1E7Fq?^)G*ucBU5!4M%1C&+;r>JV1{V3=WB{`2%AkbF2@~SYqh@S zKbniP0-^yR0Zc?^;jYBWyOpxinrUdru|N)GnHGcZ&X=b8-FN4bvRN6?qQire6Oi5-NJR{ck*8$YV z6(?nwcfm}j=Mw9|oa@myUn0cInS)=p5*6S_Xvk}dX5k$IN*uLSBCnX+N-euOR>YfqLY+qDCp#gW0kKjU%Il?8!WH%%z>55r_b6!0T?)CA_b8_ zCDq2}>h1U5{m6$us#B+;VShI<=JeCg9Xxfy6s3O`D!v%`M7zk`>zW1O1z#spzuY!7V;XFGf z@~IYrxJyq&#Ky1!D)pg*Yd`X%Kl1m#?OPvt=;K9MPNtQNC%^a0zhcRryzB0wG%g;D zL*wE&@m^W> zJZP`>kDc3l^z6>>m`m`!S8!pl-Y-{r#qo{RTel9J+FU!fzOvF^Dhe#YkgD-cy=M|u zQXytl@nJ`E2B|<0eT`cus>m@xNHs7YNj&BPqV1x#wbX4}D}B3bxvfl1Q_vX@f^KmD z8vmJA2<#)n7NiA;nezV{$NF?NoQE_sgf0F_uh;ycwwZG(fwB%EM7LZ{u^&M6Z=Q?% zT|itJ&FM^=GP2c~r)T8uyr@pi(i}L>OaJh-TcbvY=AD$LkWEi5S}jjiY&oPAQ&|V5 z86csF(jg@kQNt>r(v|~bN6vw`Qkkghfy1t1VXYKOc5gDgyuE$?(uLv9o>Vn?=dE2{ z?N2K&#u!6;>b0qD6+UBAN3-k#7LviY+O2Jkek+NYHfs!XnUfiJHubfn_ z-rE_Pb*oCN%Yzdq4xHT{nu4RXLLAgs6b|ml!GqJgZh!m}pI|j4?47r!tm^4Ak3MnN zt6!t)JT!QAF6NOIYR!qEZkK0|Yu?kDyhk#v=WpqhA{4_EM3srfD;WJ=@39Yl^uc$& zXSpcAQ1Qm%@BO`R`pU2S>bk1biwBWXbm@#k89`Dsh8l)?FoRfCPaZw+um9Z-|J}dy z51)SIQCsxt+E4Z-?|u8*-!K~9{kk{U9(flcF^HIBKnQWzF}$uOA9(kB>fzXyJ@2OL z>zjY=8^2+9`|5)q`p5@9`~fL@-Z`*&^dk?ht*qbw`EQ6mTFL@pMp$qmMLZrS2`TNY zx$Y9uY`p5=kz2Pmj<5FD2TW|OvQ-#Z_!=JK90;PyhKW=~iOH)H z!F%QCZcEyrH-xEZSbA>29r9)DeNzTHTG-yoBaK3{rNjNjdg?9e_Wz6wT*L*7#!46d z>_|$QyOgTiW|)7DU-Je^okA`ym?cOpc#C`(gI*pSl@8EeSbJSulL;pyNLc2sCYNd1Ftc$j?e$5G+T6aKg z@LfB1%Me$5J)mK+QB?`XTDtJ!)4%<;|G`eR2P5#c{Kdcg=fCOi|0AiLdY{g)l=xbS z`(6?u+={E#Oibh{oNrUzb<52^_7gw;kH767J@@fP%jK2HWIEm5``EkQwYs)^^3MC2 zA*2$Hjcjbv1gPITck%I$ecY=Un5uUF@PGR!%gf6$)z`f7^?&e@4;9Q#RY(i<55DJj zH;)`Ta_cR`PQlPHkqA|79rrV6)ADAE!}b9-T@s(o(IU!Nc$icrgrV?m>OeQW>YkH# z-TC5k&pi6U2d|tzH{RXtmjyuu-iaf&fI5kBAWkuz$ngC5`SYXSf9h;WFpQOf-5Qj~ zR|hw(te!fsd1PZ{eQ9OTvzAQ>f>%-z@?i%l5YpCj8lsPtl4b%BPo++a7+sgWu4ro% zM`rVAn%t3^Ng_2en%Wz)0*7Y5E|g2N!v5N$Lk+-8N%PU|4Y)>JYNDS}KiRd^YtxwZz^| zY8Gf+n!S{9N_uV92xR4?5y(jb&?M%gu#fB=DKAt=LP<`gRID$RxT;WAmUFwin=5^8 zmO~XF*zssmSG6TW?3E0d40CW%FTl(K6$@`jgj^w1kg!0YN-nmE6sinnCL$(g0+`rZ zW+BJ2vA%ig)Jawu?rb|(7uH<5bm{8l%Y}+5i;V;8uetNoLytd6I<Gaor_H8}ksnf!$7x(5beB*ch&<{Y^N$nL3CMXjVRKXx2NT6>5 zC#$mr*Hw-nNZ{Q)H{JC8-}BG@*Khx>)2E;94a(Y8dB`&3IfZz|7(*sv#iA;7#KVu{PK@C(-6aw7g%tKrnurMV;5s64Z=9!_1`0#t76?ttFkj=gyn%yTjMj zX!q)+7tX$P`h}efmv**ytI5hhp>YJK&@>gwH_t0y_rZ z=~x^4K?aeNIlSqGNKi?fMx_UBgoY;4o+Ia3*}flvH~G2`%>9aA=3do)(%hY9*fXJ- z(L}0$d|JB?w=$QA!r71ECm64k@28-h!g$gp|w%9VT8PKL6> zYNaaK+Id3^CITyyVX}mxG-QYi6!0c&Az-W$d!v18Rh$~5LLqw87;CLzV+=DBD;Z+# zm8Kp~CvdA98#mv1i!r#evwdYUE{s`T8;nNv_U@2IlS=i<&fbwD8%GZxxO{nAR4o}1 zcoNHn^R+E-%k8)C?G9aC`H2`NQQ5h&ySBMW4Ka6PbAZl@4Q1+J&bMcg2%2Y+DEz}> zAho4r7$cGnlX`-pF#L|6`=x5PA}>8#xO#f%z~LYL$^Yz~XAki)bcq140>SwwoO~0B zi6m4lELDPulu5mSJga~GYwrHuAO08L_ub$1(&;m0uQ#oyvNL+$FaM7(|7(A1Wo;7} zdtxC4h?%^|$KU_KE2p2gL@KVw{eS+$-@mrBRF8a7@P(Jo5s@+%y*|8$LOe+2eLw$8 z^0i-m>wWhb5>a7d32seM2T&uek~d{%rq$u=4mB?jRh>kQFJ`M%B6f`XypcjxoCCxu zz`d2t6Zamt=~WNJN1dp5(@8bFy1jGh%IPPbdh(%16l6u6)D(74GR8S|5GEKl)fAUU z)r(gysa`CZ3euIHJ-FOIv9@~C*4D|btwS4YD`i<48c=B=#)+y10~=HfC(NtL8t28t z4XW+PhE~8QQPc(_Gyy2V8)_B-Dw0e>YfESrC$8VOUEm)7&k<*L&|Y@xh`y%W=1nu@ z&nppR2l64r_>1J(TJq9P$29V{70fgIi$$#7QJ&p<9VOL$oSH$P_SQ^8X3{lL&RkNo z^O6V*IgJ(?FP=Wl#)|h4ne6Q`SRvBc!m>5fWFs;|409ZE4L#jLg0xcK_z+R_08hN9A(wh( zsNv#6?|kn|Pd-~Rd1zHvwRaDE{u>0m+FKh{mGP=ju$s_y0Hqj>4lqf<2x-zQfhvO& z>=(T0)&KPS|H=3LZ$EJH{CR7*p1SReSAX;8f96ko-CtVUI$ZfZCk$i7Pj@e0`PjRE zPb-JQdgs34E5G8^uX(L{M~2HDJ@w=>Yzpsut=c!_rcMizss{MIzx?*S?JKYS!Y?cf z>r^O&*99+JM%<-mR{1Wb(`*K?fZ}IzYc^u}@Wm~Tl9z0HdE9hP6AtxBK{o zJ%0LZ&!AWGp|!!W_0>BLY~6Hl>+tf*a#5C+doad(5>-vB_Y8ulgoFAd%nYKr$EUr1`30cp-FXGgo z|FV@00tjG+QsdDbcQ2!?p^f^Ot-)+#I`yR1U6=Ox%*)PNoE06OboL}R$C6&3aDU9Hg| zsUu)_#7mYhU%0ro)IW4!bE?Jk!nqyYsp^_x)(5Mb2g*|?PfW*?(P%QRs%c%-PAcbo zEyj|lOeh?^<3icZS0=FP*E#V^j2;_uH4Z*H@RfFJEE6^m;4GlbyYHzWsei zj~qI7;`pFks;a5f-mo!!u4?I*y{&@>&zyMyLQ+GOrjxM*Cv`+bIO~_tj!tK>X8}O! zPN%Xw+CaC)1*m1e4ARCJBI2;&U9ZQ_KmOE*fA{@`K|OUvVW=Dw&|mr0w?Fx@M}F#U zzi@DM!>O|nm0;pTvLMCDg({$phyailAq31|Vi8Z!Ug5v=i@!*I;Gh5V@BZGM^B4QQ zem$+Oym0P4Z+q)ozTvNyOTF4V65hQ!eCJz#x!&6=Y$=KZD~G@RAALuUim9(kQ;zHL z+4E=FuxF1ceeKu(mAC)G+opa*yvdS4s2qELL`Q zc8vxu>HJ{K@x_b?OCMq38A)6QCtL;E2|_GYKyfY=I!%e;)Deo??|;?mfp?F#uNdOd zWb(kNli&4~U$%SZ%9$6=J$~WRW0$tiZC|-sO@^*=Ab}7l9J=5{32=hlN-vK_kG{C~ zyYv!~F86tBrGIRF^_GKMH*c;TURhl&`~8BKK&(naYSQ5gA*>Hb*fs{WHr*2SVrqGu z>!<=z2h6d2M{b437fPd?o;y8HGg%g-eEB&S`ZJZ88NzwB(S$?>&S~9NI@O79YLX}K&ZxEVr+bw$h#NCrTv)_ZYN=fr#GqHZpXaIvf-Yk&kxU6ZnQTXO`MxfoLB9Y)(AU~&5Z*mZoPSR zP!5Na7hX8Ow=?eb%kjAKwXZ67_2MNHFn}?v@S?M?^x0N*OvHoZh#VSL)5%cJd=oCI(OkWe(tSH zq-3oKl*ozNO1IY6pLy~8U-;U;^wYoiGe=fd1#AHkiHkUbB=wWHY`H(7SeD&9?uWjzt?t{PeTbG|ZU2p+a z@$Osx?%zCi@`$f0!_44wFPxc9C#GP)5Bf{r_8ouY)QLm??nnNeRIXq+uhnGyp?ALP z(zzGD_^ZCg+QKW;3CJ@U(cn*pXq`!TrZag?wwy4ZS=9M0jcb09kS(yK*ot;wx(@PD zO+@&d_774bSO6-6VsPJUU;B~YeYb&HGQahK2mjQo?^`nC2X0-x|JHRFqbj3HE)FNp zU)p`_rAsef-9ERsw^vVx&ey?L3q;JKMi>I!p6d2=a{BW01J7OT7qrwbj&3ZU*j%~i z;MUFSYny|9X>6e=#j1o&sf5`;MJdD|D8l@JNYF|=3A(>U8j0l_sZYv{WvGz?NvP(F zs!iWCQfmQhpBaGsVy4QQAb^yjHMA2Z&<+hc-$VU6QY;QIWy{`iWJ42^7f{eyF)A}d z#GO^=YbR~RtIoGFU#s3%F0}nhXrWF{;+a_2TspTsl&XQQjGlc}{v&zzXs&m-K{w$w z?V@rxATS>4;h_xjaEhg}B!t`WnKL{TBuY^0oELyWYzdb%d+)7FtMt<8$&2S-y0pC`fKw7hQCMa>som!K+L4ndmV5otX#D*1 zFYavb5ux54)wPH^Rkemig4pz4;l1}xnK0ek{m6$uv~}R%U3cA6_WHFr_Fj$l`$f<6 zhFYn3V)8zm^A%?R$c&|#X^`5s&h_&wT$+I{xu(v}5RQz{yiExNB@z&`F@Tfm*MIh{ z){6%UQZ{__rd$5Vm%iy2|L>oj?v7X1H_l$T_|4z=m;UpA`>CTFTVX4UXy=KW2q{UR zbxqEO9_>t^AuzC|aNdGt{i?6|%395j{p%mu+urT>`qOFs!V^!v_vion=YRRvT)e#V z*n@xA6K~7HiGTC!Kkw`Q!k)SK2rOe%_rCr$k3RU|Wcw;{@zVCri!VKS6PD|#_rYCA zy)krng%2-pecq{qOx6RVX?ze6RY;)fF@o-ntMgZ? zhn~6g8~l8)(5Sm68KXocu$8tD?E@Q)|tZYT_kNd zbUWyg)U*Dktb;V~pk_3veV($?X5?2Iuvxj(8QXR$5nhqKC{0`DN?Cxc=Vf2Ud~uf7 zOfHomn%jx;#%D~NO)}9sR|aqp9QPJjzgoNQ;!3tgCe4~VLy;LM={Bm>E|gcbEwEde zW)_#}(bMx)DtR330 z%vJ6CrYwtMC<+xeBr2?E%p?uCY@M`n|GK#mTA=LbqcN!c(z@&gArm}k34vop1*}dy zfZzDpw_-SCVp~{+vMl|V|MpV{4)wnDO<(l){`NnpcZSPrgR^HY{Jn4f)}Q>TpV(a5 z5FfVi3}QccEeeN?T9e~+OB6voN{|pK9!;rd%-4MNS26p4`!D~^)vMcuwUgSv^z`$; z^9w&+6R$vR(O08e>ucZs&;My}r6*d!z?y-o{Pz3bFQSI2n8;Us?N=2AkN4zX{@{20 zK*{g=_4m~E#ImcrAMaJqKmO#e{>;yQRr$wHpS$_? z`(3@mDJas5s49u`!N^3iQqmoV%-x5Me#Je`~$$#a*Vx^(I6?(R-Cop`Ce zKnO~~_ERe+PWQ%>)0Zb7dG1or^5$}RbZhyZBS&sKv~_HGd9~~h*!GCv>#&wh76esM zhI$nSM1&dIOai&>#D;*w0>ZpdL+X?{8P)yKK1tmy3GB=i*ttYa6R3k zM|-3d>oj&*!3tucXy?-)C!#BERPW7-d56C>n)ritExCV(=21ImXtiB~*VEJUozwv5 zZnKjN)~0!yT9tr*@{)*fvF+vAltg}T{7d~8rhtSn14bO>cH@6Vh`wsPqeD>v7=j1_ z3frf95Ih)00P$L=VHl4T&8GzRwpSK#sx~?^rY49dU)2tbvM4~L#!%(fRtKx##~*s^ z;?DHK&Mp~i40)#pOiIJiWb44j(UT{aN;{s6&%AJUZ#)9XdleCQk+7?8XoRYO@{>y< zd^4orz2V-YAAe+JbM5%4lO+l-Qd%qGEpu=V4w*GYW_J2F=Ew$TfzY2N^8BkNjnK-J zG>8g>-Rr{8cvS|mpy>5}_g8*tcveoAtFfQgFdaqtW=G z2OlnNDbRxYfATB7%sF`Q(qQRd{NVTe_gDSOfBKI?{%nbtC0LB&&HKL>g>vD~psq4laBk~*?Ovm7W zrNPFDQ$r8D;SG=e;X_JJm7jRw>X+PJ22WY20D@rA3jIz5h4%`msu-ezu)NGCR@Oi7 zbx;1GgPKcx-KLt=C_%mPJWa$s?X%gfOcL0e6Wj0g}Ayk`ZRs|GA;}Or&+0AYVMC zHb>iw3pfScA)6lxjsLRQO5~SzKdw0zY@|QMd_hoivq}=eF4RNA)PR$I$rgnhrAQj@ zb(%K#)pRSS!eGU2RV%4?llF2m%L@LxZ(=Iu$kbfMq7%s4h`~IyeX^ z{HXF`Sfy5};k|Qiqd&O$@PVfud1`xiSQsc&Y6(JX>gx5i)g#A`GRfX>@9c$3kjMzR&SKP_zVBY=sW(w_kI5lU%k4$yt3qnHCRAYL*DYmU-T7U^QTy9M<@s) z;tO-;^z&CPTwGsSA63(vPaQaX=z#dCDPWY?6yNw)zJ6tM?LYkJ|NZ=#r%TJVay_Zf zJn_V@|J+Z%<YXSFH&Ch(FL99;Xk4UnSI1d>-HuKdx9V(`Bt}}kB}L-- zY(`IUlnR7FL_s1qVX zN`wO|W^--u##?U{x~+C*d+eWj>B=WwIRE6u3oq>rx9e%Ga8M>zuvbhg9bc}_UcUIy za~Dhd#G%#RZ3oxhc=XV1hYxNptrh*A6Y+8)-f%xXI-8;M9;je^#0_D;%r1&tAXYdGq$-0o#r-tEhX5ghM%Rn5^%)a|V8;pEu&TEwlPi0p7sq>NFYjKSOop{r z@$g`4SX5bWIdYicqIrZPr`TE?*bpg{4Isqo5lnAx?3{O&0EPEnL`uWMz3Jrt&)9zl z+Lje{;&@f9wf5d8-1zRx?{#<`Xc}me&X7fFKQ$ zgZOg{C^Lf0h=I_gZs=}0zwUnd-FU(dtEzr~thM&p_r8aGkNEoB6ZcuGR@JAfK2_!6 z_M<0V#s-lLAdwdxE)14eb~(iH*68$^Gox~fYE+cH3b3eB*q#{GN(HlVW(#QGrUrY! zOvZ=;5&Fg-z4I>P@}_K@$<)`@STvz`7j#6e6E}n85T38%$DO#Ur^2L;hE2U%1dAMYOX5qUWp9@RPxh5_fs3|C;$9?pDfu= zwwk~D%;y(Y-u&yo{NG%bdEX$Ys$pS71u(JfmOvC!(Li)}RO5kH1%sf7Dh!CunP)xs z>GON{{QPTP>&KJ+AaB&ywH(@i;eUPO8w!^-zAiFr5CG6x`piFl9t1))o6GkcK5+ZlRkCzq zv{fVYh+^)z{o*!V8005jqlU&x0DzI;2~DUtKv4n!n(y0(Ub6DAOZK7KQNzbqH?F(q z5-NyNM0}9Af3ZZPMMbS7cR+6P7`EBbnRus{Kofs1*MaENKxi4Fw|CKr}$FG zj&wzE_PDk}+WCl9GFrR?vq=3ci)ATb?1f`JQ1u@8= z74z1#+!#$)$CHim`3D_7EL@uy;m}aU zYPs<~`oI7ntkyW|t4bA&aZ*pYRwg#i^?R=8GGkOhN$S4o0T4Pu#a@vu?OGb-#m4&R z^!nMlYFGpb0hKaDFh&6+ow67#z%Ya`E--~akce=Q0T8idmAGn}a@-h`89dp0s^IsCf-z$OzS-x$EZJzxIVM+M2~$P!GsY`QgX^ zx3|8j@z8h=C>B7Sf*PL6Yk&FYkKcXfFaO~)2E|wWu@8Ov@P(JY@#0+xCetlnsSi5V2v7rBGLJXwyEo5Xch6Z%w`B(U z8SPt`J1{?YWY_ZHJ-hY}=6YF{lQBr7Xh76^mC!{zMLRW2O=+v9q6>-9PDDbLc3i1e z#M7^CwY0X+e;?Www4b5vzuOdR`X>Zk+GpArAGH3B0%_1nL;xl|iwd3qktzB!8AgsoF9S%dZuPG&#RxHGK+cNUjSBcR*4G9o~ zNGPBc`*BsTjmtBm$?4JP%xJtmEhlwTGYfS+ilk_N5#4Da(7k-u!U5S;@4P%9+KL z<)*3&XN4ilZLim_n`U)w_2kLZRoxI8G9;qPqM{UvK2%Y|d>0Y~Knj8<(a(!=ssLyR z6s$!=W#+2!s0N9-@y39HNE&Dv@+>nxR9g2W={S?O9UH!V(>wChYTD?&&7e}sz7xh! z6ao5b{Ke0F){h(UO+U}7y83}fKkm(c^d}%jno3a&fB;xDXpjVq$=~w!w~c?k`P^sz z5p$|)`2_C06_PCu(wIgG#=sCMpa=tsQGLV@JmdqP zxc1dAe#Lk^dfF47@T4a{5x7!R014d*a#w7uZQgmyy#`FBwG(>GV}2-3uLM<8LnicO zM5N0vyZHD1@GZabTYvbEpZZJ8iG5v{m8gF1Q=fkL6Q6kG{twIwE9!$IEX)ulL&W2g zux0{f>Fl2qZ=Q)|XE!>}ocFY*=et4S*-L}kQw1c$%z);=p(A-dURVktO)=8Tg8vp8-!tV0Ws1~5ReoNAchdU0wNgzgJc1QMK*N#f!(_f zE-Wq%hjW>dG{&pUy3K1)EB5J6zq+hsG8wUeim(EaW%A{im*y9_tQY4E^#)`hFNPZo z($vc<`=0W&r;RqtrmhgdD>uF=%WBT^!OQNaBHD;=SQ=r}MA;FpRYNZWVo(4A4TNYS z4AY9qASo#ch$Uc^BG0E)MJ79Y{M5$A`o`v{kqS`|fHEVXvG;X*;@dxhk2&L$oOAo0 z@KTd7w067uQViA#0h}?Y_^C~LL(}nn+GJ(#Dwcw=?;tu zP!M56L_!Hxmi>bsaOHbG`mTTZ+b_KI6)(;V)QrZO+z}zLXJhGx8*Utz(}kj6@^sJg z^4>jrKoP+t>k?_GNQw$8bH)Gowb%C0e)^*y1yN&-c&^trzx=s>+&p{cK~K86pZDsf z0#HPwsDwsDOt6#@WOgumm-W*w`uWk@`LzAE+qT0z+r9Q>9Yvuk^Gi#^x#7liB#O7* zb==?YGJ{soD=J9{Bn4B@>XZOnA}_0(#K2i%5&^WUQ4s(@fJoIV0IFB5atjBR;ew@w z$6UTt)_P`K-f?Q}*3)P2T3cV8mSbO+%&aPk0!m0;Re%Iw!Z053sqyHh(<8#;&Y&}x zJF_^*mx^NFe1Cb+J2)IH_xtmCmS@(Hu|NoD5KsjbL1Yx}s<7)b@l zppEK;{iLin%W`W{o~@><nrBc1EO$Xv>9YisFt+Ia?h#; zd{Y5aU2aT9BXVS2Peq4Ig|O7ph-g#${-Po|_TE^-wS<0g@g$NW5(^lMD#0C80MMYW zf^#jRG0ml_N(3q_AWI6Wu>a70@0q}qlZt&)@)Uw65&b}INdT=V%$!_Ew4Pw;Q;>Iu zGCl9DizO0Hiq4!fZtKkYZ8zVF>Xp4BG>v`Y(|*W`g@zRvkyKd(NKh>TDu}2-5?ESZ zc<+ba{o?1n;Ph=LXy`W1uD|4(SAOzi@48^`g=$DV3lRW_3LvJl7kkV^p~soTgp(Hn zLxxb8g_RHroQ`hQ;BJN)1uU+bsSEQ6-0%Z;sXU-z}iX!Pi(Jl*9P8Rbaq0s@ra zY*LtV(_*Y0_$#jL_gMUMwx@#uyAN#h9A-KJ0U|d}0Yt^-*@44{S5Mw+!QF9obxWHi zYk>u4JTIJ0j|4;&z!;Ma*A!0>DkyNU6{rZnpa_9@l-yY_DP2o32%{Hb*rpSj3&o7H}78CIK8!XW>SuuW?Fj>z!I5qBH#h)CfcRbTMRNXL<;IG z0%$KYnW6cf8)j~?SL_<}76-khet)6g9~8ZwbB>H9G^h@M6iAg=G5OC)(X_Z%4FnC= z+HX)m+`b%fvE$u%%+e4YNF#~b-G_wJ+AR-gpJEf^*ajj6cTl}Hppo#drw~Q3VOpkwiQ*IZ_aY zkY-c>@Qs%S4SF@`ML^ZFFpDB^!$DTjdl3~COzu`hPukI0?U_%fH8vcMkqssUR25-} z>Q6=07^2LX!l4$WpMcaU!rSh3a!@sCnU1V>PH_BY?L5&j5wlym_<$jj_z?i0sBDcV zWW*pD&daK@{p|1m_A}SK=$a!3E>+4A7(s=ZOk4Yj1PBO5-JyN^-~YjPUGx0coH}tl zGx^%twO76J7vBHj_wQL;GM0onSvFJ^1Pl&A$OA?UqQUNI6lzsy@fwi|`%(oO1to(< zktncZ*kuK&e)YPq5R#yP^249-SYweH00>lq9)obe!b3)l*rfse@_%~eVzKa!KX^wu z-azMgQo+{r=yz}3+WgcbpYpWbdseIy&x!&Hf-y_q0?)Xj?KzzRC+)2G_S?+Ip5grN z8@jlyMQCxDPLLb|Vo^mkh)A&i@P*(0>X(6Vy_p_AyS{6AUbF^9q|ob5aE1+9@RjUC z1d8FpXT$Z%B3OrWIqqNVJs5|g2L+&J9hJN`u8wVt z?p@zJxj8yJnr_zRR#jKxy{M=HlYj_=2d&hI!o-UxpB#J83E>7IAOfLULzbwYxqfDs z`o&_u*fZ$w8uoVedkekZoXra7GGh%Hio;CR0Dwej2C7|i8w1yAD-bY_!-&ZPX|ZsS z#vrQH(m^4xw_&!O*sda~fT{%U10k}Y4=f;!ei_8k&k*L2Y$NJxJp2lb2qHkODGvjU zqVGl;*jbTmGpqCjpb*$2Kro09v(drNQ&q20F;5#ms_U(?+N$b}vfL`Gt-6}lb?MoA zW)VqI?e-TUq5z@6FvS)@4Ys7UP>K3=#yx5KB`D zJgA0ZTxMnk00CtcRA7#2Kuo?;bnrTgIEYws%K_8n0z%>@8DR!MisRLZMTk(?E2$Ud zxQG_O&!GG^sEBRYd^?83_Eet>`*GV#x9?7puiz<*G9xbS-o5*R3r^i~OV-P+7xc~Q znbjYC_VeHN2fz2khd`c03vRreyXAETRC~hyn;Ahirz1shYBmrHUYIYGU4nXnSrUGuX4H zpSfX?%@_G%FWc4cFZPPX!C=1E8x(mjbD6Q0h>$D-A&@Gnkbp9v#`gW~@d5;+5q~8f zPl!W>MNmmhR16#jqX0+%Xn+*Kq$vQD{K#3*BIXW4`;@p7Y5Sw+lClpJ)2=O_2Q?%e z6&PdV{3xRohYNb}HS@Tsr)52<>q%9OYri=iPijA|>aymFx%R>k;uWc7UlKop_AVeI z5r$+30-^u{TCm~V8bC`X&+MSc=Zk!?*PqY(3xockX9{OBpp1|R839S_x^l{B3@Tbh zWst~(k5Lnhcq1%&2&sW~1`Bp@QaUFHs$i?B_reTHih|0KkB{m>MO1`S&;tP!2?P{C zA`CEK6k^9F6p$43i!rTW3u4uUbWSXGJWEJAyfq7|n4lZ8 zFd39iN+5l40-Za|VftgH?{V8-kS;l901&(=IroI8Kl8I6{n+ZUgvhEcdNTnUglck_2|-CQ5# zlzXlg=H@TCx!NaX=TWEI3$d6jaeGOdH-T%QKtPQ(NQX8(XI~ zw^qw?v#clFlwMdRF#bYb2Z>mWhV&AVsH)<$(ai>6TEk`yvXx2<00ArkA@mFCS-05F z7kb6sL4T=Ntn`cdUT?X`2ff}PFY>}!AQMJhr~nHvh$xmoUTN@UUg{igO-+n zLvA<;5wzn;T2X6-P$R213E(zi1F&V&2s0Ccf`mvLC=vjNsDdbiQV^FEqDd!8K|>o} z1qp#lf!Gf{2HrwnMF0wGsS#4QQMpj-q%rm%Ohh{xOItOZqBR(#1Qb9}m;`us>~)3! z0MZGLAE8|xu~QLs{+MMC^}Mh%M0}MLShzv4);;Y7FZsIQ6rVd6~(T84*c^RS89nK}AspKw^3P4?g0_9&)*-V00_IQ!jO+u|&@?o?HT)bhDr`&!s{itpuTJY~u5gX; z1&1!08x+JS(W8h!D=mkDMzk9!@S-&_J@M*Cec%J{`1#kp>7JW!an6e2x?=Q`@BH%@ zwdDIg;-M~gLh)FFh88z~Ny+YXz|ODMzlXk`=}e86+VWPyRd*PjLCMAlt7_9!gTY|e z{{5S)Ylw9F+QtnhPCxPRZssijKtTx#MrT3maIzsNtayMh9XM!-DIf?)NtUDkm}D`5 zlc3>e95kGLEVT9OZDb&1{V>GijHYX81XVd)1%gE!<~UdM4lWLWc9R-FQXsF|)PA#S z)<)&2t?|kAtz(;8Ym>>^WHR->5)lxQ&|y3vNl+jOCpmb#01yVNfs7kasP0^=1U6d; z2LL&NBj`EoXLi2G7V~0x(BC_l+cg|44;B^&MZd^iJdII@O}u#f@tp-m7f3Znudhf9rvP(ctqK*d~nnKph>)uXDK)a7PX zjjQQaS(S}1E8mDTtg2z452^rAjGdw?QYgufT`3SCj=4%9jj%xuFgO{8FeA#X?PqyE zb8~qyEZiXL4T^k_<%KhuF_wap6I2-on1R6PRZ)Zevj7nDE&l5$)81J z<44Xw@@zHE!IWJeVVk;1QK@vEu@kZji3&BwdGT3MJpDy4{M!$GV6?V@Dq4#HQT1e*FVS>9Qaac(kdkCyy>oR8k;#a;5q6FF~Tz=Jkv%*TH z$;`II42X(0_S*=Mkb~pwKp*j-D?fPcJAd)Ny#8BX`m!2}$lQpB=7ul-`^jTRfAGhi zo97P62m^pnDr8FOnGQL37RUWwoAJGFU0nn-8R6l0 zSHE@H%H#LsJzqCKLWIB^(@vt8;0Pockdz{fus4xLa*#F)04_ zPQ2naIx;&{7%sm$!ae~2FdlSL^V(#3 zW@CD4b9`cR>-5%Wy_#-Lt8r7;%nhc<9fVm#DgX)^@ihPda!j8>BiM*eJ*<{YTT_53 z>T0MkG6t^~q%j1cty^5G1eCn1&R|VIEqg z8W5Kmb`}ZPptGn%HA16)()dYLZdT2xsx~L(s47R3a#WU+rmj6Vo*NZSbRJCsqU5f{ zkdsPCv??L00Ta3X6tiH62uJ`%$pShuxwS>+23bBV^7&qGuE>W)-p_2|oFg;{1YlB# zOG6%1YEl3nJ<$|1ickfT1VBnNMbZEuFn}N`O&gWEG0BW6476f1|ZIM6sm9PG*_r0$?v&u$AM4AS?ef!(qy?J8e z=YRfZ`n`e`hzx>y5yC*~LPjO=8M&W--OsOY`uF|GdrfW|-~8F{UwiT4`#keWPk<~0 z5J*%oMxSP;wWB#OZnY$pL$k0@1d{*=NR-u+@`megLLwCp;vezo#}I-9I&nh#p)pI+ zHli9%1SadNUK^`;*@cHb{NeY$;Z1M(KY#VNSfe+}%sQE_-hJ<9Kkyen^yAO#&G(fA z30T5*&jRBRgOC8OKvBQvx>?)o@Qw$QRBy|j#cgdBW^x6CwuQhnhQK<*lIsH(T#)yA zlhKI9-Fjx@&HwO!U-p=XUbZ|}u&6c!q+UZ&0Dy8d9xY`+kuW-ftsM{I9#Z@ogYJpG z6>&(i3N1-to3Vgx&_Diw@XB_JV}vyAYuxYT7XrlmYpNTkh_1y0pn?yvXaXHt8qVhz zF7yCa2(1Dl7%$+NrwxxwULBWbHn&#CSxP6w{MX5^7*1Sf0U;N4XApB zFW-IiM$o$U>s39TjwhZyNK;E7M+FKdQG`_l0MSW6Py+-6ZS)3WL_XGX5<<(QMj|vw znK8L_g>!?f7`S{`$(HnpvPry;2w9$o@ZWm z(elz9)z{%-E$6Kg;HIYIAgaZF6lpJv*Ijl+{+%G$I@di691%43YpKQD}S~0#36iN{X+CjEh$W z0a41G0q5AOBdl4h!CJ*qYEKc0A35+*xrNmbJ=a#~qeO%-jzKg?&YFx|KhF!74f4F_ z@?l=|b2rGc!r4Hgb-^WpkmXiZMp0HF1yMDTBp33(@mPsM+qx%hIVKCOiBTGCC*BCil1Qrw>HKo7&$OW5gt81fD$#KKA7eMvQ%*;*Gux~0qnM_qZ zH%(JbDsFsJH)S1i11j8jkBSPc9K1tS84|ZRU+de`Q$^r=3(tAcC z_S!ENKKECjy5~FJ7Ex!Z8c%GVQPzLlqwe!NZ-3{m`8~p{sHoyW5R{As2%X)OjN7Q! ze&pFNx%I2pXRZ+A_w8DI--kbN>ES~dvIe3W6FO}x!W zU!VT#SN`G~=B;bETv%TD-2eOh^1?tGPGlo7qyTDWrc|P{8gOWe3hO3c|ShlJ^=F?(iEJ>WsTuqn(x9%z=)84KM zZd59vGeZPz*RFVKgUKfVC9+llt+hst0(b}$G|RQk@#fn2 z?B;Y_PR~y2)8q2&WU|%xiLV7>FW{Nu7W^53&;%X{I4m53MFYk*%%~{jfk?rqRT3o? z6V^*Zj|(M01T=&MXb^L23!C+_Ja^eJ%Z5cZ$g_UodM@iZlNsX(4In{)&!V6dE&+l| zqj7yT1=ACD2z%BE3@3Guk*BvE%V1*Q?AV$lyU|MQ*xmGb7_Sfj$k@Bb&3pd+%Yu%S z_wSnj>4!W#tG86ef=VKh&Cvc1^b}l`Bo)cnXmIk4s{P-8_fJ{Tw*%)w4j<79i&FxZ z8NT!O+fScf^CH@)S5_~Lco7BxAoQhY5ovs=)DuAkZvimYGlXQC04WG65^0z{AFx;w zR02^!017h_Lv)BNC<2m7Z2ifND4-!Toa>d7sa6dF0JEBu0PUim?RsKnTDwPN$G&Xa zpOmrdoVpfFMI#&bTvR}b5G@IahvvyY{^S4hzvpiF;=e&to7{0F%+(jabi+@*;KlF% z*oSw|?-%qS-h{B0umAv}L4t-Cv-yvI@V(D@#*ZGm^&UGMoL$@c#aI8*JKp>Di}vp~ znNmnwLE1S%(%Ee&Ij8ZgX>s92r4JG~QbK{9pd%(_ZibXEG&= z5HO&2KM)cQ?AYKAzTbX;X6QE)J=!q#Xwsyx1O9F;0H$7|%-F`WqCu}E$h79ox>_Ci z)k%3~YkYb%TAfTcrsY=Ml#Oph7?o84$N`!_MG83Y28^&a)ehu(I}caI&tM};$!p)tX2BO(z|BxOZHLPM#j zEtDH;OrgYxK@|7U@*$PZhv}3^NXCFFS%NTO1cDhNB0?~My483OfRoW=ZFS9MTC*Q4 zE*!kyWvU=nl8^%_0ZNL#hF{v*Q`ml5x<)+c2Hmz{+iY`!oXLlRIL=Fw{|UeVgv5+4 zAKdh{fBVX3{!gI%RHG?cYkS3gj$HVj54`W-?t_9p2&GpaVw7YEl~F+pcl_R?Kl;p< z-Fx(2>kK(~$OEqU{dfNH-lYW*RuBLQ(dQHj(D37u*v;54Dw4_@L*8DD?GfrTe)O8_ zzW(jyBA-sj|K(SH<<-CV8Y`sA02r_>fkp!z*>vgmCpML0DtV2MiYlU@3Ld-n%u8PK zid%2F*%XDa&zu2c4jj4oX)k(V=^JJxBiJg!Hg!KU(c0Bi-}k2H`8x)`Fsj~m+bAM+ zuU^FFnL~5t#F-nveBG%#Z(l!inmtS735=q!0$N}WZLCBxoX^a@VR6;2UH4y_yWjq$ z-u#@gb4Cpc7zM3s6cP0yEN7PaOI+N&xMrUfL zE7M6dw$VWn`b>+S9!OiP3CzacJ&=M%oqSC+as;4AY7o3vDJQEpojkQxn};0Sx6m7+ z0-0G|ay8>(hFDI$fWXCr6`dT&>sBX-3DU{*KeDCNHLC{gC@z z{gluG@AM6(Mrpt#Nlxs&{?y-_;bPer0LyXCD68qTW#Tq#}XK z1FiW!|4jiROpf0Xgp7=+9rOnxEM5r!i7cTdwAQI{1}Sqru$d(=#uzkUP{QFS6jg(v zXv2i1Mg$52B?FKoz%VK?B*zF5fRHpO`VgTbBtrmdED<7+fk2@RtAzxt0^qBf8#Rcl zXHI(-VVRD`&A2qZOjDs$h>xFRPFul6)a?t@UH|Q`Jx^phnQH93J6ens%0eVE=ta0H z?|;=J9T)%h*}qpVU15BsJgsiI`;J#!^P_+K{tq5GcnMg8UMyHeCeXk*Au>48gZmD? z?>&F?{1?1reD+Mk+1I~y!`puSH{SevZ|i4HBS&2|>_e#NQGhrubeo8!%6W)6?RRGAm>U3o^b@Wo)L60A{x0kslC+yG%z!|Qr_i%T0xL@d42gPk;DUYc{m?sp z`0D5Sx+ZJNsy0Y>-+a?_yk_hm#FYY>0A~g{Epakk-}kn|pX=^Xv>zC~-Pjc#6OkZ9 z(hUIk24vTvJ&)c06bCfjTEF=l-@NsPTQ<&|s-_caJSbTTt`kxNo3$TJMn}(#Kf~NJ z+Rx0M{_u*0h0FIWU$$puW!L-d@V+W*>M{t<4N8!Lfr82I$U8p>0U5G9NPCxStSbMyAFnYS=6xG(pp z)?jb=g`=l`^RGT@4WNMm=_T{|WOLP9r_c}}3uqJk7)3;i+Ikk2iKR9vn3jxJ0?w^- znEvicQx`KQstk6|R%bD1-g5gHog_X`CtcGnUJ~61tAbmF-564Oiz*P1f#Wa3tRV08-&Qk{t}@%E?H{V5mC+1XOb5dKtRRWG?Fs3?;r> zsHaB+5n~NP=x(5)cof3lZ99wjpVV{-5D{apMFAlhxUU$wazZ*FaEtS=4s8bhKXyBY{V-57(;b_?5$+J0*hXlJ1!+S=&>X!0~>hz!%t z6OtnMs&Se1bu%vOBUe3iZr9xBKJ_VSYTMI#TGB{wJGTC^pZLjlf8@`vIC8&GG(!q3 z9ze(#RRHwT=#>w7z}w&R+pqblpRFe{9{a!khkx94=zqTczx*nZXegH!kyLgFonO|* zk;5hP;6-#c+i2~l7L=}d1?pigaXZwi&Pbk z$uI#0RU+LSPv88zZ{I4L%mNY^V<@A+aLL(1NZXC*%4dRQ?OJL##ConA@3=Etffn;_ zdsY*Kjr}bM0nmafD|=rl2&;wR;Qo()!h@c8HL;9V&)$6fcfRw@8`jR8mT3*DYFI_Q zgh?4tvsrKay`%MSoLYxl?jnFbz*24xEcUM4z5DWgD~DEA=H`pS6a*$yBHt*hs)z`X zif3a{G!A-*@nwZjUowjl%z`pArVu7{9}d)cph`z`wJQ*dXSY3=b|7X3cC2S|-XYmj zjkpvcc6EqsFeIkz@4s{NKOH>{0>ENyW)OgdLet-J;Ad@>j+}h0ZCOt zz(VQGGd@>GC^0S0Hg(^!!MeMX{yQVGwa!{=pHtjcLn9Uuj3tMpzyO{UB0)T%JD3U1 z%u&SI=Y@b!8X^()4nPI0HK?L!l36lHfMgtzMIf7HHp?_5YarFu0ip@5>M+Sw4BZ0& z1A>NfEj1yyL1@STL|i}1q=1SFFa#V#WI(|Y5zbryKmug}a9LJ}F0U+aZf^LBn}(0y zc67LF+4USE2G+1D5T$tvX_wkdoMi~QS>mW_V%D^~spq|QZGLk4QhQhtLx>_|NCkna z0~cNR)N5Y&nGb(N%ZbgMc<`ImanWmj>_s2^i=Ni^aF1TQRVW>h1KBAB|#1*6eGj)>`MO;5Xh>1-VjX@wdy|MnXpZdA4-|+R^ zISK>Lon6_p`zhC4qo^JwQY#_lY`U8hmtD_U>~@o8D}U}y&wXihz2gCl>CM>NQl&NY zs)`H>wQA$RfU_$r5BZ_1ANr)ni*N3_{+plv^S=m92YYk<9++}c*X(Om1+{50MgUut zzw_kQzn|Q)H{9+3hB+Rb8(gxy@POSbm+V{IH@~YG^lT`=Z5Ws<_JYVFKm@=*5IlNH zP*zltS}{)GTtNexf)4Mm>;A`+HM5`RS+QBPBKn5uE8+%Vnwtj&?5CRGuXASEvbLoyx7h|H-05JCZAX;i(E8i5#( zYCCUtPa@z<cJVJjs^?cCPIsi2N zg7B3H5I_SebLd||C@KI#VVkLtL3YDu8+F*oh3H^cy<9uff{UlgCgQ~E4W+sD( zlDVwt<-I(20YD0Zsv)Dw%nS{LD|h=Di<$&;2gHQjAejQuWM+5CH`cfuX@yz4}$<+WLFm@qtRPD(heW)wdiz zxbHC!dK5T>*=bD@8EE{e-$n{zCW488$sGIU^I!aD003YCdB{V4AkQs$7KFB;4aSg3 z_`vuD317z_Eh^z0BOnV3nB19@YiD2Z!fS54@iuERLzE+`)1{R|&w1rbroQ$RhknjL zO1rF@?DUR3+O}(*r9Wr)IxkFkE4`vUW2$Mv;%`e|om@tez%KDBI$^Ywd2*lo_v@I* z7zA#vdhi1e@7`Stp!ehPbaQ=kV|`;Z8c(-IP1RIVBLIN_Xbo_t(o@ywx-+9seD_`j zC;%1+_Rse(+r9Fj{VNx*%+KdTv@SQsP@ohE5@4vDk7bZ;*Ub*41j6b`f>AqM1emFR z0EAR_e9khph_(}nz=#}Fw{1~^OPY>+g!LHurqNjZ>FGE$@>y|aG0T~QA%lc*Bb5k& zW+D0Zf@2>O1c_~1NiYX7fFg>Zz7`({Itbk;ZbW&rE*+4PF71l6{AfLomlN}SGvkS! zpVz_8t$4QJuN6S(yeis@^P-ckZAykEYWhxY1v;=a_=FH$7y&~8Mw24eMnzSTRDf-a z$flo^Rsmz{;8{|JylfpUTxz!?-xR35CuTd04gC`rCwI_U7ow#voLy+q*Fl& zjRJU96p6+hkQJ>#G!Dpz2%v-!6)1o)$%qD2#99&oo1uWQO3a?wt3qAXT#L_nZmys8 zGBTh-px~VIEC`VGvfaCv&zwC~mnA44z47L3;1>4oAxpvbg!0#bOY~^>9nzwe1WTyG?`~fVNS8jL1z> zM+GDVj-eGn&2n?{#OY@~A9 z86e`Ix6m)<_N{=bvPe_c<#e>ZKH3^pqsgSItA@QWg<4`zMqE{0+o*2bxcBdFz1tXF zDBRw;-UF5wuG+VJ!P2g|xqfa;4~z%`1|E#%P>URwB$|BTP)#0bLjie2-PfYY^c&kq zKnxcrjTs(k;Z8R~J@X@RhKo|#9%uXx5J0d-CUsMJPhdf~-_O)!stpsm*jsg$LWq4L zQyV>K6$gLrgELStJ0iEjK-zBoFUb+nf7<>d*;ht@|h2PSeqv6 zQ#C1ZqU*BxnwP%f-GBaP4}IVxm8=4T0t*8Ok^umf1}**WAOG&rAHVDRf4|arDH=Gmfk(53=3^AN&xI*i$2k zOvhG26w4$@an<5d5eWbpJ1pEcuD|I=pZCJ?#-^cyh?H3iv-{AICqMsrlX4u~3)JA9 zL?F_(=V?!e?mRQIZ#(yx>3Lo@(^3H2LbYvjIib%kAj9(~_T3I~W!_!3GXId3Jx6x$-aG8iWj$wIMhM_B49ide0AWuAVK#VZS`Zq{ zw|WHuV)MT*>Cd<>-CRNYhF~GKO8n3dk_a&{z;gpultz zoQX|DNkOo-VE}DAu!4eu8e;+#k}+o=&zlOXDoYh&=!ygOY*3-^?&ObYQnLPDDY~ zvkHjGY{g-WHZ~=@!jVN5W%iRvRaP}Oji?xcrmn|hG~}{8LrWoth6niV|{i~~M zXHT9aW5%P&E#J7|vWH%k5BdrUN(xMoloVH$Iy=?&bev&_9b&U%FSp%Vftx+qLd(_@ zRZ#*ULxjqRK&a>!ckg@ZH81|(AOARyHuFK@rz~T??&U>4`O=Sk{6i19>XBqnxIx8` zE(Aa%M6Uyr|LLE;<7q$iqpQbG645QZMh%X=`{N>;L!+(0!FCc5? z3iK?V$(f5Uzwg!0c@AsCstQJh0U0n-Op~!}7kQ?jI~ErI1GvBKp-z@fJ3F#{Q(IbJ z`&`FVcEa5d%pn?Jf792$P6!sjIlK4ZA@xGe1@Q@t<~F~qXaW?_P&Z+adM+#SgV zSh(@*n{qPU*w~tmw#u?BYu3hl5ihL3wbHQ-e{5s*U+-A!6}K$+vje^2!ui3G;rzi} zbIZf|K`$?iv&NFOBq)tn6fdAiii`jzWa2}KEC7dba*#NVGjlsrT?qz7mEJ|5fNxb2@?Wnb0IITYJv6ePY`!<$BwXhjW5yGuBP_ZPEGYh-+$I4covK zKuS+zXH$~6N5?+G3ya`MRf$kVh3NF^7$GzhKoL>UIDIP|q0|f@OwbVt{EpCG4nRRb z4H7r3NY*%et@p7{xydp_$TG8jc3f7q$!x!u_j5BaMV&iCDB@Xhv7TF6@+#uJ zfUtyVB4DgRP%_43#`FhsD+^15xjq1wQ(ixPh7r_3Q`dPhG)nB7+!^TQjpxQUTN~rk zXU;T@S7sviO+6lu3BVQ(4XLOhP(cQso1eSz$dPh9siqU7FxgnY^ZFYvzUl#4KNFBR zgeYX6G(d-B`Y~=v(m-A5p2=%Ra?hiFc1R1Ph+Cpwx4J|{0hPnt^@ee7W#3a?@}htI z$j7U#aW-((WLizdl6(0zuX^8y-}m7AJvcFM$g3Cx6(uq%<-vXXKmGTge$mr^{Nz1n zj5GiCFJJqeKYaV^fAN>|JY0cM&@gEtU1BG)7!4G$um9gyzYL&;s8M~ul@BNey%5Ro zrg$Sp2^nAvRlspQ1SB>UQp2d3#rIzOkzf1u-#}F>89GHWYT&{vulm6seQwQDA8NZn zP$0p+)~IY>aY#)JcR;#UJ#_;&+f?|@J;HOJhW2Yara_aMYvUjk7L5SWAT{IBsiSw3 zB>}&%xZHPz5K~ZX(VS?ql%YyWA>~dr5={&!ffm4!pgD|?3vMK8+=XNWQs z<{DT)!pK4f025T|3}UA6V33N`pj}%P*+INJqOTToG^Yc95Wl+9>jE|vukTrf70{{ZQNfNfq+$13DD7IT^Z|C zRY4s&m5`P~L+CjWUONF>iG@3X*Ao*up>K7NawbiuozV_k;n-izbvNEc@ z;F5)fg}FO!zkB1%X|i^HX*gV1SXy3ihK`*)%>a!k0eH`4UH6?O8#|0xqS^~NT-mj2 zbolU{x835571XmQPx3e6(yQ+0<_b^+B|#?8ST(26(IXlKep|#ryW5M~pZFfP6tln< zNg^Z}O_C8P9fF1cl!O-syPx{}mwxsWA8y9$HaEUfE&UdbUiOj~z3bXPeZ&JFP0nh= z1~B zTZ~4d8*aP_z$yVUJnD&$GZadm&huNtV+5cSTKUDsn4!fSlOpJ+|Ke}o^xxh}%r@(x z2rKvc!-xOS6YulThc#RaOUTLxcNUdGW;5}Bx(nNJsAk4_o1Ja{=s55R;bA(Ivmlao zbp@saI*R~y&vc91p!GVC2sclzHIu1DBH`T!_7fpdI|Cd*N#lsv5H$*(8-xf@Xi1i| z4FW(k=LUq3tZ{jk4SFETB1TD-H`mv1z3o=48$kg?1~o_u%7~k+TT?kT8GmPe^!cOr z7=-yeUo47?=7yIoE?%*3dG~?E!C(%-0*h6ZrdCxJHV7$+Anmn8mmu(E1pG6Bp)eirlX$WEt+I?PNy&Tw}}Pt5WMoiGq4z7!IKj(4H2W@}I&`7<*< zWD4`l5NFaphzNp6NPs{{0B8*`Qlq}Cbko=4@pNrm-Zh@CkH({>5vvHmh!$gz89joi z#&J0u2ppj=RRC%6mnu^jqd=shpeQ27k&>V)s@if?EiA8WPDZ|}S;bkiRo0tlCgW+H z^%vGx*H4`|WeCNqgkmKCBq9P!##&2;2xE?(3|X{fjX|h=vz+hpHJ>_tYBU}p02#Dd z?x*91IVZQgv~X{Bk`=4T#PejlwKc!IGF%uQBszBdgnDG}RkUfEx~%hFZj4m~uaY^( zthO)*FFZV%PEVb<#{y+!woaYA>n3y2mG{f~mX(R(5Zx3Y#hLRJ#Bp1B({}h9mvbhe z+jUS!7qtQj5Q~sI#|!|BApw*|$e=>Q+VmEdpYf6xfA-@aoouYzT${Sa8pen}_p;ag z$p_y3h=)8@41h4H74d)`fGnc=`oRx-$RA$&&Yyk7&rC+>8Q%T-@7%L{_Y0o)Tp$7! z1f#;JoJe6}5(Uf#Rk1Fk{<00{)Da1=rxML-QWBAT*LTY-Q? zf`k?v=%2msV{dxXTfDC`%CupV+1&M?`hpkiKDfX3r3x?#sGx+1F-CF|r1L+6@@eHe zvC!@A!46BX4dTaxmo(URuO}Vcbm-HEZg=`xbe0By1P11@yYKemb7P!^#l>Br@WLQ5 za0h87dM03ONT>n)YMKHDn#wf-1CIn5K@}VsQLu=BBrFTPy}eVXHrLif)hJ{|L0(V= z)C4Fk$O7mES#`_%d$u-jJTv+Sxz_?3lI1+#J2!V^dDkU-cOTxpv@kc{%N(L)00xwTqR6;1Z9MV!FxYx{HSg=CX=n{_{?ZJs;c!#IcfaVbECk3fh?&) z7SsS~U;$YSgX=E1{K&pN2ho_o|CZqWV`vAfVTfZ$xna8#h};MQvS;zWtfq*xxpvyt z>?d`zx<0C_5((?35di0G<-ITzuBfV-0E{t~3=)dQp%FFfw5}z1Ac$npAX>19Sl9K! z!rX9SxPEs1*vS)BRa;Ar%wTC@etv#hig9kbRVovjOu3$vP3gBLRlQFS%q=bK;oZki zoJ3>17xwJEr^dR(X9=-R0O<{T7hig0I^NnEjfhzQP9Hl#R9tfZ%Uo_eC@2buX|wws zj}5V-aJsR*j*HsfW;XtN;L@2D!H6IdfQn%tR3RZBOg>h{u=kV~z3A^g_~-TJy2&hf zXr_Ks^yM#p*#|%N!H3-M5nxco8wOE8qby>F*xh#_h=Q?&%d-q^=t(89 z!djCv6V5x55^3y>8`DgQFO$?oNDq+4mJ|pmU&OR0=~MQ9#RzkC$sVoLR$LZ*c^LF?)vny$kb~Ev{U!XJP;R ze81nz$q*qbWGd=5)3hO0?^8RL*OZoHHYPwR4Ht6Z<9YtwRlI^L?AQRN%oRJ961 z82s&32|)ymF`{G)kw{3bn!*}GD&U1hL$Vi)rKMfVb4v@gh=7Ux2oNAvhNqIZ_HaOQ z4gfJsf(wy04;Q#gt?3mdXich?8t)ZJKpU2(QX~>l@5LB0L_xR}6b*?g8JjtSs;Lf? zL4|$EqIE4iM}V*~+L)G8RHz$PBSoY0ON)z3Syk7k&X!8t>lGj+0ykAXnbyb3dk!Nl zEH5^dKXdl9wd6h5bz@v+Z1@R*)q?B=frbn77hZDNEjNBgg|V(dY3-h4$NKq!BNv$* z88muBaT;lxA5!QcxNkXYVh^lPouWQZ`dX%3t&1*IxUPYwvfTD?K2DnE}GqAgdZBWO?;#UU~Q3r#|s# z9|GI2>*`m3`8Tfp;QKB=bRjxa0uU1b9TJEr5UGH%j+^G6ue%NujD@Q5hcCEjP~@|` zR`iJ=fu$%$ay53c>K-}wXf-hx5JqUa9>i;sBn)!E`aL#X-}6bP+q z5lm-olJ@T?_H)l*XJNZe*G|hDRZ8;KV>{i>`)4Ted}bSG9~9i$BpD$@RrBeSCx{S1 z^WI!a0TQTEs=*QjMIkbPWE4aL+d&k<+(J<3%nMco3Xzvc`v-`%$qEW824QhHcT~I~ zs{l<|@4o2rX0pM`$^sHboYd8LIv$ND<4IlBzN#4&g)JIY7L^878ET-Bm(_ZF4TONlBGsjwH4JiSeFxAGM8`1YyJEl0&R4(lm=2y#gp35J`%>#s2MqgXAtG z4Ij*S_=CbR)a?#E#85!%n7g&{`>!d{s@v#Kb2@j{LOfeiS%uF9GK6j+29d{vdh-h4jSJ8}BN zbTVzKW_fWqGCVD@ax|KjmH3mVPVF`M{L=iiF4xyL$YA3eY8vYZoeL05S**2Q0NL-_ zvum_@@UB~LBSZ^;M(@4tR#ZK7>BW?(gigqmYRAL!w5D-~mPuJC=m<)yR=OI0oA&SO zFl|Ms6C4b04#X~0Ar(sj17+>bgUtq6-U4B#Oo;CC|t;F`Pe!A1JgKH-!(N!fq+di73RC2W0Y|m2t<|@$ok2W9Ml(ahJli!G>|N{~ zTwL5coLd?8mU1^JGKZEFP>B>RN~9T!s)oQ8QD|9$qyj`FO)vnW2nIP57E~)~iYP`+ zp9;#`Bx<)=L9&Agz^Z5pQ-}x16cAB3GY;4{v)C%7DANpu9=(0mtHEatA&7=Mo|#2ClImM}NjN|u z)`(%)q9HVjfP@aogJJ;D%9I&K5k+UhwHrewE3&*8%*_wx=3TG1cX@9yH`u*v@BIAI zJ@?-Hm!J3$As8fb)|o8$VM%Gt(hs1TqHPeDwG+}vnG*z!&97};)xe=Z7eO@m6hxRC zXRSp6BqAGUEf_K}Ys68SwhE)(zJfk5XG|uk3 z;LvEab>`k<#%9`7#<=6R-`-ywF74YxCMIkox}LKV(6+L&(*#hBvqWdmbH@ z&`CGP9JV3UkOaZ8)}V;j%FZo5>!mOK+dqH5Hr^J_R}~r9fUQ?v^HU%A)JHG7_`d8> zjG}-51BxI*?OkU7=v}|}{O7*x#&2AY#@=z;9dCU7>)!E>Ki$1|7q9{fsu5uTRV4*= zU{}{S?z-bHV;xIF01tY|BSQce5flF=@enY!@lb>i7EmOxXso>R9oPQWZ~i`jCvu`{ zjCU4eU-dk=ubf5dHF+ixX-;2yvrZtG#Nk?jWK$9W}p2sYH-Z|ZI zF>&PFm72;+^-x+-($$kJfA0Ac756A=V=sFv#MU%T<% zd+zd8T*{Eqh?KPDYR+6|0R%z_aW$~cDU$2=J^Qj5DJf&U zv~Oi`@uEB%^au03x#7b6aB+EIZhmMA*Bdxg^&)^_Oo4)eLG@=%Ek1X~0~cB0T-M4s z%veTYS)(j(^L^X1pb#q`ArkNGcxxn#YGP3qkwHV&rfiNuhXEFW%WNnB4!v%zb=))% z!vrDoWiYgp05)hEUwhw#_Hryrh|FAZwU`aXvv2A=&kW(7^su!SMiGsQlm!Jn(q&%Je#<@U!q;RbD+ytmLdJ`uA12*N}lsMyS} ztUURJ*L?P)AC+oqb0-ao_h(ps@<(6z7k~X1M-JV`OAX4XASw)Gkf74#!Q!7^`|hVc zp!J5K-YwJ@qCDww74)i0@{`7^sWFS!)wlg_}g~~cAST852vs} ztE3c9ojeI5sA!!ldPQ6p6hh}!#*^{&-}vV0>RBsjTn32BzAE|NyYJpw+jz{A9tAFk z+N%PhJ9~Qd__2F7*4D<82_ks!va@bGYMZZH@)lcNI*lL-Sv8VxI=wJ1tND50r9 zyh?(Ys0s<>`^ z&Ax1E@44~JUKuo{y3A#+7z_tl(HqXq8)u7rV2rWO-gD2L-}v%ZkO&%i=%XHWzlS}cC|vE8 zedF1KG7zvd6Y-%GloUWiTTD{xnHvI2ippy9%v#6nAu^7)A<`D@Z#yv2(Z_VglFOoC z>$)Z};6Vt`SU_-OP}LG{jW*QRf*#davQm|$S8&!kJ6xQ1hBoUd3&&w!sG*y%~eyKa;FaLJvitOCeu=+ z66LzC35`Lrc^-O7hcpZ^3HZh3T^Ag=rytceCdz<)W`nn69@JjXut!8NieFYU=+L_JiPy7pM3wbpY{SjskzR+@X!D9;g5af zr+@kt82v(2AQ3gjs=`;VzrNQJ)x;5K^;*eqE=@1i**nj-SDg*&Akp^a(boZ0B%`W^46vR$c|t%DB+v6K%P|rU zEuc}Uue+=D;?-W)2}1QBQzSt5E3Q1vG6)fmcW4+h7ym zG=LbO%;G{}mV3RWp}l2&8iph)z&(@6S#9P?JXovbLSYvH0uYi10T5JDjUDX}!B{Jb z45);a)EgDwwR+++-#O|@kw95bZ;k%s|Nc9pmLkkR3TRXr2oO`1Pw1x<3V=e>5kf!- z*mOI<)1Chkk_P)lh(KhCkjPphvesE=t#i&fmt}b`&x$7N8Rs%G##jR(A_54A z5=RdOlMEqpE}&wqN5~CWVMKsB077*Il&1=KiAIaW7dG*t*;DsJg3qL5qRJkOCZ zR9VFGidhJ>jcRnXS~yU+%`MPKrA6ECWzOWr8tVwHvCbMIENs158Z=A0SBxbKAYQze z3S?_@#Es8$YHIK6Iuz(eO&84~p{jG40EY(X2v&ealtd@>WIW!OOeQ2+v)`IjXErtt z_Im{2)gRoua@SqAk0<4HYipxeU0Pfo^yiw!dk-K|H#OC!XAKzx0HFYaEJ}mMm_2*; zZf$NHyYpz>ct>Q&j@CDBx&9j)`P-=g0RR9=L_t)SJm5jjnVLDMHH9cNZOFf?k}%!r z2F}hw{pWzu)(EE!>?)mfPbpCigZD;+fS@cW&7R$dfAD!f@%c}GQn;dwph0Nl#OCRj zzvu;j{;5ywS=`r19fOx4vyBcbe$f5y|JL7n>o5J+U$9frn%;Nq`yToO4}aiQ4>TD{ z9jbLy(W;lPeEWL!2u6kE$mRDL%oQTaL6xAY3Q_RILu)QZCc;pNkDvQL|MbS!znQ8U zZKk4V%WI0RRA3^sTcYQ)jHPKwtj) zw>QqL22MhrWmnwyioFL8I8&^yp8Do>-x`!D#H+<`nk9^c^H-G20yKW-_B$?KY zK~z){5(<&A5N!Yj4P;pbbdHQz23EwX;a*`^&)mCv*Tn(~DAdx9;;)Di-FUd;y;&j< zVoX*6LAj}!QOsyO7EmxKb$#TD%Z?np(DpK9tn0EYoAKu6`qtLw>gISlt|p}y4#rAA zK|qLAkpZR(o29>dx@lJlj2b`^A)xDzox1j`-@0Oc?!eq&U$3{j=)1xe#)w$LDoFDH&SWgV*Wj2c!kKogcQ7}7W-7DNyWBnZH9ArV?C zE5>0`M9vTq88X&bXRWm+{J*m%v(7n_WiE5pW;V0N22#5*q2eRXB$?%#f(hm@xdS0E zFB#N_W?JF_AdN~P4Fl<;h$$MhK%i=oDpdBW>KQ;#l-fvXAX}#)BQ2E#2}P@E9d(sx zp7#lfgY<8c>Tb|;7Iceea2D0VgdtEttuTuNa>RrnT9-9>t=2pNxPC2jJ+hP;lMRhm z+?r0T8#=_(r_OAQ8fDF_)An-_6u}~?5oaxtGAJSn0tkXtley96=3V2-csyljjGDF0 zb-Y`Rv3qv!LKbJ;{Mb_ zf(ws~wx(;RPZA(BrOW!GGwY}Cx@*sc7ebn$1%N7DC7|2Z>l_HF=ji)$Ze0Vh18lV9 zhm;mbp=}}(MP(*K;u~h(eemKZ{rHc6;nRPi+!zF3*UsD9Pn>$yi(mY~Pk(CITjbg! z0tyIwB_Sjevww^b0gm>t-%Hd*aNoyN{Z{fuS!k&%ExB({x36p{cVX%Qygh)tHWwAnahzMy;V?b~SNsz-xhv>@1AEv6*4i8M(ZZCd1nKZ(Mu|Q^daan-s zMo39*kq?V}eqk99Q7sXB55i?xjz*)kv+JX+&Bl^Ty zZyx_UJRvFoO=c+rSjgQRWEU*W9a&sHynC>Bp;(w-FwXh1yz}hY+gDfr_ieYI8gZ!> zMI4w+QIrIQRl`_KijHsGBGR_)ni=uFOUi9+3DDo_Kc`wUc<}$KjcoiWc5C+C3 zbO}EYxiF%d!t5;|6b|AelEf?lxacv*1hj#6CVYH8s#XbQ(3Ip*qG$!jAdGxa_TgJ& zCOd_hQXn?;(3C*GBLp!`#i5FWLGmI8z!`NdYVs5engOeXtJ+7}`;p}esAyRvBWxNU z=2a+y0fLN})mU=Y7I|^$<(I6VKD)lTX^>XeHx3>;jBcb_l5z2rw?_~`Ne#v%ptD)! zYY?@@*vvX(R@XLsJp~0M5>;!A0*=d4)a1FHo1a^lTNsbavaFhNI+||I52)8G8qd&p zMNrYQtcgtCFTf&j7@Q`Aq{4&Y;L=MkxqiIGO>K>>rzK^@@c^PgUBA1I+PVJX$}VF` zSVOO&wwCXEDEw{r&ZmZUyiIrhH8ad98;L1t6FHVq?V+fWQ3b_v?*#`R`Hgs7O=FiG+aAxcLg00K z5U9(+ohf47{@?bw?-hr`?JrM9ptA=%wy*WbI*wn8_aOkF_r4rW3>i@E^@oTgh>k26 zy8G^<$ZV`@SS~zr(Y{0bvdj!}gDP122VV7%+i$$*^zoxC`fp$O_scH75R??vsmrqI zlOCHt`SHEpGBzIBi6SA{yq3CV57ac$2o5~u*`5mP-+t$@JB}JJnNqg8v9`RtTbV*k zpi`JJGjoCd66Gt{fY1SE=F^4=&R9<>g9xZak@flm2<}*5fFvZKiY%(A!#0Qcl-bw~RI1G}c){6G)&e292pi*F9|tpE*sGt^GX|}pkY2UM5Q;?k;n0v( zH2fc62(NL}N{N2fip=(KAwrseoWcQZRB^k=%`yTh;L_C|+PTwpRuzyC#DD;^h=3{^ zKmxI^8b=y#zx?pifAHyd-*%Te`1+T>_4~i~ zhi`cO>+_=5pm%6*y7kV*4o_IDm5Q2UUg&lUF#(**_i>PNHGKdCHxnTuCG(<*2 zqzs@A*;_O!fP|t-mgX1cd^N3@l?9L>z;pmrhNzGwQi~GOk9fRgH%HH@m4uxXu~ZT> zQ=OU)^h}j%lAA~y)Ey=QqBy2xQ*bCl(pw=;xk5BxXCJ0BY3{hanDl$p9^81uP=i8Q zUIeN@izB;=JvkCH-IfF-orKw$0#vZ5SWl*&MMMH-GnODTp)(&LtZi&;ZLJg0cswOP zsXa?oIhz?$LnJJ-aswhjwPY+&W-~@4q=kh+W?Z?kIh{6*ctWt`!g4oF;{$bTFg$yD zV{vXF&$Ip@&x?FIow8?NHr2H34d(JJs~g{d03(31m#V6bLFH z0(9Op0V1(wrTt?{{n8bsj28YgMp=+-9yv z@Y^HvMU_BReK~#L!ymhOYVF(CeI++Y6f21S=Cl8B;e{9f?CXBXx!iM!5b4zlP)&Kh zKlk4EzT>&idj3XLlBbV;;**Cjx$q?~_-QFnx&F-OKT9e`aDx7#{R@lpeGw21_D?bD zJw-+&WCfSw?Z@tY?vK2rS>JGIMTBxUTw1yMsZS9QKnt<3L{%BBLy_TdNY;2SavkNfw#Y~M=ZZ{I{y z2%>IntnFId3xUfPUHDdNcl?T!B1nfaJQLt@<7*H$;FNv8H_TnmTuZBqFb0zV0u-bG zG>A|U0S%(6YQv4PFna_w)|m!-{rMuFlihm&frLmx>_b(m$!NT~x;|dptR`hyPHYpV zz!DLPXHaRFkqFT$qI&V_$=clI*fc;y%r3Lc6@#Kt(xjj@;pHd*)U|`1&DPHPbPsJe zQ-?EI+xbG6=}t(@@$MIGM-?sFo@oLFQ8g49D;g%_8cM!ItGL^*#-t$PF$pu`%4!;n z6B0U?ZTpICBHe*J9Ur>Ixvi3FSIQy+Fo*mSMZ2%c>;agC3^rvonogLT$#|M&kQH;z z^^i<%3jhRz9WR4PP3@bx;lNoMkE`W{#bSPb^X%GqI`v+RBLYwm3IRA#Vy%RI;|$)}sO3t~&?FlvCQWW_`M=qa? zN1JC>DMOxmljY_5`mx*YyzsJ1Z9zUFoH%qCq2p+#G<&x~Gz3X* z(^rNlmWmf55asb`<1tTv&S<)I?Ate~H4XvAlc7I(_j?!i&cF1Umjha53AUbv4Ix+6 z#+RS}{1=RMh+bGPx$J(%8fav8l28Ey zWzI4fmz(3OtIz(C7j2w9Y19g^De}3w<*T3dEM_)@$}B2z*ePPeJ~Pfai^i&|FgITB z{_ZVTKH_19NL7&tR9MAeOf+LFtR2TFVHQj$DI999*(L@APGM3N~p*4gE zG;K;z0RZdrL9bZew|CFtuJL$uX5DDW7J|ehjRqR-^|FQe1@G%&uV`vtZf&leUYkrR zmznT`By!YI1y~gk**9C0trKU??A?E0FhAEDF07qBiy)v<*OO|xMKo_M8Bc(UXnez> zQdd=2Ut@!2(bOgg=I7=vI&$ev({GjIY38yF)YrOk_RMjYA2@QM%|f?P4D1f=Y-`QWe)w)OMLc^JoDJi-~OH7dKWU3YolNJ3P` zVGJmqVpSz*sER=aHO5+N0pb>Hte!n}{GPps4hzJVE(T3n)^=rZ=5KdzalK;9HSvXZ z+Gd!oaaXIS)1Hn|a*sP_a~mPLW0KO*ZR$FJU^IqoEUQMK^|f^htyP@^H3%T$Ef5NN z-*~a(ikCAxnNC3k5k}K8eBY5v^1KRo^T zr4tA_fK*jem6IZyZ+}Xf0~`Gxn4#0{>zL54sw$AL>JSzZgyH-`nBR&LWHyXsK?2m& za7zI}U~_Bq&2L@5wYsjJRn;gFkfJt?RE>wNs$3hdpEz^$mfH_pbof5^dvIpZ*o;&G zH3SxvSrt4Z09cm|=IwA{4lg)Fga(kA5s^KsA|a|rW_4L!HxocYrRd^yf?loKOow*H z=}TP78PtWSBGaaClezSX=RS76Ke~UnIA+_6k|NoL{6bNDu*V2-22;>0vy={M`?l>e z&MZ|^hD|br)`WwWI6$3Op7%V(U)|M8K^KL=KaFSM(BVx%01+I7PV|svxmPT*-f%cS z91NFt?YiRr54iG*`!4U>v$Ai=6;45kj5Wp>lR2BC8Q5&!$}X2>{ki#)eFMy(9@+Gq z01LC{29)CjgQOMJOEqoEX|=wwK?Da6?dcW0!Z}otrk;#8>#`(JYY7q15?NAF7OCs1 ztf$`l2zF426hsu8J-hcDK607O3l(jAZ3z6NK70K5#@ZS(84O-6b!}~0And??-6jHr!_s-}A8%U?NvV7CZB?!1WBjUfHv&%N>A zzWOCl5fNntMOE?OnQN%|7vA{Gzxv;Qbv_>$bz7%b-}+4qdIq7WIi{HPk8*E6{kk63JUA`nT=GM zge^$#T)58o1z|Ch52`_&2|=~4rU4g|q5fb&qo@U=b{^VRS+!CZ;rYs0D@CSuj#q0)&nrxMlia8~8`)BubMYg!dtI{|D*C-{XIw zQYOe+c=4?K0@6Zvzo#o(0l*Mo+iNk7(})IJ6P2_542XIm{A5%NL*JUJjvORoO!P{z zbzYJX#}5e~soM@%dnVF5Qu5e>K@`%&mr}&0X#lOWnJ5xqHK{~Bs%8%RgT8f8mpOcoCw zI5gQDow)ZdQp;WpVN=z2-|}66%a?X9H>8phfN8ngIP!MYzSG~-wBM}_K}y{ASAX^=qqX%s&$#yFbG6OSyzEtf{dfQC@PWe$ z4X6nF*zs!GsM=Tk+$(Rr{fKtf-~9F8xk1kosKLcyfB&A{Aj--X0F+S> zL6wZlnM;#4W^1#6~Rx4OK21Y8X*DO_hL9Ze0X^HaBux63#+kIPNzhI zU}MFCuo9$xudzr~TQe2~Ie_CCI-ZteLq$jt!puz;$vdhf&68)J+$fvN>N zk$s0}-kL{%nWou^k^lg$%Pgr81OyNT<7j?E`T$dYN?= z=Nwr$M_iJ4v|M-vM2l7txM>Kn;&ErGPwfAfJ)Zk6M&f9bj+x5y}>%lq~Y2MbzG(SVYudISSV zg_V<|>GPiU!sGYeK{iuGAk0nigU@&tIE%^%$|9f~!F+UJfR#ZB2?@ami6lTI_O-G0 z^gVa)I4+5-H<_~}3jxT-Z zUYn1aNkeRmu{IO5fX3uR^ZmLg)L3>%4P?aJv*O&wTD`T_>$7c;McH`YY;CMBF6|Lv z7Ks71L_gQ<>w}=Nx`-gL3_w`9X%LA3jImjkD>QA!pbeVD=8}ZmG&kLJ(|B{Ma2a~< zJ?y{evPV4X;kM`U+yGh3jDbAwXO}17{?&i_=hG)oNv$`2{Tokw)}>G>aA+_I ziW&x>fB-_8s}?|PtN#NNArz8|AygJM07yuolj@E*EwuLU9KZ(ciRy0jwynqQ;(_gZ zV5S1vr#sreBUr7RbOMZ>jB`@=7_mAbB7!8^ns)GG8ybe_Q-m%U;dP`8Tze!`6=RJd z12IB3o2i+6p&cs_@8LF~?=nNdW<@~^;%ruAdEu-x%7kc4Zu25%7DcjX)SAqSh-|KJ zoSv?GX{^afu$H=)yUZEpYOWaUKCnwcvW#xO>-e2V@2RFWS@PWY#s}V5a^na905QvK z(eKaC&o9HStUsJ=tv5>xDyl$ig~Y1&D#G=2JRvgF>kS(AqCRt371+O^%+l12Di}jR zq@dn=Lm8?Lhr>%RyX-sFWU{g0Ak)U%%uPp=yKcGpqATy44+mZ)w8~Nq-BM@Tzg@5Y zpsHy5?R%IB*sf$|JCMXI*zH)(8CXhygci_ilV{n}U-aVt^?~=*t7`~^r8v!QKXLRw zz2cQ0{K&Pr&DjeoOPtAO>asD;{`PPG=0z*JfB*M?ul6Hj2Z(^=?{n!DNXo#J_?fDL z!1tcndhWAddF<{x$swvLsWrvb&w6T+6N`@nbQBXsr2Pq?A&;)Aq#>~%q#X!AM3C;h z>BcJ`_HdWG1_Thvka8SozH?D`u5t2m1FAiDTmHjc*lvy6(|z7s3mMz@5ya>?#_s-M zbaHUp2vs#mv=;(et-6#Z55fx_dIaYf( zLl&h@^Q2}ApqQMB(hET?y_Z>X+q^CX+pf+d$buu2EICjQY)#7ltvTxrN z7hiDUzGwXHU;X2q-~H}*W7E*k}Q2>!1LH=wNE#j37itg+t3D&{We9 z)pH_2wJ0Ezm?S50$Kl#02(u;nkA&tNGTC`<$&uWNV>;HOy@n85Z>Jfch#*KOXM;N~ zNfW?|7bWa#9}b~0jtr?tG9AhKXiIp&)(_lyY3&tuETgTaC6NI^MP?84^LEhhiv=!4 zn7xE??25o)MuRoE?c>^J>AA_t=Dh+zd|l5i4fh`0XEGg4s?D?Or_Y=z%hFiVrm+~R zGeW>S#9D&Al6qP;)2beg)>qex;c#JLv1YvJ$fcKEcJXLqb>r+A7K2(NsV}Evvew!n z%SY2KCGHo+v?_&F6g{&sPEkM=?{{y% z_yJdfHL9!tgho~Hd~5dqP5HE@|9mezzwSvmCVp%3;Dm^PEJ6bU>Sa_6@~2+&;!nTp zU8eMqo2sl#ZohWjx8C+UfB5TfctdEo0s;a+M#YGTW>CEDzrJ?3ci~rG_lChRCm<>P zqaXcf5zinL>V}Z|j>b*%ikJW5(WAE!0I3>6_Vk2jK7DR+LBsEI zOhOH60DLTJN*IK)rdVAGXZ?@%zyOFWM1#E1LZAbuv36K~A zArQc%0gvSIKJt+~@)CFfLJ7qfOlY<-xX4{Dk|j&BB+I(ey}G@ezS~-B&N0UOW6rhq zKIdLJd0SWKoW1&*bIehHV+>)y@#g5vV~=0^%x4f$5Futj6ixjOlYzVgxMPuF06-I{ zf~Vu(S5f`081)?sc?z~}M}6A`42URZPp4%rc_7i0`|EfO$x1rQSj3mFq# zUR`D9oO9sKArTmw)M~*>Rmu%e*;4r#KxneVqZ|RpfFW`^bpZq%FcAZ*XjKQ6vL?-x z0g?*1O@rNG1El_R*rb|5@IK-Y!7$Hq29y?NH60{0Fvna@ziKl$N&B8U@*LN;lhCf*OF8* z_z;1OG);nO{UEVCGo+#xF$&B`u`RmBbWJ3T{p8w8?f|Wj+ZMs!X>mW@%EhPodmEK} z-4EhUnrvR8p)Z^suScxlUoK3P^0h$CyxT@7BbxkpNgttI7uhFIv|1 z#(2a+d-oqceBe+y9F*dv_UO$({iGc6R)1lsaCuqPgw*SFCv~YJ5*n+Z4?Nyuf?VT`zG?KH#G+ixlm9H~v z@oCl0ZKpJbEhRz$0|50JqpKP)6xSI$#fU=>N7rx}BL4txh005*6HYS4~_(d{#DZmJ4Zn)jPAqAPaS@}M8cK5DN3}>b>bYQa;q>YGJxjX|9d_(Q z6bPA8-cEyCj04e7?hZ4bBl@+LAmqbbEPj{r|=mPq;#F%rh;x~dqE zT5L{5>_2V-}tImEcA0RUEkdLhxdP2 zhFgeOP-aMo`EU@va^J(}PF(orZ~NAx*B^Q4frm~#`NWYUH)wEbn(W8c*NWI?oV6Vw zT2BT-ikVvU6mom)P8`@ai1ydz*H5FAU6ow6eVbk0I~o2A-)>1O@rm@Hk!}<1AtE+y zqE)P6fx7LY?Nr85X>KnfsuE|*u}g*E;vtE5PS<-F4~D}K zg34$(j<|p$y}6(iH00<26hJ~CPo$$UIi$j5EU0ks$e~?(7q-?{FI-$9;5|o*tl#r0 zj$DT5K?zI=%>gKxDW!zQN;C0wef+V9`*ZyRM-Hs6UN~C~iJb-yB196Z zx-QEi&w?jkR#4=HD{Ayo`w)V2jsd|?z|?}OQl2T8GdySj!tqo8`} z^x1xY?!eJwY#^e@hza`)jf~$G5Qb@#X7+%1p6KGyxiLUHkJVj~fCw z6wywnxBt*yut01;lsOvv@Qc6rpC7*eK~NAhhlK22`0Cdz9zGl<9?gkXlnASVVx%RE zDIgccm05@#NC7qG;)6k~0ZyU_`y-$fsqC8nJR}0umgU4`cw|JN4|* zTTo@pdf=gHI`3JgOCW*PyBMW<*pgwseT zk!Xlus#}BMq?$0353>K@(Q9wKA=E>!^+!MaVLu$W%%NG9=YUSMc7arI{qp4x{l)wC z9Nt5iudS{t2xx#d39{)W+0HtE;;0_&CQL?En+tsPx`r=d9(O#DGLr80cjS&a%gJm1r%3S z&VTJ|4?X{RFSzNZ8!oM`jVF_w2mpOu6K7>zWrfQ!F3ZZ-wR4;~hndw?RaNC&uP-8? zVB{3lyw9@St7hz;`K&wcnT!YPYt)-#MiWql(@#9%vTWDELu4XqKt_}b+Q$dnL1VUU z{MSnIBYH4!NvBYjVl-al}_9& zcSsl`yfd*^U!?mvitA(^48_e zxn9RWJ6ZSU+n%*=|A7l@=bwE1aj8RAXTjIyV3ZeGUDc!EAZKdYV@5}pC1pQCBV*1% z(>0PBYmG7XeD!TmjKE|{7clGQXchAvTXrnEZHn;DRcVa|y>si=`Fi!sH9BKUqth@) zirmDxQ2>PP?wZ;AO!+y20jQd3>@foDvYBIT$Ggphd$&uacH<0uIBs!DSWYSt$vERK z1Y{sk2~3zdt|k)+-m7K+j1V6LeBg|hm-jC&_RD&5;)!#U@yHu459uV#56p|%P)*0z53$A9iOfA7EVnO^`iWCx&x zq~ag>%46iBi52!AJDNKRUJSSv{qsNn)8G58-|mprWE}-`ZvT;MU-ar%eB!Q8udHl@ zFvePP$AG}hra;Vy7J0XGPC*HnIM%uXGnHCQO);R8{2W_9Xj-7NBQ`UZGoS4fu`TR4tNTxtx%Nw(Q3K1ff`|=b<3DQ@ zY7HvAxdn0@lQ71EQI_XXmeut{>w0UrX`oDmiu1d&V&3`MG$^Pd3!xEKNQ~qRpsAD| z%*4=Qe=Q_MGB#CEQcwe-eAoP*>kra{XAE-)-p7=p#Ap&vndTKH6~1ZcnHCxVfQC>< zK)NYpMFy=Oq9s5?F=fCYvbnVx2fb7D4;(nkXyv5*>Q^4law3DFufFM2^gW=7=vU*$N8$Z zD&)*Xo@H5DnIRw()m8Px<6nE~YmYA!-J^#OqG9cW zYN#gFaBE|0V|{h?A|n(<5kde3Q$T|v&#JPjs*1>g0e})>2wGJW01TjW3yU}3_N<^b z9+q(sbIyESKK{@{$`Seb5z6wp-HGm)stsW{p`>GOr^#d8yX{lLhb9# zm5ol8huV)P^{d|aT4xIAh~1-)KJqL7?*Hyt?L$p!R`9`t`@jFk-%)N3j44RX3WZ|= zKvk`S2GQDU6?|ESNnMR5<>t5?3E| z_4siI=qL?koOW&9OKG(%X^*}rrYypPcGXz7_(QtV7 z?5QV?fA#Fy6RT?%HYb~9m~3nf5}u3z&8SJ4Y(;fD#aD1PyV~Ej?O)73YKG^E)7yUl zSD~HlTeh9uTs#u$6cC!2a|+sHEc?;$YQ!Bnc|t%m?ok5>DhjFT7BkLFdpcz5LdC># zrnwcf53%D-5fH#-NG{K)+jY(X8-V&C8iE3LyS>fLRSALfg3(N<*YE8;cyM8EUg~P) z(&e?)l?X@hbqEL<^I$wU(%IL^$Y+jYH3{Yrj1Wwj5iJBGG*u+D*xfl+^dtmBU}YdP z1(0&I`QU^1c6$rJmUZ)bFb=A!K|@_ule*Klx|*L~=yVG2JrM(-ijs4|djufPObiT& zQ2}aSQ|27Y-XjODncVi&qhHOG422PZXuP%g@PiLM`(-aR43TFjHn}u2gBX7{JGO@h zU{(e|Gf7WlIPSRU)bkNHs6~CD5$YJrM>!N9$bvX~!}opn-~HiVuADxRG5We3ZTNdX zci(^ejov6EI5{GHPaCW8BuCcggzBCdXXU=ZerLl9w zE`XUTf-yTr1l7Etwe_{bM-OkTTqc4rsW(?H9yoN(e76|P7iAqnkf5d*(7@5sur%Sl z=D{drnNqK2t0WL%01Iep;2`?JBFs}0+5$~LU7%o4q4pNKb4#7vAP};E#C}?!229wN ztxuZYlsz>TkHtECgbJ!t5lak`&W!+9YyLFEy7s}>#1w+xy=RYEEg_sbd4jXR<~@8QPP_PdxPH z`!ZxO05S$Z$=rlqA6~U$vP3$N)^9aq1&p`d7=i=)O&g`o> z2e51ZuF6YQmUS&&LRMtpAk={f05R)ijvb&ZFE8xfzpvBH$HU>;<(0u;(||amy7s_m zio}@-24O>XSq2P>#*X@PbK_wtR|syQ)mC);!2z<2!6+r3I4_GXJqdl$c9SG8J>*GH4lu&O4$E~~N%zN$lQqGp-^ zOF&3u$OsT6R7yW=#UsQvx1d2043QM!YY#qL`f%+n*AtVNF|kI-5GJ;U4Hjjmj})iW zezmb|cF(GP_;lxOhj}-4SX5KlIdW`ZswS!tx@rb_o^7mb%`fz`EEn}ibo%7E1N)DH zvwpuDCN*d_p48nw2*SOe+r0AypYQZxS5FJYtV^z^-8m`dZ1*1R_rh`?T#@aXH!g6w z&)K~7=3KXf>@0^OM^~wpV@JLi4K~lO<$U&mSWTaV^R;015v?%%M^Wr%NWD>GY0bZ)fDC>3OByM*lY-biYv(0vp zgl#))Cq-c^m#?a|G>xm%ZM88IA!*-4i~ykGfuJ+j`Ihhc&cFTLKY+o2Tw%VJ%6{fw z{`_D5^cL;r0T^p;KF@P#CI_#9?zIWwyL~|C_%5`@LC+-C6;N zm>gyMi-moQpc3JDps~WEi1+oR9uLRmWK>m?dQt`NLmj+$4c6cYp{Y;+vC||VnwqMp zDj=SG=uxSvW4GVR8O5@q)|^GDYEXRND==42N6pi@x(cqxW+$^IjFR^(fo>%;XyKGzqk*r5+T@8)a)oq@ur#&K|4 zTN=AdDv+8Bii$?2*c8k$H3tZ0Cdg*q2ZJrmprjy`dK|GCyLmQH73bIt#VD29jxxYf z``H+;Fo^3Xk(;6-U*x?@xR|OYiQccI!8#j zCo?b!+n!=-HDIGTLBhsj3LAj7ED0MsVn&IX@%2v)gQt~Q>412M1E$G%qJS!D2F~Tq z0cX@v6oGE9d+5OaJ&ViTPOq*eE2}G8s~bT)0Z5P_o{^LwHe~j-_r5kC@*?BR5r9Yt zwXaMw$~r}7JQ-_HLnI<_7~dU{5LFF`BDh=;NL4a+At(~&S%FkXAc}~`u^Ub%wGUuW z*0l>V9*rQYJ6TRddDhWT0kUI9oRSYECiVz&#u}6nJ9&2fjki3!wONgZP7y@GK{*^{ z{chy{c7a?mliKqeVj2eLsGiR>5JU4Gk$ykexIz@c#>q#{pPs-7x zs>b8Vq^>Go)uL*mrU+_;1OP~Apr;-?KH3`I_WWmYzsF3f8ui1*xz=DBn~wF(u;J_g zUh$b$6_`!|P8SMJw_Y((QyyVNn0LAgrV1hnH;I6qPS-##T)K4N$f32B^N64dk3aF% z+n@VFKvYk@n)Lde$>x@!Qbt|^K*$jpkU#-Z#6-XvAS6VH1Xzj)5-OOX0Uvw;{OIZ_O03k6^AUk;Db>Hx+JHK+*XP8Mv3vcI+KmP8Y z{n=mto&T}Eu@&l26b=DV?A{Y!{Ez>S|Bx9XXWW6@&A;(`zdz)iAR@66edC6Ulo{Pl zkP-pnQyC&kOb$Z;L?c5-3`D)GyVP5NU5zqNU?z3!C_5T#Y>hTH$Kzo=se^bEMYEN2 zr@yqZe%lM4x3G5)F$Ob5KtoN2kO4N_f5!a33O&zm$E#BP)2eSt`a-JuosJ?ZiY@@8 zEO<()bK!C(T3=Z?c;uQQ?}i{;(B|sK;}1R7UtIQ+F(E8;`eDlj5d+DBqg--T1RzvE z%@kALA|e8d-E?Ds696Cu1C$7eodKXJn-4&h!Wy90V1ldb7q>2ry!T+5`XXYZNtzj` znKsbQ81jw$6E*cgg;?)xs^7HAYU4;y5i}q}bj*aHu(7&9U?PgFx$CM4WsGRSG}ZM5 zqzo-+x7XR+QdR?ijms;DDR0?QNw@?J3qD-Fcv;a1NKD`Goo~MRy6en2CZ5Z(BJadP zvIrn5?NlXmGQBP~ru0?K>GW#b^86a`)YA~d)h@CfG&%D#U4AD$ZDRrrXGQ?R2ABmw zLS+5ZxOUR*uP|(5pnzc7A*Kndw>nY#dz;h0@gz;3bgIg28-dh;)3HM$Lk((6{dofw z)GW^#wA1Z^$?214g7-ueyS_)LhDMAa06HWI%nXi#goUMr+5{xzMV2{dWNI=QPW*-` zdiBB(n%5TXdOdVR2z@zMo~ef)BM!>UuOP*EY*j$IqJS zu08v@MJHekt*8%y3Yv^2SUZWuilf0nK#m9q*)T5*tk>)8J9Oy6xwC_{RU)UNrlB3& zDV!I;8YTQH4hRIB;;?owde|Pan%U6`mxckg^fG02NlrKFFhW{A5Zf_=fe||v`-Yd? zdEu!GD<_{|Lhpr?K6Tf}{_bx+zA=~p7$~S|mbu^h#sAmVV5{i#vWzGzUjO#*>h4;q zy#zFfC8|IjkQpIJd^~DBQt1^NwE-HN8(ODBWHXkM!$`r<^Ww~CJkIy)S&)yGPW2r}VU5Q5!hO&k-f*uV_QjIx_{h5_C)_{s{uC>cyz5~RtZxJ^J zoi98EK0^(bWtk76s;Gu>)uarg=t`qlcA!z{LBRn4Dg>2STmjHxIj0TBaInzV}_1q z?8|Mpnex>rlq1K$q`{*$$4N+OfQguAg~pV05gI&DDw1l@bd|I#wbG~u;I;?5in-jp z&~#ZlF7l2eCSu1xCIr~njg(Pd3#dwDuQ>=PM5(J2rC z*%iHRmSuUyVwPvF=(uvJaz*FT$|}~uPf9f-Fk*JOgIHG*2|!d$LqG;U^eby?Qk#NM z6pjoCK%ARlspch!*{H7aPS+p+2?%5kiHi9pEBbSD3-eViA|dz?BsQM}@4ePTc08C= zoua?E=it`HmKuon-uqMxF^!bXj3>6c+V41vq@F5bQ?i*dEtmlXZKIM|4PZL+&ED9h zBjRqXH58CY!6^2!A+MCb@g3j)SHJz+xEeJ6)SBtE;bm{^r zQGr1G$~U}u-?8gQlc7XSF*$`J!D%vI6Uik;kI?1;H?-4Q=2y|U4FJU;@;3uO1t7>5 zI(rs-d#^bpm8`8?I(_2AcrZBk)KleXc>NvEa(N*l(M4cwtzc}dk}Gb7vwR>L3bSV0 z({ueRxyE#@AQ(fp*Nb1pdozgM^0{6wXRdvD;nJC7*Im1M@scSJlR&*WSaHjKIZ$@spi>|@HINJ)e!gLKQ@B6!OFC50YV~nVkI;WkKnzTy9gGYJolYL@ZUC$%K3X7#&=guhL=@GPl}oAuz>1j9 z6^o1Wby)%e0|0?@nB}e-mB;`hZSl)QlhX#EUuS}^^ptErqSfwplGXOJww-w;>))|A z-6;vw#`rJ*q}T}n3`|16E1xj21Dqwr2%n8^J&1h|r~!FmdyqBEVwUO+uK3z)iTY$p z7;$-)2QYE0U=R!TvRhhO91O=^>e`1u&|mKN7W-(JgF^@G(9noT)R@r#7zqK3er9S} zmNW679M=-eQBf3m?&jwEiwmyb>q*9w;W#rS17bvE=eUz+F3W<6N{F@C0n`u&8(SC7 ztxE7jXa-^;X0;EYRtemn>uWF{LM=5yKro89W71AR0Rv}6o&gbxYEpJE1>^xSGnQcE zt>Kv`j>oEBp)Sn~QscrTb`=p#W9^kz5^vW8;;3#*w%7&&O#>ePo)X+tv@}9sIq(|S>X`j zC9iw+jd$EpmLownt1+g%8IZM4mEa82_+K#McxUymM2D@Um{rdbWnvoe_&$*jSTJ>D zklVgP`}Z8&KUyE0eB$`laP`5@eeSwv+`4P`J{3rviP973%ort2eFpbp>1lCh+^(`p zw|%y)yr~V-oQTlv&&6-vmrWLq_ButklULQ`^0|vQTz})@uH}{0%cvY7yP>KM?(eOf zQ)FPk{=zt5i8hfQ5P)%P1pza+;!vQQ0yM6lJp3SDg%i~t#B8<^mSP|R07R5CGP?+U zOmV?>LYwTs|IKH|AuY$W6clQdyB!?zDwmnHDzS~W;_$&8QMtO1LqAmRZ*g2ijK z!Jt;}o8jsT7X7c<6vJqoH&fUyre>c2Gf*jP9(?+$?GwQa3o-yiclhwWyy%Jobx=gg z!EiG6wfb&em>RL0>*i{z0su-7QDlh8nPSPQXclW&bMDwVRm<{DD9h2Psw9IK;k?v92vl_-Ahu*?gP8dJb6CUtXiW+GtkN)QiRg?Z@?fCU?ad>CNDvEx0t6ImRW<59 z0NOw$zuI(28x6QY#W!^h79*#hc%9*Pp-7>e^*!A#AK|BMrDYmqmP@6N@GsGF=2r-EkYKTNljVu@#Sa-R9`}3c-wXu2j z%u}Zye`4eE%F!EdV91S{alj<=;vEu++tVm+PpA8D-#E1Z+N_;f4nR0RHy>|bPA1k| zfVr4oSlrm$EQf<}SzdeN%_}SGYUCWv&o6!3_x`|F@4NTZsmEPTM6j@sqX!8S12Ar< zvf(+{Eci4?jqzczf%-cH0jT)kn7yHaiN#Jp*iKedS|Ao>GE`GU z!ERXVf)yv{Da2tZ0M-ybvj)SYGz(bZ@Rj+ zr65dP)t<-@ky97~Qe{5_j)@(Za)2;mbSM^oh0M9`+*}oeEO1d6La0Jr`GrogJhwC) zP6%^U$T$d#51zopRD&3z%Q7-Izp&sWo1a@)+O=HOWjPvw8kiQYP;%o6ToDvd6$Q-@ zxbdFGQh6M!uOzi!Ej2!}*hERq5X_4?%3U|7EElbT888~Qt%pnzP@yTiG8gyVVpaoYU?VkB2__A?0*xGJ1s8J*`>xr4@YvCV2afFCbKuR8>4ai z5j($JO`@b*T|qwEq`(dWY~?Wk#1;?DdXIJP+C@BjgLHVxhDl0LH7O-XY&4zFp+JDC z&Q8l)5|*Kb%{8V{3wfSCS>v5XM0fhBv&`A%XfPRtX;#X7n7)A zgpDUoDHyRmgk*?}%vsJEvI8%s210c$bsb7_USw%*zVhn84Mt-}WYL$6rl6+ay^pEL z6A6r#7f#d}QkJoo07ixs(iwoD6thx^zzhkahmfM7Yc^$;W=6nen8-@g{SiBoNbY z8zfWGCYmgwc3nXX-Pu&&!Ia(r5}Tj(NbXn}$uHBAxj~ck2vh%%qJeoJoSW<1aKmlm z;c#$Pl!y zs%SKVfgvt0?Ir;rx_tTk^|#-4C)^Fhu68==P{n^!lCN zVt@I-{{06J^p_WkPN57+s%pbf+I&ARa#JyadQw`H7S!C_67dpJkrkP9mG>r6PDTng z*PR1IG9cpMy|2ba&SolR(OMKWN1Sn%l3W2|VVBxh-08$xF9cwWdFCE`=-#5p%E~jL zuj|QpNC+X;DT2Ep0gOy3k=9WghC9eNp?rTgdrf3f;s0vwbSWzmKMY1^I4vCvQCk8 z%X)$t5Evu6JP%#~qIHTfQ4Ih=wQ1^+j9-B0K8={dWMj1*SFN3uX3C)j0Z((ku!V(b zg8wEhCQhSTyuSeuC1WF|?l*i)MIpTEO>a8;)X8f7Qr^i%n?rVth%bBHYp%WNCd$ds zfe8{owBlP_&x|05@6xCdk+hPM(>`lUP$^1a*0B4jIGj~H8mH?lJ8l~aAR;Pg>^{1% zxHvbzI2>-ST)NclcNdm-scEx>ZK{j4(rU*_-0??yUSs(}^jW~nV!_spm9(X9ugfkE zVIoyk`%sXJt*sUo=84fjh8tVM_07Gz_tX+lT^RamtQ+eCM}T0CY?N4z*_jYVWJx*6%UWd{ZT%ANAYYdiL-Avy-qUT@(|Km3n}Lk|v_q3Cq-oQw$( z#5C$sK|+lIVtEcQB;W7$dP|F2D{D+t*OiJiLx}BQME|18T$Z^>RjcZ7FsOZ)Uz|r2 zQ!}&R_438b*WGYb>*!Y1U%J3p9wxU(wN6`!fjfV1E2ss~?rhpS(% zRlTFj7@Llmh+sN%&nvIcq){RepwwZoxd{;}#^j}vAixe{EHkwRo5{hPQ90wS(a>V4 z)wp_6tj7$17+o;wWIaM8BvC<#uq^^L9~97ti50n}Q$Qw?)E-u61TZ3k%bl7MlQ$*A zh!F5~=ytoKN$o4inVA6r#f+Jh9ix$vk#R7N&G?i=LBW`*)5~dq{a$Z08b%6I)0}Xm z#-Jj>05gtVN)U-+5R8yXDJaAo!dQYGQZO^tC`M#pVgT&-7ZkYPod@NumG!eL=gyuy zt>x&3n{PdM_z1cT08}BiGmL#th&a7=(vMNqI0f|#6e&h+%|tC0%b98-EqWm`rADmc zjBbrnN=i^*jW3|nkV6#wjHF;hY+$G$SX0q^^ACOhpZ&&f_^M(iQ+WQJci#S-=LhgW z2qu<#!M6<1+SM~l|5LqY7I85{tTP5~IwLK}saycq_QJDYqbz8OgeedK5{RbM;Qqq= z+~OjFnh9;U;jMv%He?O}(?{9y4%1iJ_L4gp#x^uALZ{R1^tz+1Nl^7wso5L>2&&7n zqTj8?le(%dT{v^&&ClGod-r%SL6GraFq~|f13-1o=Jqh47y_^wC{V=7Xbf)~DMWB_ zDvTO$E3?)WH1uMi*puszbuy=76x4$G<%7F%ZB$x7CNFgWieM`MAW}1k<*W=WrfMoc zQ53rm9o@Km*?_(GzV^&*8;VF{hG0m*&J{)1w#I~RJQ+>Kqosu0wG6)TLHR)aOG@lthdu2SX9p{;!+rICxCa;hm&E{>(r@8Ue zV8@vA1dY|JwnMlyazLSpb2WTj8QuEjbpv2CHokQFY@X#szn>Rf$Lxrah?4NO7?zim zoRroY8jw<2ZeR_j77@%(YFFf41T?^)g2)`};jjf2hzV5Qv!g8fwx^mtAOb3gHC37b z6vSoDG1oo-atPulA+VBxuRRwI)EJ=C$%$N~epREG?WvYJMGI8m0Wr(jfY}vu3yWr! z7x}m>4JVUQd>u5X=9!l|q8QCNNvy?~T&L)09b%yxFG|P)(P170!5Bo9O3Ph7*XfH= zUCH|DR&Rd!-Y>l0Pe%2)>~@PUon2YpcjV=-eMQmj)ZPP5tG zSLPNyaWG_qm^8Tk#SNhK1wj*FY{qEnREsG@VBqQl2m2YDmtY2UH54%>$dD8iDE4EH zV_^Uo>%T#SR>#W{a-QwkcldF*U(G~yJQ~d{^jrNov7}g+#bIx*qZfo6*5zbtZFTqV zy;(OO4JJi~;PK*x3w5ZYNyx+o5W6Rrld-Q#YRa5Niw6Oi&^ZKi_k7_ClfkekSVBOc znso2}g9ncslF2}f&@}QGfLJ`(Vqcpk7p&E{5}{594Yu>^89HdaL$lof=?sRQ9Davn zm?5O8P)LS@HS0NUZPQnh&O!)8sKF3GwecEkzhJ`|tXVq-2okK*?|Bdg3Z@s&oL{+o zIWLO5({Y>?oub>D>&|tHZl@?ZSymLz5fcC*If@FTL3A>i5r86D2pTgSi*D|i84Lgw z;*v8YV()_wz5+6-7dcNy6aZXoj&o^2R2qO_^PVwai}$vlWxC% z`OL{Pj~(7~^l&!cGc$H|9tj44f^i7_LBCgZX> zTU*Ovb`@iLvFQqK7nJRMm+6VKYtNun!W$2svE!xPd(NFYDJtXfK=4O1F~+Wq$304gq&c4OIj?%%Wb_~t1y%yS-W4C=Zp@+>xTXM~uPHY$h1(I#ci z>e?DdC;<{N1D(Ho>G7{V<_JVZeBhjKz4=*h{=V<4$0I;6l}HI1(HMvZ7+awzs7+rn zK4eP^$p^Vj#h8)*trjxN@vp}HXGyx9gemq1rW|{lP-$F|Q{mHkKjXX@O%)CUKx#Uo zCpBREL(Kp@z|cUDvs<6{{3jlL%m!QFFw_DfQdg5ugTj`nY0M8GCPYHVOc@iA%Zn__ zUGDO%$XtewqF-Dr5Yk|{6?{F|+;Z5;8ZZD8H6t01C+AL|TiUlz5XQrycrnpVhq63J z048cPLNOwoBI8htnTbTv6OP{32B;EDMI<(pA_63eW+EU_tO6t<+O41(R79iR9CMD* zfWU$U38p4!%Akg&atXy_mnLUNt5`50Q^x^ffz<0c)v$N(-o@okU8$mhMGM0afgGVR zJ3`Io@*>Z8*WTrazckURHkEh>BsUokGnaqv<9E$3?|$BEU$L}%A4rIEWCpQdiwe~e zkQe|=l!*W!%U!2aj5Y_UjJZaKzNLi7L~V@{I#n7V{by*&$4>^vL>jA8Py*<*Kp<)k zkII{g5s{b?BZ72$S+}=GH2_hJvP>bZpa9(5eMgL}RgZ9%BiZz^vEla9vs$D@d+$Rs?(Y z?Td_hG#H4P6AeJ1w!FOLoEc(Jxpel-q30e6-YY}tOZDn91i-mD?Dm3@HAYf9vW?#& zS~@r#vG&mj8rFu%@rMSceqk5P<#w?$0}NHD%8*6bVvQHFm1Qu)LmEyJ3vDg#TJH9G z)o=)AgUxk?Yf@{5ZQM}^X?}hlh!p^o&R@8A+o-zfhFhOFd0K)v=CZ7xc=GsjpZi=t z93hbbpo%I?Ce>&#>J-JK_K|`Oz#>QlMbZ8z3UvzQYG!`0`hN@veXHRmqN3M1yMM zQ6fYp(2$CZ1Q0BvT{22Hh>MeAHXSHgk>?5!${=E7lxW{#S_T4woOt5+M?drrXP$W6 zN^pcO%Zgskc@6+*#srSgAvz>RWR1Cu#t3XcV5kaesv1=gMj|6dhd^XVh9F6@o0xe8 z0n^w@L^LR>F>}8`0pSBgfCon9ZhGG&BrsV8jp1;`Ds8l{ zR_}slK{d+U%xc~t9H!#Hn(Lt<UF!lPA8hAzAT?S zb$s8!1G^R$MTN+S_-kKz%!e{#MkHoOkcntr*MqHLQDj63AxP1rRWY-2bBsU;7J|R& z8Ml4&>tClPNW!QXQ#BFW*C$QTG>rnlz(A8oh&qC4)aoK3Cy0=>gBgbzl6GY6%0g?$ z8XC7*tG%=|(EN^8QGzdnfu*NO=qIyg(3%?q#II3HO9*N;28@lS4Pt|XsXfz>a(q5a z%NY>}2%*-RdV2edo_qMFX9$?7NicLo#Hr3wTRS;|API@kWzIQv8FLI2ICh*lqRepy zOacz5)5$W9x;SH8lV~753^#`l-1DXJc=HQ)fBM|1$Fic=E%I(r^m^T1uRFKU?{qtP zr|5KxPOs>8JH5GXw^wv}oub$2_B)+kH}7^j-MrH+if+;G_4@O3bIS|!yB3yqFE1=D z%+1fw&G);#UccY#cDnsu-;v9*j&m6jxSTm>VgyEXsGuQu4WeGcq(+6D-Dof@iW~q{ z2-KNmKA;4uD=cd(OC3z=%7?ANkh5qQ5iuJ95&AMN!LY zqGpJk6&brs4a%zalX`P){nPJ%|Chgb&#;^@IwX?V>WUcv(a@K5PB|FYRXF|l$+dHr zaw2vP5s8{Kj%YBo>OsT)k`opIfq+N>h)9B}7ceAb0(7xVGdMydYN)zpw~5FtY3NaZ zh%MOTJpqz+(EuV+JfVpy%rL}O6KX+0?E-24wfqTM{oAg%M0*6_ba~Bk-l^t04Sr*K z-Wd*$t-UfEc#QT@8wZntnW!%B-QAfh0IZr!ycZKx1vBv? zH{W`jm=eHnt9<0%uLS2raqaS205C%p+jjsRDFR?D_tQW#+FM;U7>TpqtX3}oLj{At zd3E?8S%fe!udiK#NZLpdJ=SWbGvtNI6&=-7Ln`>-v17;pij(nVQjIKG|6r!n+7GJi zTyL&xDk|nfIDPs_M|k}W*VZ6jw3oZ##^}^jXMqUNRLs|U`qbI`@4Lrk?DEV28kUJ_ z;(ci<3(E@tNI(YAo$oj>P?GfOhN(b&Wb+s-Y~$GtSB<)KVvuQmlZKtd9RkLLB!ZZr z1hIqyB0$@Gkg!QMNb(#?t5E2Mwe)~`eYz!U)@lkp)4$+KVjVwZOS5gZ!m-hI3F?B1Q{1px-py7slNt5AFKwGVahwGSc0 zBC)EfYGPm^h@w_iSyz>>y`j1UappuLV0h-liE=P5D62=+XFvAQ>yDp##kYRDVA&~H z4IHy*DA=h9#>&n~Pc>&!)+^Z8-b8C39J9-FKr|vl17=C>(}k0K))<&rTVJih4csI%;* z#*+YpA`yt3dh)4zKlfRwCa?SMw|3_iMMVHW`vx@p)HA(ip9*a|Y{(LnGQ zPF?8E&o3;^Q^BDYax7kuP(iQ>7(>#*DMHK|u5CEu+>b(LTYwQ;fGTch;j@gj@vI~+ zYcqDUwS0A|ufo*BKJ|X2a}uL!z5Y`H(p(`@}Aw3&0(l3(OQhmOabZ;_U_-`$qNi-3YSiuGEWQFUR#cbS)MZ) zm_M?Iok?2x$!wZF9nP-vnStK1Hz~l)$dL25U)TNM{go*Z+r`soZhq!-RYf8TPyKk( zP&6JnGy}#)voulWBiG&V@I7Df<1%;|Zfy4V_ZzSZ8ff|-6qyekI1wMF2oH1)*rHfT5+%L_pdMTlAeb zZkdJvTd$9`U)#NA+omCXl5v2Tmd$pnGwEFbFtdWOL3dj_-)can02KW%h!&wQD%7sR z>CKyFp7F9#C5&x-9PHY^Yv0jpE}wXkR79lo<&ncj_vr4ruE(QlR9524PzRAkA@KARBCqW?BgH&i$8whov%D}>)}ik z5F9uFW6S^)i3mXf91&s!Rz{PA9FbT6NTo~@e25Uth*`lhauOuV91*JtcMA-l69FTs z4T-WC!wzPmXfPR%eT8a>9&>Q4!UzOpUd@z%C;*W$2$B&{HLk0woa=PVjF17OaS|dp za~b``AN|Y71g+OaHsy_cOU_QlB~g1f4(E>2-;syH~Eewm|X?qnI6|-jHwK3Ogd;7No=khi#ybZ z_c@4=H=@Y5BF zXD}c}BZMGgnv5!uy}S4H=X=#)T)1qwG5+dfkKTOKGY5lBYy@O5Eehv2uPY68u%s>n z0!Dr%;&WFplc=dCfO~vrj>(_cR`N;|vEU_5Npy|}<$`zIsTJF;?$XdP5F$Ie;kMh?&z|+;U}U4M zk?a>&6pr(L(eInZwps*csv@ExcrOw{G5|n*2*C$KbwoZ05JLzq=BH>(=yA z)P#vuG!-5oWf$AR*ALzQz*A41dFFHP=yd1mYT|<;Iv^ucsr1shwc6JRJRFyO(A>r#@(bXdw~{5*RTc&Uf9P{_Y<>^_9mA5J*N_Ygwo8 zwf@Kd{Qt}{-Wrd-^*i2p-{c~V8nC5_#8goOXC@i|Kuy(*7-Qv} zp35$reCm^b|6xBIm4Ki9$j2Ug;Gu7Q`*&xZh2T;NCbCqBaU0&nrp|Di0!^EkRl^r& zfRMA)-+-(W1E;pe)NF`#W?8iCX1cZIVyLr`U`Q5lVtYxevV=>vmLKc3mr2U|lu0(+ zbM{@@JI@Fw+s1csdUpKY@ZmU8ZPdBRcsDTSy$6rPiw-td_wK!hDTe8=3X`RShp)MD z>*Vp{Mdm1H3%(k8R3v70aOfx#OaQ0&sp%VGyTV(+)hNMJAq++{+9`n%U>1%Y=wt+C z00Y}vTV-am*k}u&9nd5QtQEm%h7_CPnStj0-l3y6TsU=#Eg!6{sRReC$#ZCcK*(wa zAX%q7zqq)zx{i)fVdK*J$;P;_$I+o_y#LLT2Q@|J%Rc^P`8fQpXu(?0q1{ATk+mNQHy-VZw_5s)}d` zDh{bEM<?>;UD~VB@3X4tl}57A6x{W$}O zf_ExB68n$YylIzM%#TZIlL7&R==|~;Ab0@Tf8^Q&yRYLcYsgkbAa7;V)I*q5qh>82 z#9mtlit2K@{?=Q*de4_uM$`R>`5*)-B&c9{p8fs% z{`$;U9%WGj5HG;cDY`%Z^Y830bT&4&IvL+``;DEvbL|Z`5$4%aXEfOO>_EeZK zf>rQm9zP-P|GSsH;q?o13tHp3)93&4_x}j0iin~g=YhLF|NK|n3FIPHA0zAr5oQ35 zV5#0eQlrZdqME3gw?`j(=#zi<;c_r!MhmJntXx?6%isFFH~q*Dcjo3OcPf^!q0p*s zjVdz(R7*5~?ZnJzNYD~UtHY;BOrXGR7V%EM#jJV+&?ud)2?3~>3Jt~Q)QFOVCMN1OjT8Z1u~GCjy>(`N4thFa*?Qv#^E(2K77Ls4}AX9F+YEO<j2J-WWOQrD%ZiiDWI61*tD z^6sTxuYc*xFh)8=Ma&RQ6->jC!-r2k_Lzt=^KgCr+?mq{cVEL9sRlOtT*4e;kIY3UN}o=qPl*0b#7@f%le>=!hk7SO%(Oaq;*DD6U8QsM97Red+!OE zqL3ET$#`(z=kC=yIL2~3p3j&5>#zR$i(mS3sI{(@nd zIWcqP>pE1up35EfT$W2#Zi)tA&TG|J&x~SCT2o{sCL|^*%utLyohMSHa-hbexn{WBY z|KtZ>`yFrEbKp?nvQXp6haSJ{&;O0(EHv)J|H;)LUzc^fS-K-2YTK4tm6=f z93g_FqTa0z*f78t+KPY*%)0C@ojCQmk9@QoY#@LJBXmS8YSn1+!TOmG6Ns9f zfu_R0Ei-8?$b_JbzKLXNq}4sumy>$fQg&GY=TP9thKZb5|35(%`B~q1=Qq6On~V9~Oe9{xV6JNmONPy&+;$(FK1`C! z?UT?pV+EkWt;C^Yz+Cnoa2YBZnu1hih;?wIb3Ea=8+Qbx7^9_WOq>jvLQ-s(J;4bVPSqgjlJsT#`;$teBjBGPh1?F+Z=BUtI>Eeo{Xxh zQs(Ziz58GIvKK%9MbAHW!!;sCW(cvTCW1ncpi;XmTiUfds4+39-S>t2iXwOHoFmTI z47;7V7rpRhFMaVhLh#9i#i&Y}nMV8!f+A%u%R5Eh?d6?Lrznb|TXZ@_r`PHBxfkxYoA0=N zVfTJC&YY7 zodhwDKlr2nWY^(c-}gOl>i6flI3cNu~!PD1jIm8X+u<)KwZ|cY@vuUks@|GtN=~`h%;w*JoC2Y#f86m-=A$>xa@;J z@yJ8(`)}v+<=vx|i-3e+q^v}-fxwAJzV^_ApS|gh7iIZzC2D1U}J}1V~Zx;9j569jXrt@7=Sx zu_Yd=@oKNTOF<##$|@3rGewur6$|^XIdtZ+jVR0(`_x~E{*>uZHP?jp)!L`Cc2;)0 z$u@2TVA7q_g`Qiffrx^H@nDoO&oGZzY-Y#Zk~D~n3<=DvGuJ(E&9UQa4>)xjYpdhY zxZCM9dIFH4f?`^%aP-Eb0d1%=HEmn-!>E&$CG7>!UemsbR002YxrXkeGurQ$Sn9knkDA~q&%Ah6^p-O;+?ht35(hZOc4;6S`T4jmrXRz2nnMlkmOK| z4mBxI2!tuA2^pCPG#QA1h6-86;Hc>4%X^k~EiX7G#||2Gyvc1&2HG^xmZma&#mFEG zO$ERdt-pKjhTCs`;IkK4Pz^`Jt-)|}X^NV-TO` znF}bD$y3LlxP10}p0Pm)s?WOZnXh{NH(ok_M$G=v_x|I>eajzv|A)*WTByqE@kbuo z8ckmD>Tk?*R*X{#BtU@D6ithfNi$7uwdh?{HAldt#6`}Z{lwj$z3Wq|K4T}|l*tiF zuyap7^`%dL?pZH>zLzb`i!M@7b$LOUvEg-x53X#iUvp&X(uOZbl4V3--WvfcM;|{a zusK2rTZ55kaG>m{-<$jLeP8;}pZ>W{DiKAfKurwZ@%A4$cFPTZIF1fmY9jMZ?hz43 zWQgU2*Is|!+kfN--}49WIse3yCcJ)rGn`#zWMCuIz59+1HaE(8*a1)b ziRx?f1~ck^tBp4dGco4`el=7s=-|<7&OUL%OgGlg?K-fZf~pBYB6`P6tU)cyxRN^O zTm|;-=DZUS1#lL6)Hok-=4Q>Ob@jAjU~2amG#Y|*7Pa3qSOZnlpqm>Td-m8Lkv zWvz5>q+JZ{A_9O|pn`9F<};sqEbrcxbvbrBX*)C^DOG|L%X6uLq(aE5szv~d3yYmjM?zr2(bm@1 z#ztrN0iec31BPtfxvqy0p$dq`jxcFX0T8ac>6U%_j{%b-beUsE7QkhU8o{7uVi8V( z5p~n_(QTq-QBP`UET+##I!_HOQzRfNMiJE5tRw_PAftq6p@dqtHonmC+E}uY5I{x1 zA#ifiYYd4bsD?q)EG-eitZopAJJwKeNZyAm%Wk~m8K)lm>gL*IMv{rFp1)M|`<<-I z5RkcT6Wz*_7Q=*yu{TFF7qTqN^A43hY^|)`|CtAz0=ulPtGVv{PyOqEzIy3GWym>6 zJ^Z$Bd-ZGI^ahcDq(nH}nmqOR*FN&Wf2dU{W6T`_BN3zowixG5)_K%VqwFCh6Ad9u z%JQN6zjXiIcY{e@I0Ri@UT{c0ctqzF&YXPe^b@DBm-KH`}6%y*DWsf2Gy`r zRv2vrMSf~>6oS3-)xqkoNpZLiiT|RsW0LW4FEioa2`wzeT zYp;F7ni*b~ssM&e?I)G?8KmH2FhfVNOQ`K3qI~=F@-scVRp-6Q;}z zUhtxqzw8w+yyn<}U;dR}CLlj4Da(9m8}#KG7|;ORcwUCTK8n$2rXU)7qg z2Ao$1_aMbu0tl-YFQw|DSH4Lr=vu6cfdQy0A{pX=YmUw>&Z}5ZxP0M~Xo$K%Lghzi zwwkF(2+w-{^CXxlsY18gdEu*G_R80M)AiRM?e#kVATd=pWn&>2GGtOim=onhIk}8o;aowkV9tqi9 zOT;NkI%DbrHqNwIh!S;a@2;Dk^K2kQVgo2A<+-O$1Ya@ch_QGlBNAHU`M(|NGzcnRtMAPcR*>j)z&|TGd?3mPxbM9aN+h6+L zfAWK56oVC2IsWRG9@xA%0OBm?ypxkLbA~w^W8NuNM}rPppKA((S_UR+>cx8qstJT; z3}{A^Nwqk?Se29a{KoJ2t&xEn*JVy-rZ?Vr(+|A!9aT930{|hj1SoDIMFcTf0ph~X z7&8J@*t=`j8@}T;-c*9;!Vyqi`*-}%yO#EJU-O1nUU$pQW$AOu&_X>P{{0{Q#c+MY zJRlk|10nzgF#u&IFa+QXX!X+S-~X?_os71;cr-I|&${h-KmGGRJKVagl|OKJ@6Y|x zzv*=P!E2u9GOo+@@!$XcpRb)dFO?9gwQbp>Ct{mbnU-g>8x5kLJtE|`aT|zb$J>OO zR57SIp;2lr!G)T_%2DHpAR26nfFUUYDfWu&kuQJwfBf37f9}Kouy*?5@dqFItKa>T z5B$$RmEa))M!*bXp$m&O(_2m1w&_I88*Jm?S91R=d{)ghT0{tJ`?>Q<2wt7C}t8nHkfLxv;Z1R z1=JuYn2O7pKJ_;r9}l*QPHsK~l~>&Pikoh|MQV@4#7JPAIRNy7t=GNkmEZWPSJhR` z5S&9_mZy$?^~3M~Ks6Z?$8tDiW=-M!=2g(5%(M^`pbXWSbEoh6yMGA7N#-bLM$kK+ z`<&~qz2SM!yW`NI!{uP;n9+1nZr%5Vy9S%%thXSDS&pI11ZF`=ie7ekYx8}7{NCJU#>}dQ_^f9>>zlsy&W(+8q~V=E`p=e@7o{qh zvU*$%E?@kIKYPz;xB(P(Vp0Gm1V9x*#2{hy(xngm`QPYhWI+g+yV>YlZ|-Y&9`S+Zeq0$ zD;F>Mx|XQ+10+w7nyR5AB)IO@V`7ScwXe>eJs~0?C;*`%8j@O*ub_s81Z6b=Fa?;O z>n93~Z)ZjbyQr6{|PCvE6fZnW|l%j(Xp%@fPw1NW{+&t zC{ifJ7fi9;rrSZoHbE;6XY>g)p9m~PBmyEL1fn+k7q}^Pld3d0 zaBR$gpvY#-sH*WTt!@1|Lj#ty9ZO^%{dPv_@f6HrNkQn&_n!OWmvFb^gA$;M4F_8% zzV^u4#j`6H&TXu%Zfve@Zmkan>s#Zs!FYW*-WZM7N286wcx`LAI^0?xjW)}2ytTGY z7f)T#AVgAz^4P%}-tlAqtR9aIfXUE|n81`72&}HhZ+_cbU-6n(p;?yafGAb9aq0YL zKK$|F`i5!%j+RTHf>1KlihP(d7*2$A01` z=I0mvq$bA-z8sDo_{`nIjd3b;gluLRxu6mxsN=c0-hn-H^Bu~=fP5uosdX?7ZD1Y& z=6B6~_%HtQ@dqDKLCXon8)#n4{hNRPOH~!jD}s?K+mtaT>kKINFa?c8+!e?nWozTh z@BYbm57$S=mXis=?p+6d{y+S?(b}39F{}6OUHX9^dPmXe0hn`6%W`n(^56d9d$iV= z*g%n5l@K#DEC<8C`lCM^udk>oGP*oJeBju-f9dC|YK)2<2acd{2%&oZ3%}v5Z~yK{ z7+Ic$s+PgmGDbnh4db+V(^-atlb zw08c2fv2dfBBl0JhGy#Piis4hsO| zU~3aVZ2D4(-8CmRoNwk1l>BT)4t5{hxBI{WHABPAwY91)C4yUkEUMI+iW>sz!mj0R z*BL4RK6>xNm)9Os04)+(lJm4CCB>@9RvU~MYYd- z{G&jwalc^#5r{`qi$$-P)ndxC#S}tJKqnov?~ zagyT2*cxF54W1EWVN#9lxxkv$0|uh1)_6VID2yS-@&eWr12BvQ^u*G$O|cBnI2f&A zMK&WGh++siK(0q`zTp`!y^}H*OWUYQIrb~(S1z5qbn(=M3#TuhKYjk(Q|Hbee)boB4#b-PFcKOW0S$LAd+BYnFbIQ)c_)3__6o@^~I-7In5jy5fhT7 zTCt5FfTv~fSKTqQX}h|=&DYiVzA!Dgwq!3MnnEnIj|j^L5B28zYBU-S%F%|I0!9=? z{3wXlbp-%mmUV2`UXHaaw>`wuKL6MKG%`CfGPAJnAUl>=N5fa8)PcZKo4ZB;H}a-+ zbEL1-6xNJ~XB~ITbM62%6)VeX<>Gl$RYA3s+JuNEs$v9Kc;u1e#E1ZSua_~J2?E3(C#D7%s1 z0iuN$9RR73B|@xU%oHPS#HkQlQ~U>vOu>K=31TS(ATd-z0}{g^7$zZ9-Yhy+3BiHI z4!TpnPg2fi^e~7LE$L`zY6v7j!5}a4J6`mHo1gbwp@>|f;6*g~QJIl5$O_5|&I>Mj zMR%^-oA31(yK@V@{(QISxL!YV4#=<`4L7{!AAaYL^ydmN0X9P82ttmg7a9W)k%4!B z?|A1sU-YcoKV zRF@#Ku{ht6SQtbT8qAQ@XmNS&|MTnr_3X(DmNBB3dNus9pZf8+g}znZ96B;)KvvT5 zoo{>F9nbp)7VFM+kQ{hFS>O2h-~AoA%nXp6BL|3o|7U->b>Up)J%Iu9;=;an|Kh*y zb~_MVhiQ2Op`s&1AMwozvyXl0%j&J^RoN&$4fF+L zaq6imnp~w8D`*j$MKc!|5JW!!*FY%0_lZyb@qhn~_x{#z{@HK;_Hc6}R3agWCOv%` zF(!-+#8dGsqkfj%{h^P%|9`yKkH!)VL>O5O5xXz_##jH?zx&zez2X}cICEKdzM~;% z6+Zjnk8G~5qh_%bhFOYZM=$gh9-hR~uF6!mDZTCAXjdE<-K*A)PkVvrPas4UMTVu_ z%gYD%A#tc>_0nau1frNRq(DM&jsR@2Ym3X2aM;@|jVqfq~IebB0wQ0c`>7tWqO$6zAiz`;YLqGlj5 zvSSFb1h7!%_U_vc$i(C)^`nnIjE-XkG$2s(==`K2d45GThv%0mey))kr4)l1PT(w=kxBxuX**eU-@lT%sVcMPT`pHEaQw-)z^MJ zuEwKkJSr#SvKm#@s47Rk9M_XkUDrA(eN_kNC-tC`@BhAk{G2;(2k}5eCKwACC9_h& zDE4L`BtXkT^+WIYC;w%2>#L7GT68mJ3T1u%)K5dsVo!Ao=y&hl``$l$@7ErDte3f92qK8|-9PyK z*WGv>)ZUyU6NHpqp$aC|JAd>?e)Zq~>Jv{K@8o$|TbR_3-*;cpqdULl4a^q2eCz`s zUU}*%2FNlN)46`{-M{!V3k!vc8OL0rqfBFu3J~FU?)%r2<0`K!z!%G7``fct8d~m~z{Vz!XvO(#6Xk{fob@$6H;1%;lrC z(O><+A3XcTFS_|f-;fb`QBxrWLuAIFil(v9M&Yu}&5ghNgAZIjd#*!Zltl@HF59!T z_!B?(uEoy0w{Z9$y)k3>;>SO38Msd7MAE|R3wO@YEU(W zph48keC@$7_*%?|T7#&miHMkiS{3TZqYMGW*ir0Io)rwSB4nIeY`MEy1Nuran}%c> zG@c?x2d}aOmuJs@(Tg1M>92j|;;B;vYGVC5MR^9-kQ}x42@e#rDDw9^^-sMo4@g^Cmwyw6&Pp;Lj}g-Xn--3ON5 z_C5dT&wuZa*il`BSg5M<_(M+~-GA-jW5)o*gf&=J5CR%2gCRlYsMGC?wVF&6sp=JW z-={vediJ8CFEWOpM%hbVa_4t`*LRJ!))9a}RTaUs!TUxJMq&wyDF9C{s2)DB=R+U6 z>u>+p2XbTsMN@LwE5GTr-}Fu26zY)?ut_X@fP@4J%pf%azw4)d`ak|(zr1WYvb_~aMvc=C-o;_rVJPBjF1_Vl=^&NM<0+}?nZZK7~ROS{8o8E7LP3(|U z9L#(m;xB*ho`>(bCu|L)cQ}X@S#G5~@R`pK2ZI;C{&gIJh=9w@v^I0d=qM*9g0I|t z&wZcyVi-;^28Rgj zU%bbU2b0lcYin)y?gPXKN?;@g;sZ35VGizcMV?$V+YJjqm`1b{NT z2lf_p?;@QYqXL-e%F3k!M~()8RGz-2-Z*9kHdQJi!QUGXprUflx7_iZhrVz(h>7T> zGv{_6ID`;$U6C+0EKcYWMO#=}xbD^)jz4xh(~uPzn69sHtgWs95|ImaC1`A@%qDu> zjW;?rkvgRq&y-961GUiW&+Xm2=knzhW*%>i9(eGcZ+yust1v1k-y9D@U1wQN2)lOe zG0?iIYpu3cR*Lz4C(lC(l+$=J%GimhXaGP%jrInpimHmJnuw^SddMPzph484yFOM* zw$!{NCZ$LaL~KqH4o0AS+z#ogUb zC*p1q8@mXa>Doro%}Rwvz9Xp`M_h)fSe^IsXTSK_N3T2bg-?F`{Ns?8Ik3`w3>OCMM>=`0mes?%NOS>CG>( z2xo;dmV>sN(c9IoB_@lUQ^xQr%Q<{$_=y5Z(q-|?;=nhZA;3BhyJ z9)K{0d}dJah7h4l7F0;)=H@>CrTc&D*ME0D!ysUWS?-?ktmnP?d%sibi6I*V1~X8G zWYZC-A|v3!Lhqmdi=X~4zxsc#t*pA-RdsMk@AV=D4XU=8ny$JlvfAcT* z99jkl+FtDxr!P!H53*Z#K?8WtCS6kzv%KW|2;ZeJzha@X&a)`O3Gv zq0{Y$vi4?-4jIYu+RDo3KKRkq)2AV{Kv80L^ZmuQy#1{=-+E(^5f~UT8nGC%ef#TQ zKdC17f9A8~vf#zQ4{-F6_y5gn-~64OJg>A))dex)(y?{YH%xA7AaCRI+gShXH=Owy zXWF3E)sym!N%e|H#+zc;y>Hj9eY?*dU-xF0&YxRa+MQ7zy}976EGMRl1QzVTe#b6A z@~dsr@!On?9o*j9z~9q<&;Sh-A#?SC-JoYxOdZq4$~q9DB+oy#LlPNxd(9@b5y1e- zL}U3!Gu?Gy@3EV1I{xrO9qw)owl+6bmY4UM3ZPl4G2H|yRRQ_Pk!uL>$;Y3BTC$At z!bu?Sy;_Y9SpkVMa)+-ua`?KVDy1@*CZ)5%??B|I0Cw>3k(Kqe=!yUQU7x(}n(K}n zzIIfOKKQ{8I6^bvqF?0sqz>eYhaPxj{o(}!ba~#%ovPH{N4{(T2&oMQ01%*JW8zsu zFs;yq2J_QI%(2TVlWzQ4cW+tq~;!2%<`;UJ?gqpg?A#sj{}2hyq~V z$?8gqUia8FH{SG|XR~7?HVF-1#x_h1u`bxu+(m0L{ZeC0LW9)3*USI|Iy-RWz^h*W zt$+1Lmxh-w16Wzrn`>M1i+fA}jM+8mmZ}kG$64mRFc8F~!8&PM&@LKmDOwpLvIg=A9gYH2C3g@Yzq_ zYo7Y^{VdPWu+!~!iY_YUh07dgu2|?UbUXZ|FWh(W{ADjSvXTih?LTnj$A9K0MJhE# z@RpzeapfQ+d>Bz2+!z5f1mcCc{-_@PmtXyF-Hd!t)tVjc*>mUz-}NJgq67rm3{65Y zC#YBqAc5@LzxSvA?Jw-!zaJ|pTy6?F@t03tuu2KZiyv3jKl{0#x#9NPA|PH>P$gX= z#j+r!bs(keLq>qWDsT9my;PT)A-JuJ`@T-~QGgUU>YZRO&^*LNGIQ*WY-{kG=b+Zn^!YI+Q9P&?M%gq8V~{ z%iG>^({rC&*TFfb8lVe$JGP%Q46zNYZCBwVkHOiS zHjg*6<0_x27Z`!KzTsHGvCD>owM&;HFgohjje&&IKO(R$H!EboQ zokh`$g?3Iqc``D80E}vMP_w2v7pNG>(PP)V;3Y5KwR@M;G8vWLiwXD|e5C+9x3KiA zJDz>?x}zE@wf|pxZyrC(an*-@&#CI3ncsFd-FvlfmMqz_Wh5ILufYa8#+c1!3;UM5 z;NW10SxgAvuq2Q`2>F;0NC+el){wAxiy3nr@Z(Ol9$c`K?s2t@11D7c3}P3#TR=ghIqEq z{)eCXw{QB_KmL8Pg3O1-u+ zT3xNzM)k^}!$&6@8>4DmjcQ}qc~5L#`0~$v$*aEL>Km^U5^-L=hN)ZH@~c2zm!fVB zKY8&eQzc^TQe18#_SCE$Jov(wzf#Qz!sK-K+}76CX+W$I6EvJCh4aD;vr%hJJ+k)T z#?dNf{Y`<8(O*cN<*Aw?X0y5qP3s!m>tFXBKm5iwK5*jx$=V8eXd`d`<==kst6zTU zu}e>#dF;>L`Ujh*&RS!X<2f*|`l>I#{>B^O9oUj@K*V5GPh?aD;@KF0CYAY`um9SA z_I+q1WFs+Q<@!x;z{Hc>xoy6m? z{eeRVzxBIcR~hxfDVYZ)Z@3ad_>TsGNJa?^QBOqBsc--3cmD|Q?xHdwx#?te?RDSz ztrfv1>x&hnHVhGKT2lyy1IVjhbYSCKUiYm(@z4I*nKNhE8gT?>h-<`GHUIr@{|C>w z>8aLKP(U4ow2W%tXb8j%hZ^T$Ay(D+<^|7u=Em#3{ipubPc%DQW>o2JBU66l{`=qd zUw-u^U-*R^hY!Oz6;-vOE_ONEilTFfoseCdvNfBmO_dEZ}utliv+hk~<*6K}1l%*(#; zbN|*0o@)$dvnfJcLOjDGPHByJYvgOb;;Vk@)MF>_zMJYwT`NxRyW?Yj_BOomb6?Rq zH}ei*dww*95EHuunW|Y_cQ$l(5*3;uiQ3M{DilTkwJ_u2u&WWlEvwAt@++^dM-!Pf z%}h={^3clq2AD$Hd*@uR*;M4(D_01cn(c4tHPHb&@4C|dSMA>qZZ8Je_Ojy@)Qe*p zo1M+=5Stc`8jo`f%~P24Lp5fmPHwYo<%qbWmtJwjlb&?f?H?MAMqB64oqp`$i;f=i z-iPWK0CCKsBVZ=){b*d@bn{bZv)QSWk8Pei=bWoYql1SJt*@`GZLGVtQ57&}gFoq{ zn5aiZLx7=gn=7xpV)N{|b7#*p$dGyDffJQ6Vs;i`(fk<0dSJkX>-pl5> zZHAHES=+S6ut-dd&M6*-5aPC#4XY}vflAoe6DGcC-iKfju?g`X9AZF1_@lKI05*mU z3~|_RZ>ow7RaFIs1>y@#irfqkxdHT~XzvA+h z_0`RtO*5%l=hza5E%cpvkoYqXUFX8fvs0x^LrUIzVUw1+3K#?N#0(Y=2X@Ad7r*w)zf2ZNV$=i{6QoT;rTE14uSbhs)YLd zmi*X{{=mr-Cq^3^B5-X}TRiubFMIzx|NNnQAFM4yMB!EF({6pvKm6X;`({RAAvYdi zrHDNhVrEeo115!e*Pq|^vp?~p)QVWx+8QNzeDui6AOexthC(oz#~8Y zLq9k@w@s6gs3*WM*wo+kgWq}m6*q*KIu#*RBDNIgq#+waT6N4jSOP!CV@5&admg;! zpZ(Ae?Vj56pJ1LnxZht8hg+TGmdRwFUg+5` ze&MYzc)`|m)1}3)Fiq?HKxu-nUF0;f5#OnX-qra5lD{vNP6AVr@f>%_ft1wvssF?O z`kQy%c6(LZwYBQz=YEEVx1;W-u0G`3K>K(svIs+7}$1XW` z{E91xnP5bOgX{|yfLCh`3x}Y)&~(^+Lr7k;>??~hI@57j%@<)}f_zKI%ue|*4ecRvHX2zxpCRaMh3Yr)D!em5+MJ?pH z&wJJjKKmsOEr`Xbce1@TecPLV&->=Uk&7y0M&r6>V#V5ljkmw~EuXmk_S!0wTIP_i z>zlvr9~?Sz5KymSmkFtcSkGWbn`j6S2j`k41CXeW*H{1J&;7zjK6raIwrs69QA6MG znr}LG^cVvYkGn>)=mw~XgeVXaH6TNL)fJb0`y0N?u8o@Mtgeh9qiWRP=ic;lGik_F z&I`zd4H%)eI18XWs}FSt#VJrP05ci#*Iah#8@}%c)-O8H?CyB5c<-jO>E`aAzWwcg z_LjG)dTVTDjUi>WOdtagjNy0x$-6)D-Vd-7W(zMZ+~wC^{cUgf)>d|6g813&@@ubt z_VZq}v(q+CTc@J>(7h*i&zxli#pq}DqRP1Ty6fKX1K)o2RhPPU3Pnf_8~6BR=MCb1 zPE{CjYh(JqUh~=m#|}-mcf6t9on2LZ?>pc9*YAH{ZANuGeKiE?We-X+;c}2mmj1b& z1%9G5%kHFqDnc1H%{Ao+JrIq?qo+LMR<5loZEtR$eCVVqT0Yni) zOmhQq4xj^g3fPOQbO`C7N9+$DQDcHG*Vegax*HjXlF%(?JVji27bFxS-&DgUDHhcu zmt1_^O;2~;L1=4h=Yjk0HEdN$RXs#RC7q@2<2J@HA@ESww#}^BnzcK#cGroQI9Z4S z7CCw`j9DI+u;nkLUn9NY$=5yag)hAI+0VKD+Uu{m_PVD&P4Mc z!%uzc4cFc9q|2|k{P-o8Typs(hmIUNaCl?=;M&H4)wPY4)wOZ_w?1B7o2;%+Cad*$ zwH{4uJ+{?|ZOx`8wg}0BKtf^L1H5P}(u%asHR03wnQLagZCu+p*SfZGu5r!G`%tn` zapGHeuTiuJ`?z;eRQ=39_Ry)?n%Y)^_Sz?3fB3-B$@+#jBqR_O=M0;$nh>3_VY5d^ zw+VM)hZ|BdogA4Hrt%^xUMaA2d*GrY&wSBm?s~_D33TSv=|>)VplznA9txG{I|?yb zuJIflJ#qHIN$_xvgNVLY>N!YbU?Gdblkr5;BZpVM<9pt4+3`zc=9$onxS2wXhp2A_ zIvH(z_YZ!L88I6oI0|{aQ@lkwqfk@8unKu18QIxuzUA*e>qRdW4+evz_5Sq9(|`Q? ze*%oFQEhEy>-yqj7ft>4AHCzx;GrBsiq%c=_g?!g*WCCNCPmEoC*h>$sNXngycqo- zWv?OLICS`r|KM%!c*|P@zSXsEDzE;EuYAUHo@I)J50^Jh<;{@(BYzO(1f8(6PX4jW9O7cLquiKDX|(TFL8 z-MWn-x#sfYKmL1Fcm>|XwL0<7iuUxs^Up5zwY|u zS6u0QOJ@AY{SQuOyIx$|w5@BIVL+=RUOVIsq!4tyYD>x9yXHXG^5xP`#d_>wyE1|y zKq0N$-r7mFD1e;KqMJ~pX-L<0;4~o4tpp-9p7p}doU9%aFChEqy$`yXQaA%A78R&E zRc2De%nyW^-xffyqzH%`IV5`&J0vo3B+MXzLL{6a zA$0W6fp7eVuO~a&Jh#>HY;GgUEc2!plYIbMa zZud*R=8JB=5kj|oG*IC z%Rl$!hLwx~hn&~ZGZRyU2V#!%D=6a8w?S-4h=mY7y1xGXKk!3Gk6ya7Jte63@U5OX z{pgSU(D$D@bH>s*WK1kT%&Zf&NtB#WiXqJERK3DDOsM{j*L~;nUi6}NDw~^A@qTw_ zyV;&T_V7c0_~ze!`)~f&Q|C^$;&!I9(_3eL_ZNQs6Ysmt@6Hqg6>ntY$iZ*>C$A$I z0|T-~m_u$i@5ZCiXMD!zme3wY~0X*Szk#|KaDp^fPT`jT*33328z> z5+;iwGJ{g68<8qW*bL9){Q9W=me+pA!GlMd?WwYH&CJiHfA~AUd*Z=+K`6T|Y5>>ymv-7~c_cm?Y zw2f;UKt*+Z;@1xXEaets%C$d-ICL`3g$N?;!HbSO>87W(;)$@^wD&)74=X1lBMH@zBq}%&(&BKOI~UbP z$8|DVvm`5&TJ~sY;B*2YAwu7&IwGNPI=v#$8{$S@0t6zYLZoS@WDq9WZJZ<}2=$-# zw0i_7hP+0TDoh46?T6R6B^c3VMIpFDJAw+f850=7VJ7UI2-J%|aqoi$FxHCrC*Azi zwe0WWY>p$PkfbVh)FSn)nYDvsJdr5NbCr8vmp3c`dJ4nKkOgyP4bF{iT2Z3nx!L zbltT#I3E4j5C03ly;DzCAcDrvrtb5;?A0&({Ld%v$f=4LRR&XVej_IABQUWcN`Dz_ z3|X@~J@sR6{HN2cEd|j`+)O_Eb6)x7U-i{~Iwc2)T2H1UeKsJ5;jk%DnaPBVa!g@T zMbQf)BGih^4jh<#*Y|(#6_+2EX#*&{`l&nn=$RjU;~P($c)(~Sz74z1naCj2W=!7l z&cwvIBLJ~Npsh9{tugvd-|%&>`l>Gz?`B(5ahT0^XVcwwd*{KA-~C%}`o*{Y@~^(- zH-F{V|J9ow`uLsg?hNYLtM|ey>;Le(zkO}IZatH+mJGuLP9`sCXSaRmuS{hHqNL)y zZ&koYFT4EfzVREs`8BV(>dMPVJ$v#Z>e=y7~BJS2zb!-hA}T?$*xs_O^=H%BaWT!)z-T<_-ghC{N!KG&FdO z#Mh<79`r!~#_9n*v;iV`=T-I0=~HaGgHVDFOPZ`~x?4C*y#&H8e`u>MM*fx;J%7Bm z?!AKb(fjY4wGQE2Nic^61c?eplb0t%(*>KqgE+dLQe&D;qU8NaK`+6KNJeP%Q>D3? z<^%0xCxW9s2E`@iqKHkSoHr#{DEmqZZA{&BAZ7OpN}uDldq9JoDk3?(xHAzGbp2u1?n_)x zit|&_cm_?FgfTcOJdfE$mtOj!FMM?a2j{EG5VIiz4^@@cc^~#kv~G9GyEE^D5wE14 zys{Vguz6d9aUW=p1To|`dTLaisPn#cuJP^mY-ifcc4zIAp8O=|yb@gN02QO(`CYF) zxONZ%C-5STbFFu+m)3hHUM0+;2r!z~o0Ow+Zb^kyXVWJ=>8gM9k6u5WO}&bU`k8E< zKmV)0@*AIc_|9*C-M5`OeVVDBPN!}|4I%i@sR58>n$4D&z$rF{-M1MVfMj z*=P_(Ahy~94*&f7|7E+o16VZ9$?Vo=-SV|x`PDmHo2te^y;mpVMZH%a_n5%PaAy)C z1q3V#uPWg@SB)&9qGHrT$E&07{I1tu`;_b3#(`A4%yyft^Jjkehkx+?2kvLCH72Zz zqDwR;VGxA~yr>g#;+*%b_pNK4Yg<*P;-!V5m%Zf0-}bHFvVLG~wmWsLYnpavX9uF~ z?(F^#-}&GN@4!xD0)L2jZFy9^=C$9vHd(h^dsB&!_oPB@$G5xf_SW>j|F_>heezN9 zPBpkMarnrg&-=W;{cYd=np+ApZR ze`(^a`Gy3N4-UxJDWQXKlI4%&Tc)jAy)FTOR9=Q^R6B3nwr0~ z&)eM>9p3AhAArD^=8|I^!hQgpd+dy1ONa_KslF&!05bd@IeYo7ZQTRei&r?e=YDhm^L4cjazVv4dq93gE`+Kv)^SrpF7 z37`_f%oZAisAPwJ%!tHgv3HOL2dEE@MA*=YXM zD86D+>>%4h0$@?wKIIuVf7Ta#sjMA1zuV5*R*1Z)^WsIC*1OiXPP}^h$)EYxD&l9} zSW9X=l*kdt5E)~tkSl`>m_w%6U>t?PM^7zpEKk`4`@%FZ93_-pB zrq}=7XWsH`xE7`sRj)oc$i)Lth>yEI!I3;-25VCC3KjL1xu!`q-l*0N{P$n{g}1%+ zw}q^Fry#awcjp}H@yOOIE0bnAtra)k@|4%U;UD^Ku57*CY{CE++|egAl6vcd#) zO*jHJSXyDG3yNFd(*{BoRrTJBK*^{Yg7Vl_=FF+n@A#j8@Q$~=rENTzTfw#G^>bV2&TpRII=?fUZtw2woIQK`6CeHfx$`^TJ9v-?3|m7_ zzxCG7|C+yZZlM;5tHABQx!nbJ5G`Hf-?(9G4mBH^O$UX_b2ZB zcW?U1vuDm!RRwkRcw{CAKK~oOrXCp~iDwn6QaZb;v-B2Ri>$)o!_p(9LA(UxGdQcF zzkn(Rb8G(K_kQQjzk2V;+G;Xd+gRV)Jnb6aoNr$HjrI3^ho#ABWq}JeMd1m`qKpww zA?zYO3fnvZRvPP}i!nTJcHp1;xt-lD3(6CPF$ zvn`zENK{lxDaDR4)#k~q-}-kyySsIs4H5iJ&-k>B0~^6^0VT&HfEa{AF~LwW?&H*o zwCE6J5H!tDB6N8kl-BfP$Ybb4$irw@y@UgNHDmoi?I>jtkJr>VqX{Qpsf6WmJ-4}i|6O;pVS=i6H905LlD6aX0us}2v{|G;hUegBEO@0^}L z57!EbH5N>wGOBA@IdIWPycxyq&S9<-rX~{4Yei)Zm@OM+iesEYvQ@-+1px278tbI> zUM;((QRbQz#?%#qjfzmPyG4*rRSRk??8G(9qNE(wt3^dUh4VqYSaZNkCL0^q-Eh^1 z{_Oo{cD9+p#^4fd3w{Bu@@I&62ig@!5X993sHZ5b^>cAYb)y9=~L$o^Q?8Mq6~GSBBtVMTvg2V+GOYat|cqs zNDUuZ);qN|OAO=`fQ==H@VGv3ayZR6Ae-aq)@gKpM>$XMpOwriu8fB6@!95_sDgM>37=SwGDdjX+6 zX$tC?W#BIAc9?Z?tz<>YYwyHNWYuh*-TBp@{WpGdd$PU)fwfA&)}veh>YpC@sxRN6 z$$5n*56+B|SbQk!7r~kfM75*Aj|PP7Bp&2PKl2MK-~UsM^GtQMe(=!Ozy9^x=QhIz zml$#k#Pv-iqm3ll!37K)!!X0D4uR0r?|sJ~z3-iWP+NB5*49>UzV+6y!U&ZpepOQ7 zLmAbixlf@N^AS(lFU&>ni=rWVH5|3Z;E<|{OWYtTvWU@`%{PyJv@nvU%M(Q%v>$Ef zDEd{wob*qgS!!qEC7UU&YeZvKMZA}$X&n64`SaUnH=FI58CUSmIscp&zwFsB{#(0# z>J58o3`j*yo|Yv|St6morDZ@UF*dkY9u#-^BCW3h1QXJ8DOkWDy9 zt;Zwp1n}aB4G1PCl_H}M3Cr0aVuosv6-JaTfnh5W@d{FiNae&iH{Ck5`~EYJI;HjX zmEEoBWK(sVkooS;W^-2`hso{O_xP=Y6;nYtJvC!f{%Hmw> zS%Hxq*@{N16KVYEhtHAsj@qz?-m3<jl$1}HD2P|}#ENE8gwuxTNz%f;3p%tWk0jZSyA z6xC={Gt*>sytB2-mbDgut>N+d#7$e>^&?}wYYiKCRfRZZOALi5ks;FBR$j$e11|ud zIeCWEYe+JsEMBuk6HG2b*dD-|&!VA_WIf_X#7US3#%wD9h(%eU5U;kX?WnF{jB6Wd z8r{WPf9d!B_E)}Y?cf0l`;0<6G3|KZ(9%CKoD)#VQ|aE^tbtG{l5Ra!p{y$2k**y& z_{zWYRloi7|HV%o*iFWxW;PqMTzSPR;k@K2U-$kJS>I#rA-tOAD_PXV&&pkTG;1wt zrcbtO5>og%G|pS{i1#2K(n`jvc4#fI zoQZ^zmkasqdIFJGfgRVY$Btij?9#{1Z=L(|cN<%=oiuK0xv}1}8jw?)_J$BqVCfVH zm&r6FsSff#S|)K%lVRr#2s&$7LZGV`3Axrty=SsMOhSXo_M)Ct2xYy3Cco#=HYclYN!@Z-nn4fkXJGgPs)G~EFv*)n*yY) zYA9?bgJT0?@j@i5HA_f_YebETW1>L(9I^&_6@`jq8lp_2UWi#F1TIpH*=JIfux%zB zJ*}c`9CAOM?Wm`4Af*pP=CrOWbwDNYa68c$6&iMch0Od)@J8Wa!k#uZAht#oB;*x_ zNJ)vjcv5MNQ5A1uVnLa1PYDbqs5K@W0w-(?sj3N^xWqdZ@0p1N#)Rd6qo};saFm!b zF_+ z^!)Gt+Hbt#tG{A2SxIwt5XbpSlKz?mc1N{CYqYbl=C9U@_meRlIzR}g>T0TdnL5(sc1W^o-Vc;v?9FQg3V-P(wyxT?RTX&e zo9PTlY9}@$K=4}UeR9!E3k$T_j*dFPhxE!Msw)Rpp7!a_eAnCG%3fNpcYo}ziw+%U z3NCDzXf=1UspyZ+g1wVeC?*2Q1W!sh^s5*LDpWB6A-gzsr&EX$!yu&nlr-Xik4Am2 zQZy_N#uRVrMc_l;H&vgLzj=|?IaT%EIqxV#?nUE1FOlF%_wfvaz}X>OAuu&0e^mew zWv2udr?#@<)r{&F{_U5D7g$TI-g}T(HL9FLs{+2#U~57c6~s`ehy_Gi+7G>n1C%8s zZw3g=hDAMuZomDnZ~K#XPAXC%D6uj2NB{ZvV`W5*BV|$tHbF*nSY-}N%L0m9I-~n5 zpNm8cV>o!#eLRd3^{Db7VjhjE;8^#b1ft%@>8J)Z!eImnim2X&z#`sQ1E_+nHB9QA zCxvU(x2<|@ee1>T%%+pcxSh=^TaU(LHDg;_X9mWgu) zX2T@n#ltW+&VkiC_3%&#nUzV^wqgw_P#IDp69Sth8a!bVlS3AeEU=K&9Bhmsf{F(b zMB-Ub&O26a#8p*I6i&G?Y#1Y5mV^G`*!A?lXKfU+q;_&JoM0q{`v#wPM-tU zM8b`0+O2o~?mIr~)vqG!(doc!XKRNGWCqDUD0!Qcb)7^Pbu5TzJcm1B!HPi43LyhP zgj!Uir#}0ZbDO7b|KtB@n8oRlRXTiFnOjM=Z0uSBj!Lal+I@wjH^2w?TPdG6fG+6E!b$2%8Rmdr7TJIUi3JaQT&2L1re(8&Z-I#xzrjl_x8`1HV&$h0mj}@RAab2N!6#anJn^xY=wn zSz*8h?v=1Iub_B%L|A_flll-7lx*QZa3Rh!9B>)@#0Yz0y$GPDvP^8kbe=fM2uUk1 z9MT<#i8@rnbTwow7kH>KhGDrf7KS|q3>zmtsIKv7gpl_zERSS_2BFWvi-1T- z!TALe5jG5{NbHyKASUtwR%SKCT!ncru|iD9noUW@cT-X7jV+O?a1uyy-V=7JD~Qyq znz-i)MDSjjSu}@KQ?`+`+XGQ-hL068|J4 zD@nuXR7s3Q-D;(l3>UnjAteAFlnw$4c_2QIQJYpUcDJ@@2eXXsH0N}scl zmW6wOr@4L7WeThvko7hH*g1uG13Go`(W?&}6z_}E)4B$z10zyq2pSIFp%Cs7vIzmO z#ya2F+PvVUpZ%Nv=|5IbVsqc!cOJduSY>JrThOUXOi;@DG#e-;W5_=fv;txE91 zLd3HgGVDdgiNZ+=#|$iluv;_b;>O2M)jJ zb6(Lp)yhc7fz}Zk^=ANG`0K!IS!DTVoTjz+B<3@rQJO>KQBhT|&e-wRiHCMhot;$H zT01hgFC}!xX;{qClO81lGew<6;)>XdJgH%Cod#v1P%@+lNvRR_ZYPn5 z$|+xdl9CWb5m#7Ypx9gPzNH}wvxzYJ9D(QH{0lz5WDb+zlv{?N2*)1)h7>RM>3PtJ(vpxkYc?jHLC<2N5GG zkdP8i4Ko_`&H-RzwiQ>#nu@Ecwl!O_#B9`>utSQhWoARnY+!5^a-q$d=EMV!wC#)` zEo7xS@QSbaiqUwyJ=-;gNy5Zk)7cD(0+KyKoinVn8%iCpkeHEYIZ+i;3P0`^iV39A z7f9CV```U8CgQ3hHrvyg5G=Fx3JMG#A)?G5aV||+bal;hDw{-E5lf)}By}+?lE&`l zT9T!b$v>$+N{x0>5`j#z3Z-=ZG$AR_U_>ISgJh&8dqlMm(HY3XJkRdl{4j}XO3Er> zmAa`_ZkCX%N&=pW?`bR(bEgdm3A0_?TsLRU>NlGnoGsQ)svt|_jM{8_c03<GHg^3AV?>?RLTMnhqrR@^$^K1jnUV~ql{<~@I8`7xpa2k9)v%Ii zE4cNU&%EvS50m!*38~wi-g(QtyciuM#YxfF$Y)Jawldr9>tD`A(K=1+)cI6>=-po8W+EL%lQ{(~AKS)Y&JonY0xo zLC|?QvM$stp^E`4;vKT_*>Q!I7$`bdR@eT-Ebl6TAM>ExBeVfTLrT+*CWYof8#WYD1_pq0W@7q*foUo~R0?VT#*{OOZqs*uDw){<6!qfFDH zqPUdAK%BJ&L8>Zjj2B@hD4cKBFFN?*SAO2_|F_?+0Z(%J!IO_1I(+QtC2Sg%F7mLH zU%f@%^3q<{I=@jgOEgX@(@jwiA}{Uw%IfHQAeOo#vwgWq!p3o#ah_OrwZ z_oL9w5tC#P(#_?u)40}|nuxnLSkrcPRcqK2oRia!oZj7?vej8L1FGkJ=1Z=5@{@Pl zU9n8?@WGTBF6DM&iwcoY(5w~@28bLYG*W4>$2#^3!yw^QK_xi#tv7XTIGmhA&P#17 z%U}UOWk|Iaw(@|Rirt~lu{o@_R#33ETv3nt+bw!1&0ok zy|xlJB*1eAqWI764+U%|#?Yzk*z+WpdxY0jKN!4D;37tcBPrER0;K71Ne7Dt0MSFC zJ!ED{%ZbYKI#HoZqX(maw~*z?9)Vt)3HUr>L2OW(Dr%N+CFG?CtS^3(aE(3{0F;dg zQfSzl&ro3%@iWNJ{LC-jd(VmBcrhUq%i)$6zHsK+ZiW&ELi4~P3YJnlp`cU(p>P?I zq6_58@|g&bZg(vy!Vx|20#BP~&sEkCgdmq(QZwQV0Hs_^(vIfGb|59^keFj!DCId0 zH<@Nv9G?K{y=S%4t(|C%aR_4!GAecis)%W}C{kVFBF<_&ES821@gl-xn$|t}sZaUX zZGZj1M?YLw^=vk~>tlDUt#7Q3M?${vtdt$;YuLGtl~!x&n`VuXbPAN1G;BIFRtcgoV3c`EXxLL`@3Bg*`GH))Tx2XNejWAr+i??A+N$ z&yH5>W>-}Crdw`(=JQ|ZwGp-;7wtu*5Cl@#UJ6j~&J>!m8}HVYv-e{1{HN(` za?-E@r0RVIt^n`6w=CWhv8ma67Y}U+$}XwAlxd5)hVpc)n0j?8vIl=&horQqKs{lj z#b-|?#QhbW`Yw=Bf|va_l*d>T6+~h#)J2|x&)NAw4pMaS#(6LydDu&jQCT4h`zAHr ziPYS=0;MIox<|27xKnj7xDMcqn$`b0ur z_UCq_Qcy@YaMWwuiN$e(00tSu+O}s;pZ4OR zs4XrzZit%LXpa~=dMp{HbAR{wIwF9IQO|-vBehmzchzN8U5OzgqGmP~^%NfxA!MLp z1EP@Y7R+()cyPF-B{+(!8*x<_(X=qkhDhL0)62f#bH|4cx6W0SbxnKs$8K|B>xv=7 z{jo`EX9ZOfLMbEq{HN$xJx;{~{R&KyHEfKnVw^UUhHiw^cOXrNCLu6)Sl7!uOsV_5 zFJX}}NTuxk3j?lE@Nvjcn1+Ir^%Rx?f;yi$x&NLMk3ISrvCi6AtMsHBp8nETy?W+m zt$3)16VAg&f^^t=!OEoFoxT7DdQ;N@+ImDau&W}6Q51J!DkDl>NUyx%`t9i!iHC@Y zYnp~MEd3_KFjHz5O%Utu6`;5S2Z?JV4`gsd?%}jNFrSgl=LaeniC8(01TXT2s%wN_b)z*RfTp_Mw7DL z+#O_Si!LBxI1XI`5B-w4{z&@VN6w%lxrQFnD0dmfsAbASMoz|0gpEKcEn|cvBL|&o zrR0zfbH9+!%BT{lsKRhjtQ>CHPna+@f#GH1^2=roJ1q}dB8RtmCCDa6vM zVUZWA1P>@kk{dI0I_>WY8Obz~Wfba^g5)@IZl?*thEpJ(vPUW9eJDd6@dunFFJ+W1 zsbXdYv#5C1)91JDyX%2wXEv@YHb#W5f6C1-|B_cXZd(jFa>NLmH`CywFlS2~EO7EH zzqJ1&MZqA!o}a|!+&G|6QBkMvxi5b4CD%Q91~^FDwBAA7%;q|Zh`M2`I-uNvP>RnB z2k!vXEE*^+KcVw-4L$IYistxwcv1dK$ugyW%bBO6n zzXarx!lPF?I%ky$8>%k7=Bm$l@k`$G`~P!Po5nS#PoBD` z`uLM>xB=-b#^lE@#Co3<27<4g5>O7LAQDkStNyvm{s#GB0^Y_ zNm?z~MJdWWNHxwT7ox(;`cJZfLjqyuxLuJDOcMc&VSu6Ryg%{C$=$6Pyth`TttV7B z-SW&Az2ap)WLINSuV5cS8)#8~5u<8|3aem_j}}}}E@qJ&DI|G=J9U$U8e;SjR9b3L z+b{U)uR3>b`^+N`J$mASlaJhY_OUICPLE`_av!98ZwQhtexa2y}}A zG^Yl0;jZC)e_qP=qQ0S9)kknZo}tL8O?PQd5JpTqF(vM4Rt-DBnV2BY7+fj z)J?zA-shly1!2T1x#)wCFEn9xbqrdGqKcxQp{Ob9lDuZ6<)g0M+?hfx6*@$zTaQb= zS5V~ANDB;gMp?X>to(&#r$GS5Ne{|Kg9MMkbzNxPG_6v9@{#7_UzW__WaiFw1G0b*aNH8_~7c=N^NRC z^Ta*~zx6TJ)?%KibcAyp_N)W)m@g2AeGR95UFoZK6LWP zMfLX1=5*)$bbE9A?5W+IEp5HE%w!H6Jh*=N@WDfeR}XGj6VJv7=NQJhSMq{UIxH3; zc{vjs_P+V_=RNn4`ycqkhd(l@P1DFDCr%LInj3Dgst#TxWY=|U%FU~VokF1RkUUSKluW_xMJAK+Fi54(fsDr*p zDOX8LK$7S$r3oP!d`TQ=@#3;8lTRN7aqvn(IoH)*Egcyyz)J2@$7F#WGSPI;wEt@P zqcb(;hOUIP-%wxV&w1Gph17677xp|8Mqe)va9H$8(X)=r-UreOOwhX-#B!L+2X@O{ zNPN_TCqiG6Y!dXz$WMFNVoQ{*@v!uZkwv{a`KdSk+@JjZA6g-Aj8O%{+Lc#)*_RzW zdXZ=d;T9iu{ZL;>7IUNIl17+grY?8k(%Bb401Hj3%7{Mj&;uWQ_n$p_&t1Fcw`Q}r zhg_8n8zy6FZ5@q9BNb!E6Eaf4kkZkERW)jvJdt$xK-gZ<4I^oHN^byB@+i_^^5asNc;TFfMuL_$HP!5GnO5h@yKKYaUbBdL;AK*aI9c5BIw>h;z2@pw{C zRt#5BcT?~zP@=t(9?7(V{ZO;#$uUtMA?SbxdQ_7LH+dN2dr>Hs zg13_%l$Mu+vxUM$j{vBOGYkP&)p*Ssi#)mNn~(#r`&U3;7ws7bGMQGHddoiKR&v+M zZc_n94~Bun9}1lkMd4oPcaly?J0*Em_&Ksoo9fB7aoGaRqoPoYL#@$udswt6v`A@m zq@da#)PV_D_P94+ArNvJ0>xm^N+k7ci(FucdFl;cR%fL`%Mw048oIB#Of(rpil`67 z82wo!Dn>{lRsE)a^|OERu6NgLlv%w;#cS(_U-rdcym91!z$+VpH!yLZ1RB#^4A2dm$G?EGK+$vZ#(;oIBk7I_eJ#RevxwPKA?5oTH$8zw?+#qHX# zhC=@0%S|)BE6|C7grs~kXba7BmEF|}^02i#c#vTLMdRi4snc@m zF=~~8ij}A$>%(4e5%C^Gym@Bxj&rx&f9L&Ad)BSbc>eRplaUiK-IOowr4FJXrnQog z*a{-X;FVwUs$cyNzp#1s%(yab<4!*G@Yc@u^*7!)8jaF6+i=JmQP|BA^HgeK>}dX9 zJE97!zaUoE$nnERrSU{Y#CxcSQ-z8;(RQcV**s|o2M%mpeC0LJc)lNH6eXtCw1_z5 zrifb-0taQ+*))>O2TK+(*xKBB^x;#}=`5U&WR3N$-)&nWzTxJZUi3LHvtzr{YzsJS z6bDjbPE`;E-;yNNANi;o-3Z*kRP9l3U%pWOv-nEB*XW~2DuY6n3zD!QEiQ^M!B@7n z^Gd4Zn2sb8Wt1MnQhm*{|3WzD6$&l+(n-{=)*RrsNWRYLj;^-s9L}DO9%dIIRy$c- z)Y;clI@cX70b4BS%WK|F7=p3z8rnGpcu}zI`DVZAWq>Wv`zXdfnROkJ0FmgjHz|q| zozupFMx&=$!>LS=wW9}r;>UjCFaGo|SR~|xY87jTj(zTze(7j!Bm@unZyRyFWWqk(a18D*+ zc`t1ifJS`oCq0G!YH(=3@SQx`s~?Ln_FAk>O32^ zwW%trQ`fjwoUR`_{JdAZ^xA8$XyF^zc&3x>(!IzXnmU_vLti6gl zDZ5alXhK&q42yU^?QRdSQmi=-aM%+!!zIwJOi$()YA#)AcDl?bGr!nLaZ$1;6Cqh5 zPZ!-B=z?6NC|d|`1#-j~btWZx;}X-qEEGfoC?XMc21{8yiu`;8a?$|>cWJIM&Zo4f zh*BgFNgf#$F~(`Lwz2W!Kl-NkzUw_4R^Hmy*Y?QKOFsYWzB26W6qs=8T3n}~ke4X4 zc!V1L_FcFJV#fZn&wQhI!_7A-8!H<2y`IbQs-+$t* zzxFF%_*LIP7Cz*^isztoD>VUxIIIeSapG52R=)V_zWUdH?&qgFJ0r_ZA#HpAU3Z;4 z@!*x$JZZAFT90ZXj&8RU;*&-wih?X`g3BPD+2R#Y*E)o=qT|AEI61^902LKh%i3VF zzN#GjH%ZJ%y}=wY>nZGHO7dO z*{p?EyE3}@mZ#tP+~?Mldgi@C#aazV@+Na5NsO2fGTWO4lcnA(k`-0zgJh=!<0XmB zfgqT>`a+{CM}b{620M@@e^+u1i4Bbj#c zflB(bD-|&vd`SS_Oz!KWxBwOFc>s=uN16#g|{T}xgKN5WhT4W)!w8gG+a#Hf#f$X`dlEeP#%RI zqqHu-%2XMwAHL|ve)Pxw@?GzRbEalL6{mXj4Nv*oulj<>tqdzFq26xmXStq1DOj+# z02B$5l2)Uf#){xsL^md*JKlfW``-O$zG(@#=~>Ty&PzVqx$wRqiZOw5SU0eiHVz%O z^_ur=Ys;k8wnvYSNt}98wi=hFQ)CkL^wDt9s3agt<4|h+;%V$`m?G5v(4mot2ZKF{ zQ&wGBSyNKaN?tkS;||cPCA;?Y=e_8%Yo7d`xBm|j2jG!=?)$^H|L!YZ^{VZuKo}%Z zpE95^e_~MA2vUQ<%1+(N!S%2H*4O^dul({O_uOwmY%36^v*zO;{b*g;jUxvSA2~Lj zjE%L%F!e*SBH<;?kY|YyFu{2hX+^{utK}vF21MBy2M^K1M=x66IM9uGv|iJ+FFU_G z6DTDy41k0Tiv(4fHnUTYo^EE1I7&(GwX&6Zv6j@MX&dKhJegd1-|)seKK5ZI2-r6w zD$jq(i$DFvFY(?BLpYqJ$E*_OvPtw)H)t`M2Ay%R=n6nduwYbbV;_6u;di|CE#%cQ zF1!AQ&wk}A&Th7~9fc?(i6=TU$Pbe_mxaNi%#ktn`%9@zBEFv@wF~tad5Dc-1)+76+ zU;UNu`-}I!>-YaqS_ef{TZPPK?$kq%o<4b|s_bYyTH9D(Utb?jCf3@Nn?6yBCN}|- z0wJBeLQkJMW7udwI>mq`f(Vgw&KNVU?U6%=i7gRSNICB5%{&yAgp(;l!Tb-YWL3i^ zD7U@6y|X=??KGl7Ffhu-hzOW`19%687h&*dvU2UUSAF_(pL68cQ8MJ4R=f0LVFwZ? z4_D|%#Dv`#m0G0~Ty1)o1Yw4D&`d+>`mXt?0BC}^GPyt4! z#)OLuWnVP)UhJ@&rq$uq90$-1QD+6@{vZCS*JxyC&9Xnml4i5Ar_2Mki_uU@IyKFP4R~zmci#Ma+ov97 zW9#wii(dZ9bLVEZ9)%NZG|F-)Nmw>i1#>lXZB>zKBLWe(Ht`3K2+S1Zl@kCgg&Q;4 zxsg%}r)VDXB*6MqlhZ9INI{C=WAX&@di~{V@Q)B!M7@ghLKR5^;kd3M2-1lOY)HAb zUfeY|J>~wpKXLZ-Ij#%?fB3s^yX?wqDda*kre{~h*?+;#3?{A&K;TjRnJ<0GQ*XNI zJ%9P0+y4B0L>?YOL`2>T$TjEN>Ci=?NmT*4WBU)+Xc0WMy^LR+iatFfssDh?lcx zPM<%w2~}oO*&5;az?i4j+KOvi3DL&E1E#i+7}`jA={CRzQPptphlp3G^S)`DwrzKJ zcf9w$^OBcNRp-0_5UuNKytaDy=%K5xzwWy0uQ_=9B2suE9}b8K=f%Vr zrX-lc34KX(OEQK#@=NM|ApI#BC53H>!M9vEQF1B$6Zdz@Iw*@m2v8>>wPRvpfEadX z)=W$#NbWuksrpkk`4C=}7ofsKCs~DE^~qvXM9ZOA+D=4Goy_b>Mr8Gvey1`;Gd-b~ ztdrg{fcE|XF)*wUqiN$}5>u&k;V_6lvoM}BCVL=tC2}v)EsDddva8J#$D`VHUt-Eb`_dGDFv*naM-Uwz%vZrPqXYbr-7tq;d9rAYI@XOxn` zYho=*$nUua)3lH@oGnWTX9STDi+S+=hwk~d$z|^K}MUt-WeRVF#_Y1hgW6 zZ(9*~C7M~;RwH0#*R~|GGO0!@#I~hiYMXH0o5_?yIn=#FwMLpBB)KZcToWlkfDr$L zur>~|aDHXu$Pv+dnFs=FtF?`>h*smVmzLDCvXBes*f5beC6%_7w&6>zxZ&)X_ZT*f z*Yjr{z5AX!Zn@?8P8(IPR#f7VSR$(V6eX2Fi{5~h91%6Txjm)P#xtJz+>4K1`M{kY zzx(dHX4{+L)Ff$z!EA}xK*fnP)7kE92Alz?vMkJ_x`I+XL`oD8QL$`HMdBJJB4%Sk z!Uv;3H5%Ev5>bLl=|Cl|S&NE#Rq?L%u9;1nwsozWH8Tl`{-bI@7J~}-){{3P0&yU& zM)ttLjjOJ{^2#f&xa87{*AE@A^+-Wps8LmcLvWjmg9ehMY)!^Q4^f|?KMzflgUsE@ zx!SG%bY;VfQktjPEQ}=6aeFeYdUYgb>xqIw9LFh)65wF(y7$hy8Zj{&g0O-pp0g3n zf^fELh9s-cBo8`snJ63=8a=!r)+mKrr`{wXloGmz(8Z8|FG-=W>szBv(N4NV9h5~U z2r)rlN@_q6ip)uQJ9d`!I*{v8nPja~R2^Jcr`rltRYt8mB>v*C0qbD|~!D5QnS z10nIyr4-B)kre^RQ;&2d=p=@~D@YIy6jSDK{9%V?U(R2HuciLuNdg zyzDE#^pcCOY?~ceZpDZ5TLq59gtO@ssuGUui>oJ+r*ceDdu3%v(V^~Dz4!5GD1xe1 zs9H3C^7c2wd0UTHH#VkQv-|G6ZEHH+*`2kst=aC(t7}^&_2P)hC}~xV8DoRVbb5v> z)z(4aF{$yJ5U-Zh2m{1nJCRq?l+1(Ediuc|uD@<)XY1^# z$4;L<^U%ZhK5+N_v)QhSCk;p8rel3onb~{wjq@`fS)Lg2sA1y?zHNdnMZ_HQyf8sG zEgNHuHIJUAc;KptLZlTz@E|3^NFp~xzmvw~K^!+mh(HKbjq2J~$BrMr?8>W-9Y1>T z@S*jMH9H!QYz=}}FCZ`8c?tG$Jj0I3stJca5Yi!$;V?49GlgTSyuO$TA}ShCot&h6 zVm2b9fV#VUo6`da_|!saFjn z9G9lS4@er~Mj@iXxkKC$W?@qHU9Ote4wJQ8ZZFpSk(jhIg!_9ZRC8^~2+a&pyxKR& z6BB8%J1z;rY>X;8(2GIptKkF^`j-~}Cl2kb>L`F?Ch;D3Q!y6_0w|JrYNgOMDcNmC zRK!GATe9S%<1uwDYPckQUcX}D<87bGh2yvlgeeL}xxSFq-Lc^se-UMd39k}p2v z8{xn`ipjwqfn{dP)_4ae4Z_JyAZDnjVMaKyCK?(D&iOFY z2pc=I1|mgB;;zA#6(x!X2l|)*%hdJAx2+25+K$Gnu65F?iudX)bL%~`abB!3p20$D zcvOuAtj>5hZQQmYVeo;C`qi&I`t@Hqy6mc*@!F{g&uBK|Xp~8i5lHco(GsMd+Aru3 zn)Z%ST1^Y2;MrOt(ec!+K6q;K=C@S;_P;#*-~&eBY9=>TFNjYQ|%DqZgu(6UA9PfnlcjHk6 zfr5zAqDZv3Qiww4)O1poLc=i`aS=;mZ6RLO6Ff{!V6JOgU0o;fKwu$>F;ayLPdLpI zBn?~erN*@Si)3XM2+2Mk=)`4L9K!B*l+W7Pw#9;~cGId-8TF2zkHzbKO(z;Ve|4nxkrq(z!R(Lp~K~nXf;NMBzc|wV9Xji&HDh zMW4<+9mgWRpG0wi!00iGL1d9hB&C1~mJ+G=o?*xm2=JaPivv*`>@_7)pCXrtkmCZ0 zdIMJOsqbRXlkJfZl(~dJqCUhzFf){hxT;N@k$b2Cyov)kW{^=rIGq%*#9rV@z4udT z9A*Yo*QWJCVkUNS`4za~26^^Vam|(P;!A1$D6Joq^|iJdb8W#OqZ&>XBqdUg;k$7g zErCekm02OGs;%{&rmaqQ-1d2T_>r~0y6yaX-)rA_yFYo~&ddX3t(}Z(29c^b#mLl9 zVNoIp^9*rp$2yzJXjHkTVXmk$2JDH}R#r}(dXyl>z*;ueMqjZ&RFpshG9*sfP%wgx zvEF$$;o#h`hc38?Adn!CRT0xFF*CC&m|4UlP5=^7Mzg4k9!rkKxKepT2(fa-{?381SRG?sn8sYO-RumEb-WT0f?16 zrQIkJ2_Ru3W;#kPvb@9+5l~EhD4E+)bVxKjp$JE0D#(Zk8)7JCO2R93b#!ff^x){q z%f>4kmJe4f=f;y!RhjKw<9F=l=4_YU|NOHP=N@yOJjjy}kuj#SY%7LgT^&z5pR?8GCxv)#6BNyJ(c!b=kZMpdq4v zizMW#j9R3V>T%`~-Bt+^b4o(;GJM*W6vYx7Rb}GVwSa_l`NlFDKeBk?bFciN?|I&l ziJR69m@g}ltB5Z|hhjxk%2T^>K_!1lwvNQiwcBeCsPE7pw8KcuhtlDF(`j=bpj$l=X1XJ)!vq zS<=axoX&L(Q>jj@5P&WLLt@KhfJY;UO+MR+2*?{{^B%&U?NhK#RtB9h)FZm&kL(=W zolK7cuqUKbGkN_icnhcA(VK z+JmMq_4-1!QwmAjXXCZhc)j-uZCtpd;*b!MsLNJup*i|(=Qg{K+=UDu2Hy&YIQ8C~ zhjED)X@G%+-=l6y6TwWax%NI04WQ^|Y6B`k_p|?yfO#vV_&MOgt}&D&6`YdgMs+Qw z8X4v=ppF`n=~~_T^u3?Ty#6wx_l>A70;(Y6K?VZaeSAjI9${Ut2qO;@pv|uUNTk zr8!qU^w;fw`h~lH>n)pDX&dFnIfaTR5QzjrNC2l}53=DCL~86?bfsDLrZk{@| zGG1Rhcwp=F!FT>?`{O_T-V@WqyUnJpCg)F|5%HE;RHX%hRa;7l8Ooq>ig>i3bf9GX zP-3In9WxopIc!0QOE`%B@i>u>t5eBjSRlc&eUdzRsc@#mv{NtGPu>dD7tJsg*_XkMu56E%WsArzMDNG(D0-NK5&&JEAka=iTRajJVmXX&p#bHx68X!;OBXs^Z#401+ol zA}v4=C1^S*k&^UB)Lr4!+h`6ev58Lf!tO?*`$SMV)I70`_KA{GQw19!Yt1fDArWq- zhe-GuDKMN6)2*5Y!u26GAlMlqCG*7YX>=v#+u6{hc-%lHTn!paGAt#zcU26mu7JTF z17`k7-Oh$!syYkzTs-zQOR+GY42Z}{?x6rA?psz8bpjRgzOnUq6e2A`p7ClA`L`5!i`@5Ro#{*LnC8*X-kj|IQw&zOih7EbkHLtPcRQugOdN|LYpWJB+1;Y;O~12^tw&|^oSxnETU*Wa96OQeuHW8r-m`OP zombXb>!k^crYhdoBX;6PHCIdrj~N=xF1^AWKH{&u-mb3E`r69&bgP<<*AH*3>biIk z(2&wpm6VxlhB_UuFzn1Z@6}8{_)KdzzbHdiIKE-}DvV^loes48tiw zy>G_jH8)E0F%f})q3Vg!ki-}f$wECC*GwTukUG9EBm_~==~04d=ASv@N}rnK3H7O( z61^4nQ6lM1ZY6_1@ML&hGuZ&t3331w!iZ4J>a%S@VO6914@t!&6;-U9p#vsUW!HFV z6nACwk5aIs6k?s4qwbC9T%Zoqnt89gqL9rZo$}NK;iNku!(=V9aPo zE>H}VA4h{k(-gIYJi##3ARTjLd$#L){;mjJjN*R)W^}Gl!d)?&&TVKnOy%3%+_(T| z(8+?~iW{0f37Yp`rjHDxV$qcdMF@qp)-xtlgNs=?(}MyjGDLusg(@yS2WIW}u=p9r zq{KdjWBO9y3PH(>)|TPu*wN-&-f-=umz{Ie7yODZ~*%Bi}#RjjoDid2WRMmE5*KX!(Eb)Y%@|?qtn#qnH z-!SK=&Ny2c@70U;GsQ~o>V5A) zUY02C5A4A{FZXK;ngMAoAae(S*~8l~C>(?QJ3R{I_4+L63jLKnlbGv`!Q$@;=z%k4 zKnK0fBC&r@0_MDCb7)Qg4(i*_)z>r&fmtw0K}tpB#cD&FZwt+^Y0&g8K zkvRHp`W~F!0#NTQ>Xlk@QPI(o?)pwL&F!QWhdszSTMhkXkH|l{CG9j|$8(+drlb?H zgoz_w;B5|gO7{r}f>jBuAb5}pGr=od`>b16kF4*SYFnuVJh4-VuoqHhQsKBPO)Uss zTELS9OygC>w>&cB7zo>rlst$?$bb;`)2cE7X&0D4L$-a5CbtscBQY_<6T%tA0n~6l zZa9=2EkHaHRzN+GD0zYjd<;Y{HUki&eoB=v3>gRscD3y)LuLv0DzLQ;4W!Ze7~D*EBe;!K;NMMgcd&Ojef75eaYxpG)*V^tMha1JpTIk zD7c4+L{g*)Iz*55ASP?cwM<2p6M;S*l&Yeeb@nMGTN&9xd0bjhhu?avf%z__xnGvU z>E-#3XFjB0kCb%}7hk$BeLbM)VZBgs9T#U%l0c%!svT?;kL@KxM#V*VM4x`scy*;A zg`q~+#k~CCTy-Gk>1QTZumCf#Dk_A-|A@si)WpD^6bhm7kY51=aqT+{U0fB-`0nxt z0#HE+3sMGg7fKZ^?J%bf=rEempD|RNe@g_061;){Po!$uPp7EQzTo-C|I=F@acWxM zop>xN@hF%?2l3dnMMPDI-+@KiLDQf8cSJC}G^-d*Wro&f|7Tf8XV_lI@(YORt-y7! z=&&1uNqw*Wu=EkXcJt6~<*V?S1Iha`hoxok4(<*`TO{^{rseQe0#Y<*2Sf71iw#8H zdvoX??t#3JxjQyZ#RpuD>@VmK>AY@OdW8mPftDGJ=p4w)D;(O*gO}!OxZuc@Br{N# z1ulCtnjoY46y2eP3XBzNJ%~U1crK(~Sr3x-T-3`2%Bttd9S}k)oBZb8ohHEF!2b8gZ`+EvOvj{ANsYV!cOd=_zz1kY&9aLcnms~s|OjTVl&!Ltmgo?AM zLJbKk89)J#m{p=?p%69*s!5HiR}vNxfiVUM4(71=$N+!}LRM>vT+)q7O#G>c2`-I- z0D&4n!_H2`JYB)0V^Y?r3^XKti&^4RwDyUpK|k+7Q;CaB0__-tCTYmLeNV3l$bIk4kCdEv8s@Gz{H-y5VAgF z4W1tog+~Am92bTV^nsGjKwjb4fS|r@6`oeM4qm)nn`V1fB~hmY)!?ZT$)XzsB?;O! z=kZS{){NlDnHpte_qZ6BEU8~G$Da0^ z=r`GQYl%3>bY5NyZJFU~`@4GB$Pz4hY5Ks1UTU|>I)E}sYqEu690V*P0j-OH?;8Y^ zl>b7&_ai~~zPd3ges&Ek`LVpV#|6~D9$83;3tL%O;KC4UNjSZ?mg-SjaBq+5F=(OS ziQ-^X zX4VQYL>3y)c?D_Ob}CTe&b{G-0ZIs2;(cnCyRfC~fJ(j~HHe9xDQ=@x%FF%1@f1T@ z6il!R25b_OgBWOo82=hHM97ZG1dUP~Lh!0W3KdV(5=+}SH?!lF?IWx0*+u~<8wS^P zQ=rRYDL5Fl#Rkk?*M3Dy$=U(${nmRw`+XTo_JvI@m;T{t zso=Vr7rmMl!yh#V+CIZ{;LZ(m(UVg2_Yk?b1B>ns zB}xA#%@ycZHXx-Eb<5rxmZv9#^!dV{ylPw8%>JvME4j~CBQjMJ#Vj;42vNS}my#?f z$UgcZiUJn|V{c?Ge7b}lfH;&?{z&6IUmF22xjm@}K&{A>R=hEd187Bv3~FXp*09`7 zY9t>JrUVbD#7H8r#symipi0T*s>#3)nNed1kcL!inimED3Sm_mJTbw#2Z%ueCN&5L ze8p4?aa&I?MimOGqIjmLJVJgvRY1dOUryB%DyStR6+6FERZ3$PC`5^^iSPm>Asr<0 zT)VUHicq~0?LBhM2KJ&6Pfzx3^n_IDvydb+@NFL_M z@uDE*0;MPqlcUb#N>-7SMdaQkLszhS{!8eAwCK$ear2Mnzw6v*Zhg;JOBK5x^H-6O zw5-2`K7m}21QvsO0XPQ5m$f$kZf91|h09+6kj_vVq9hM{VHTwF1ssJ_3QPOHP)#o* z?LlW0DKb1+J6$CSG)jDsgbZbQLn#y@N0BPP#!%d7;J4t$lY`Y{*RG0lJ6u_&T0sJ0 z2tx%G2e(YH*CEN76#P4t!Xipa%1Ir9R*bHggs~2>@Hr$tc`XpPD|9(D0x1q;kfLin z=owNNz@)0eynzH_5Mqpsz$#V*7^!7C;7?z)sUzn^RgAF#8{r^H%CL8XUaWI!ZbI`^Tsw?b-evkS$1~O`|OFKOEcIwP)lKIXq zDzjAhb=W8&*11R7Z&f&tL$_`3&F)cnZ8+MLESb!bsfj(1QmBoEOur9l+OGmj-&|17 zp0&?Qoet%x<9z~J+Ri>6btO8WisB_|!y_un4DmJ(%V1&Pg4ck#mchEX&J0r?8r@?= z7ZGwmZ239hRV;cG#7YWl?qNc+^y!6N7jXkY`UiFw7-K`yW+v>k^7h|5`RLu}cF)Yt zZEc^Qwhc_+G0AAr8#KU=b2XRn^03u+5VHm&|C`Xasas-1IUO)n0 zfee(<2u^LSe&VbVZ53*j4OfP_RZrS&!RW0!B1hpbFtkel!+=csyxvKV;%RPXXb+?v zQK|U^N^X5XKbk=4fme`F`KS{u{avgm%IsxT6&0et7)u=#2(+rXKvsjDoSlQMSZ7E9 znt58)!_VTuC?M>aWks-RM13$@qA*`je^)ET@^c7W+V~`{JE$=vGS`6N~VVq5X!nq<0i)>ZlEDFhu9EV_O0_?NbSG)kDu6T(iZP1Hi=+E zOitRJMU+8y0Po%?xrmO024AvL_t({|LP1a0w_k6QkDh?LrGB>QQBvvVG9;0 z9?gQh8!m2|3l$`lnA(X%6vF$M0~!=$$cs231C>gNP(#@eRM{FbhNw-zguYNV^Gb8R z81?iwn=d83WqZ7kkEIyw4QM&u^A8vD{T`GvxEAXKbTV?u%5JZzd9EmBTfkD`3hj5H zA15&{{g&69Bt|x|hSl$J^~HIT9FbB;V-!%loh8v6qUMxU@5@|+Ny{&G2GU#|y6ENw zd-cEUTBsO`4)sKfu*i-}PKdu(JB1acuGkrDxxh(zPr z@DwBXV=R6Yj72{+WR@I2r9daGgTuAsr=p*_K=Or1Q4Pldr;?O%b=f^M&NuG9|IUtN#)ee-t2_OD&1`T=bwPw0e85 zH3`H${Od~u+2R(Kz5j$zQCt^NAZe_I^Q%%JE@0vPU7sxQ`>T6l= zSQt^81bnF>k){FV0;49v9rV5o4lH}JKV7(Rpcj+Xr}SDld<8tI4-53v!kZW9Z`szO zf`cB@g~~6z27N&uv;_^7qeTneUkGDaL%g%ZJ(~o@VEPf>q#hmzJ%}LnxHj`SN)=MP z668XEKVV1PNpKTF3Sbe}I$VC;4aZs`5qPae7AhXfY&{$)Asl5X%8YOpA*Ck5CDFl= zbEiiuu-IFqK#Us-&?rS65zULv$W{!{*vVN%a$+gv_i`F!ls!%pfY649uq8lMVJtI| ziZGLSQ34T*dL_0BA@WW_N|>MoQdocg>c@(A1GC^-$i{o9@ZOz5RV>j&Z`n&@t~xeJ!)FgiGlI4 zs3PtCS^)UMeq89u5Rd!6borNjBXw#~i;IbGP--BTySsf}Spd}@cjf_~FEikn{qLEYd@yD2PArvlmM@)K&3ji74h%;}?f zZ>lUALkADa?&{#PT>mO@vXGMJzn5< z&}%o2KnGcAmkvZiu6W5F zOJEQtMO5^)+}e@S5@@#tChR{Wf>9_`h!741M^0~3#Oy2y^IAyNbAvNSLb~vC896>=(a4%O%WtD!7O4 z$_4gGdV4CiMRjz98uOs2NRh%XCD#sLqQEQ`LvuhPbzv+~!33#0=p7;;#X?z6$jwbC zBIG&%pL%*M{Lwz!7w@NFq7K5YK!OJZQdUmQBtcjl`K?`r=zrDDRE#(JdX0J|`mGOS z)!qZWlxUZf+|SLy(}f(gf9q;*wXl$97gRz0a@o?@v*}^=doi*O-{_tz{we-p`40Yq8%{vQT+nZ%B)HHg&wgn?He{;d(g}}^nZob(UmwUmR zxi7JP!*<$Jf66-?&u;8rTOzNQue%HupeSrZ_KfVxZ5R( z{W3Hi+3SJ+M>(HO(U5%$r@UEWY{`Pf0>RyNYfhDxC{3)cS+EbQNO~p#kye7|*f;Dh z4l5n`jY2~to!G%OM>eXMgSbD~3rBuX&mP9&{BqK;MJjF%8rY-lc_Lp%qNT>02XDzs z3&7a>%|V$0$S#VlWQss&7hZQ>c6BtWhzcN&uof*~PO^4#r;u0|;_pvJ2`pACSTKge zy(N3g-3#HZ;Kc!QBbn8m(^INCGFUxXGkxEe@U{Ha_qaNwPe@=xL&&`0YwVB^^Id4lp30C z@s)0oKU?zo{nVA*yWVPLhqe1;#IHmR3)&qB z-+8i_Bb%PkiiS_JVmcR4K@e$ z(`!?QcZP+QxWZ`3_nu|4hfVW%uM57ukQJ8AhCT_4p$ACW(+k!)--Y?n$ACnam){Gv z{iC}(3Q&i3dK$ca*;fVh*#KEcRhr9R2*^G{`Z&%&FRGzrszR)Gvw}i)Q>2UX3}%d+n!CWaDhKdtp7&Yo`#45n*}hmCmxR#@kFm>I)auJS~f@p zZ4D%0p_P|3d10VF1(y5}j6E70bZY))X{5~~r|jv%s`dcyiNQRyCibpksYsc7p-1uA zbXr(fSuA6Sx)O`jV=ryQK3Kb8jy{kybm%NZPQRBrtYw11 zW!$~X4asL2GhVpM{gMk|Tu9FsgmRx9UD)CUDSXkWbdW#K04mq|3TgR=U9I(%#=Cl?-|@e}5S`7nGy> zvAuEOG8d%O4CxbNvkPDQ>BU@IMRW0QXGP2lPZYPy-?8Zg!2t8o(w&E}G|ef0_UxHG zF;b)}U7&QRxIefD%*WOg>`}nqBcBl0Q+8InLY)&DptbNJ%C?0O=#mE=8?k-1Etg7+(?lhN9Rfi4W*{G_{3cmWuD*w}ksk-B@6#DQ_7gPVvqOCxA;tNpu6fg23NB9Y#8 zZ}~=>{r7%|sfF6}iL=98WBuWJ(|`SrrF~qTKv<;f_7-5; z|Jw^E?1Mq6!K}NU0CCLQL77tLB#ic68+@7X!SKt4KwBV2`;0%-hI(OamOu^3V&RMX z!ygsj_K^N_FAa3ZUX?2VvP-EX(K_Z*y`&O*L$b$n8sdE!$ou5_#l`lf)kJvvLhc@q z=Qw2<&rt!-6H=-d#zv24`W<|HbT@XlyV?h|pZ*YZ z!GSROh4Lhg$9qx#uL4DoS`ULu2Kn)h{XFR`yg3-c$9;9WbJ*@YWfVgYk}M8hnyYJZ zV^~TjdtRSf&Y^uXE*I(VJCVGV9rkHk#MOKJ}IK=5A%M^nI1|C17V2f`JeOc z?m;J|mA~&R>-{H&lp)0p7-m2x%N}JI7GiUWO%q8x41pciw8Y$40LmUHUvSL_ufK6@{+M0${cR=(gWC+`ZFkL8}LWC?_xa(K7aAI*mHM{3vbfO^@ zC^iH~jO}kEK9yI;Rs(x#Z@wBx!(}RAZhQzuh|Qk8TwoM@68O*oJbUzRApP^rJyc*( zdR_t)^%2=cZoOX zXz%8*#4r!$5Ta#2E(FNlY<$7C_IG^>xoPS4w`DCUkd#($1*I%Z^AbIj>e)PT4rYgC zyMz6Db?&n(|GOyv|G)kwUkmvnyUGU!(=yjdY0xcdBb%Xn%*KmmI#Y74z6-s*_b-6D?O#1dR#1fXCbt&>i_=>C|ox45Bl=g4lwg2Aty-9;T0y-?(m(Ftr zeE+P7G%41840+MSGWD=eSJlFoFGvB3UN|H5=PuOi$owI9NY9t8@GfyvT(B#{e$(*L zLIv_S?b;Vb%$YF5w}!u$&7E^HSOnLf+M+NO(`%sT0$Kzm4ZkRmQY9{E|8bc=e?zaH zv>AFF{$Gl{g?8y4eVLQ2p?uGeu)k}LbQj;~Ql?`V1+%o$#cq>WyDnhZCv-(rELI)b zD>ty$=3hxlY7aK-r3Wes?U(R6*Uqvj$m6)?EBZgg2I^_mPg#9?T#wKEqXpmco$RAT zPUUO6BO+9y5fF_~nse$bA)dl~La`$S1>m}fOa2#JpW0gIX>Y(mgE`W&dH4Sw(cQOv zANTdY1jxdyMlapeu<6c1)P1A%30_M#R(`4^OfexC-hbRe@B*#uUARAcSQ2ib3lP81 zHGM(wmn*B~HpN{O`MH0bui~O_mz?^VaQrnF~TN9H@MAufvOI`Ok%q3NG!#r-Q$r;!86S11R!G z`s|Ja%sVaOv?mhC9A7Ub_PJ{yW1sl7v=*BCyih%Z?|U%Feyb{4AI1(n9-3TeL3Y=| zn)PvDpx41dkeP3zaRH?!L(4zuRYZ91zYV`vk;&E$6oz)TmZ?8TXHD(Qbf^`?{h!r8F2aI zPx|W1>1fI=E18RRxt=pb!-_7r?RUUI_>}bQlc3W7FJH7^UbaY&l=dd|{&wY}mCt0M Z|2N>k3xpo~ZzBKz002ovPDHLkV1mszSQr2R literal 0 HcmV?d00001 diff --git a/bip-0324/packet_encoding_test_vectors.csv b/bip-0324/packet_encoding_test_vectors.csv new file mode 100644 index 0000000000..519b77a925 --- /dev/null +++ b/bip-0324/packet_encoding_test_vectors.csv @@ -0,0 +1,8 @@ +in_idx,in_priv_ours,in_ellswift_ours,in_ellswift_theirs,in_initiating,in_content,in_multiply,in_aad,in_ignore,mid_x_ours,mid_x_shared,mid_shared_secret,mid_initiator_l,mid_initiator_p,mid_responder_l,mid_responder_p,mid_send_garbage_terminator,mid_recv_garbage_terminator,mid_session_id,out_ciphertext,out_ciphertext_endswith +1,e79f04ad4c684525ff3e3cf7c19f4cdb11193d387d7f3fe82a948a0c3165f5fe,4eff53ea1945e57b5d170565e760d771e5d496101c1005c302fd687af80d8b858c5a681c474fc4c0546ee464a1b95899ecb9d4f50c2c0854fe029fc054ae6777,824a1da0530fa695b95b375fee2a56ec96ce375ddd2fcf8367cc8ec1c0b751a3304bbef5dc96543acaac50c24be8cb39906ef8521727de0c6e96c2060a026bd7,1,1f,1,,0,b63341693587b4944b865485cffcc34707b3e0760a6ba8d1d402fc1c996c4e91,961fa6c9491bde887a6e67898c9335579d1931b435af16d969f3c9f12e58c698,05ac09c882b2cddd57fd4a1a14f93ae78d78a2ab2adb8cb6d67176cdb3101e15,c845747c92a2f0d83058ccceee69322cfd84cf3b086c30790f2a8789b303defc,3d0c55fa080de10236da830c7b092f63f6897c5243259adcedc4288a847ee9bc,f32949925481a88ad5246c408aeb8b9c0dc5dbc21fd6e5484331e1c0cd0ef6d6,5b94f3fce2b276e9d7ef5646657e61dbbc8ea27a9bf531ce23c553de1fdfd27d,38d7b65a6d58a08b2506e799caacd4f6,d6156094782d98fa27f37758dcd0677f,4418cf03c0d7cd5849022a7976014f234b4d4f5c18a6d3a6540c11e01a7180c1,d88ea86cdd6b61592e038741b474eeef0de0802412, +999,53a915e6d8f6c5bbb93e537081085e9e642dc525649acf05be74e3a825e20921,715d7b8357dd4d15a07b3f8c6764ebd9927140f75047fb50478c33ea8889d710511cdf39aa0fd6b1e94ea660d87f9d97bffc548646f9e2aaebc1468fe563fb97,cea7abc3112397b894bd3e89a615248af473f897bbdd30997c20e53e7ce499a295e55c4c5655cd3d21191e76c8af0aa1bbea10fd1b540a42d0fbed388dc59877,0,e4,1,,0,533bbaefc711f303be5e8271fdecfd31d03abd42128ff73479e2a427059e4a74,ed679745127d32714ff84bcce7651a14b9f275bf4b18bc8e880ff51cd7ac012b,08cbe6a86ff92a9757b2aeea92b8b2f4d78426786a2caec99c3cc73d7dda47ab,953a372f0d3933afef342fec533fa4fed644cc1cbc9252d31883e10fbca9b81a,e8c1759d865d59f37e5cf0404296fb0530f0fc601ad783853791e5459ca7f135,52925c95091e7dac8e580e9a0548e18915e01919a416c5aac22096b8bab17c31,ba778684047d705839590c466daef7c0ac53a3f8790b9744f154712e5644c647,0442c66254045c5018d828d42afaa69f,930c6d7cbf8c7c2006ed287c2ba6d941,9619dd4731d6160617da82da407c80732455a67b59ad7be07f86252aadb79440,0d5892533b0453c777d5ff3f217c94297e7927bb45, +0,dcf45714d450a32cdd05997b75acd34e8786969dfcff34295c287a13ba3225f0,feaa1ef8bb05296a8d5153855357868835fc5bc59d96dcbccb108e0e2dd671676c5683ad566ee4290ede5236ba6259ab47668e25853d64c0678641d27d5d0eed,c8067851ccc5df7331e9f137e66ebce1220306c4644266ff3e38436a1036ea36582dac8ce2c30de59a890f81611f866f659c1334bdd82cce1ea20ab0128b7f56,1,d3ed40688778a439928b38f1f67e04afb94843625ce1932590fe0606fcabffad25df7d2476214dc1d06aa368a4dc1e6d940a974307836e291c54f6948623ce,1,3c208efa88a545dbd29d71bbf41268fe3d123eac7e20e92be7f227b93166ee3cfd2f26639b27f20513ec5fe25c4e762096b3e49c29110a5b0d170eb9292e1ecdd3d3bab3660f9970811330d6a0f7112709666bb9d3443c9f35a84e7bde9bf2b5e29b903c64e86aca86bb5799fcf6a7416f48d98668749852c49e4cb2f3325c44d63995cea48af98bb42bcf4fbe03681bb552cf5d51b424bd53f1ffb6d6cb70af606debbe07124aeb14b28f2b26e63f3421c6ac512d5cdb7f97540f2ae64487d84dc57fb8c97f5785b60bcf12a22225988007c4dcc8895301a6e36c59f3a33ab5fa099945b1dd4d6e0a3822ffea087b01f9fb27b38c7711211c523b0e153422a5e06c8200ed45560ed4eb1317b7b730b5d31096bd3ac5cfc1e876a178851d297bec38b7a753013d7590533b5f6d654add3b38ca046d932d9739a5f0fbe6cda89cc97597a046d08b66fde7533fcb0528562960832f623dadbbe35d2d54ff15e1a9a260477169e2d8a95ec66e6ed8ccc2366f5ded2fddc2b351d6475c4b3831b6dd5c330917ea1b0b229ce719b5bd6d839861e5374f51a176b500e7546a2b4b1325be9615305d591605783279a73f28b9a281b17a45bb79029a30bf3c0b248945f4523979bbb57d69df4881d8030a4146080dbf13255b712919fb4fa016c66dd323d7a5c56b3ceeb57c4120fd554719a3851b9f3e810c4ad35b141ebff6b7c7038fdfa784681f20dcf99773721d4ec07e58a312d638fa7a90c1afbb282f30ea74d7002288441c93263eebb593f2b36cf795a8a0ee7cc119d28caa13332fdb6f2f5a6011e26e1f33941fa275d2d75af014c7739b9a999f018c7c96b854332225cb9104c016f94ff255191ab93df7c1ac29e566d672e8ccb1a4b1f53f201d583da6c410df98fc502f3b366d7624cd812cb9dedce92329b6e591366bb83c7b84c1fb30301f0199ee9ec727a33d3a9a0382af1fcf1f42e945a5acf1ea8db30a03856b8d4e0361c08028bcfc05c5204fd508e67b9924600526a1f297efd091e3a0bdc6de5a46229792069c08af9b7961ec890a3ecd6af6b08ae08f3892084a8224dd5ac50b99a7034ba48b6f599ab3e3f9fe30734229558694b8e3091161f8bd425cc2e63635c1ff82e6b6b6c89d3ea4a0dc4193b80e6014f87571bc8499107576a910f0aa50d471fb35fa07dfd0488a404ef9907ee767b1f3786415561c445e0487feed348da527bd5e8adad8de928159fb32cfac4430f51dcf710507baedf326597d8039cbecd07e9cde781d0e307d589d52b5ac262a69b366541efc78e9398dc69345f00004268c9c6ae079f09aa4e4afb830ae35715623451ee2520ef201cb5885030aec9a24d9968f8c6f25d234c69cb2f569ae2a91029b6401110fed798b2289de1e7e8621dcbe466a2fef44f09176e252dae6707ecc35695a156f6b97ab4cbaabd325fd8eb941248490824f2520f49aae6eaab95a1cf92c061c57c90910873f1866b8763b78f90b2b737020527ad16c33938ab438f0eb7845a034aec20253e71ab717c4243dbcc084f4b09a87ceeb8ef124755ac8802a66b02cf9396a700a661e16b418cf838ea1262935bb7bdeec1648f0cacb1c3236ec1856d93f172c5a9a938246606db326336425c27e2adfa428f347b9f7aa4cf1648dd4e7e66f5e8a858d499c95dc2092a0a9c8b80a05c93bd359ba5b1acc714be5a1c26be118abe8abafce45d0b9bb668a8204fccf166bb85ce17f70330c0c8ca8dc7394beee22a52624558b69b81e223c779447ee09d822dc44226432a0c86f9b25e7d85a98e187d879a4ddeeb2463d12bce3eb137e227d41e2a3df55dad1219cf18129dd23ad50930286b732037cbe7d474d06ae9f7d93f7285d2db44a8e72011460e3d34381bfe6d3221f49915312d00a5a2c7ef98ab829c995081abf9dc5551f472f34f9b39607b8e55bdb047e68582d27d2582afb9a07549c7a134a34f7d0e5a1a046cb2c3959feb98fe7a698291a2defa5fbb32473b9c9ed02d02284559325e12cda1bf0bc24ea9849fc4c87eaed71f2537242b8635fdc969872b1017d218943647fca47f9430af3b78ae2c39882118612c288d474b0298de3c3ec1efd23c65554f6d6813b4ccbf604250d295f795b679fe0ecceef5b4739eb6b418376d2fd47f95685a259cd2e2e7c00c18e93329a80a467a2a0aeb22e361732c943beb0c3dc7ca57699b690d26e6314d0b28082f8f26894c249d1587b8895dd1c5e8863bbe31cdebbce06b1d6aa17f64a125f4cbad47f2e02761259973ea164b22a580d74413d900023f03d2b2587bca60501f639050262b61a67bec83246d6ec7726f5a8a62d99c582a159db6a539ae88732f8d101d324550c9fa2dd9ba60c449d329cba823ec4b3d80d613d8df5256b3ce6ffec42ab23e5e27c001aec29d080fb519a6cce5b974f65375870c22577a2f6e76760870de047ff65dca90bfd6a303b4605b6f90631d57a8f66969ec7b96749c1f1a4ee70e8915396e114100fde651700416239d82ce7e32be5f20e5886510a37b3cd3eefe78c40ccb0425f03bcaab1aa9eeffa2f4681b7938a813f49f10a34c280de09345ffe00af340a451ebdae630ddade51a6510fdda44c3fcacfaf3f2f748d8bfe48ff71871eaec9b1790df27d4ae913d1ad16b0b33a04266540a49cb5acb8d2e16df7a35933bba7c5af1ac1f522419e76c58cddee219cf5d3229d5a27af4411ae890b4329ae5699820766b0d73841baddc11c24802684c7f7c738bf4843595dd508850b69dbd38671a385ea39188a04e7b489daabf860f4747a7172cb72a578b9903ce161e7b8a7f31ea7e8630f97571bae93f51186b94cf3c697839a6dcb2f53de9893e53a7bc2f94c9a33b2dd112cdae81f60019b7c20aa7c4921f72492329afb8841a4c80a42d1a12fcc09cf7094cadf6a48ffd6f200bd64ec17906cf4ceda6f10313bdc9ce23eba2d8d8bdba728fac90321b4893a0a61e443f611ce16486aa477ed59ccd27b58bf01a5d6d396ffa249c0728eaf87f1c41dd56c7cbc1491b369aec1a576e286fceb37746891aa37da87fa77db443bbc2df63c589f928532c6e8f4e6e3186441dca4c7118d1bfdd0a1e24087837d7dabff8d64f7df1d4cd1628eb312d6c631f092ac0172642de2f2c3c1a71573de41d2165b8f3164db59070593d8c16dd6c161303a6523a33da328fd88929e434da4d102c0ef7303eafeb6a0c3583f74bc277ae1fac36efe68b98af3340a766b0ddb61e268f3dfdc6d858a90aab491e00e010ef195bbe12435a6f225395a1c3d0ba05a094cb2c6610353fb5bdda198c6c6a1564ddf21ab51b2e13e735969d109acf4ff05ac0071d018e98b42b18692ff2dff6bb1fdc6aa630d2a978b652fa6944fbf693a251db943e10cdabfd7e26276ef16844024432286400d36d15c6acf43cb6247c6316b0729ad2a465ed215a97c937e9f9a405ae9f520d91a198cd18077e7d6134f268741b73c6ad16d1e2164102e8bd276237599ff5811837faa0b1b4ac6b61092c14da64ee83904d62c57d336b80f4476f5a9fa6f0ce6ba6b34454906bf5af60b5e42170bc358bb90927c20f753b8d69d80e5aff23daee4727bdf16e01cb549783816b9a066ade19c26bf2e30aad9f3faf35c5e17c81062f53fdb9f57c2608f6c638f0f2e8c071581107bba371eb0cfec67bd823c3d892d21d14e65b366343839bddb2b7da0d7af7e7b3b927c4d71441ecbf14f5276d0da11cf33723a10fbf1e5a97b1f95072de9872932d7bfc200080043cec2dbf2f0840be85933d8f0cb6862316d1dc18292b90b8a583df01464fe1d6a4720ea361ff2280398df7008023f364989692c86bd2ceb94e466febe2fae6bb2635c1cfcdde45c4d3b6ff55106a432a64e6827f52cc0a25f4581a058c962e99ee9b3ca2c10e32eb93729690b3066d9b9343be9863faaa0599b99daddb2e53704002cc3dc09d5df8f3bb783b37e3ef85f01b272d84073576352428720ee08b9bc527020413346c0bb7f7040fd9b149197bdc4988eebc4e012e73d75bc4f4d2d2a3cc30dae96836c590e5a5976f0392102e1c592da1fd373be252fc3b0d34a6dec22725dd697ac55d4d50e07ccba88f70a44b75abb5dfececacb1b5483760e5d40b84255455fdb93faecbc24ae3b30d73311d6afd5fbad5b6e61e64530e7645cc43adc3053a40d6fc0e63d6c664df163f197d2d3efbb5a5abcf4a7ad69d07bb866876fc22d9c7a2fe529260153283cdbe1fc5768d625ad09a9bdb60442a744d22a827264d2722baae4549097f745bcf0de7f21c80951cc5ed8a48e4099663dbf6ac1f995e7ab3d6c8fe2c3e817e13b26741f2a7f33bad56bb002ebf0c69282dc763e1e9cb44bc0a0814170116d2dc16fdf1e08158fc571c5a5285242ab6376f9c213953e3a0a315eff722831cc27e426b0fe299fb325933ba9631be00ffd51f7bb3d13d962f5b6a0a01ad0c60455993699b9ec594cb749c82c870dc443c7466db518e4a5ebc7c530539ae48bea63d77c0e175d673edff001511bbdbddf30f2c231cba0565f043aa52c584fc05069728a95e040893d4e9c6c8d3b7bae906be38b9e1480f8e4665f157f4b347be01d1c355c94576b32a335864f6cd341857a696fe5f8af10a4ae87246cd119d33205bb969009655e36db394f750382fd58648aee80179bb3f1df7f291b4de27edf056c3968aca546e0e81d131b3fb52ae8b3fdedf297289420c4aa1aa74560aae150f623e120b08592c0304dbf7ff2e432e737227ac1e7e9e65485b30d058b30f81807a18fba48822baaf2e7ec6c88a604495a000e62340273db9079c2a7123a8a197b63d9616e7e9ebef572ba3efec09fb038a57adceffeffcbbb6c4e0e9bd73c1d1e82d26d39bda2420a45fb2463218b2988b5fbd316b3f4e81e7b0728d700637333fe5448b395e384169c4bfc57ff6062c962ac4f13e66cd5b6166a7a049b6459291d2d2a632d749060d8070b9e2db3159db8047e8024bc12c92562c7b4ee953b426c551d1b9064551833c758683693a57e724bed8a5c05e55d8e5f27d22b4adc246116747f23cc8ec35b51148168cd27dfb8a466cb8f4b1980209735694e411184875da7254a2ff850a73377c1f9f0b87f808b76a9f0882231fcc4446ed01c9876edf92fc505040583d9ccd0fcaf3935f215dd45022a9464835a505022cdd54de634fe207b5e202f7bcad463e00312952d3d4b421cc77be0cac587426f0239b8d3d94c0c24141b10cc8ab33aa655388fa5a323016e7a1fe2470d4dad92cb19acf779ce1c48f64bf588c99a766010252b983edcd4725ff16c15683bd7be62323c39405358358fcff306182a3a147c025dc91801258f4d71e1888b0a19f4e52a8c5885cc99474e94448c0081d1ce2a7110e1a6c7e23184cd76a44c806b0f1ea3de321cfdf8569dd35221e9ab1ccbcf6dee81cc611d0731226228d71e98abf05a0db761bf6807d4c0400a39835f33b144f85ddcdee7945e63027d3cd25d44b7e9fdda2548284497af9b57dc72b3e026d49e86950b434fc9a9713f5be858500b54614d5d4c79186289d744fa0df3d655f9fb79ec60f49dc72eea538515b53f74c578f9d4ffc9e79063e19f3a38d9dde42f7c3910ac5ca16f60afefcccd4a49b1d93032b7e82189caebd2993991f7f4f1610d3b7cd4b8dbf895523b28d0a3e672232412145649b1a28570d9c114a851f10e6761f52ade202167d94fb69135f3d2932849a85267b998a23f6c6229697e0098097cb6a6dc4f84cff4c7da997d5631b694,0,d23f19ad26c7ab984c682c5b1475f5a7df0452a05dd29a164974d2027a6e488a,6f8420ebf786ee13dcf65855b11428db43061cb599e6fe9ed79e59d9f273dc44,33a1ef8464def100bf031dae882ae4b7837b481f6adbc63c44baa8ef61c102eb,8edefd89c5ddb77db6333981740b83fd4d9c246639e0dcfd1ea2a26d4a26f508,6b0aae6192e7a92c7a3b5de8ab1349d26637b17e500da162cf25df13c85d35df,87a8da66207605720c64d5267b5ce90becb01248a60808a921c5eff59013d59f,e9292dc44be3294db04cf689a3141bbe0d0dbaca2dd8d8fb606a45b8d7d8e089,57b8c1343aea943714ff848970b2a89b,ce7988ab7ce5c93b89328ff815ae803b,a306c86bea9e6befa7f72bd5cde761d5f4f86cfbc8749c1e844100c540a6cefc,a844ddeb465f302c4b408a6ab972d4ff4035109bc25fb8fe88d4892bccefc238cf93e5a61459f9c0cb4877cb03967d592c5d8dc6d4c4b5f489005a645b2f7a2ee368749f0b172b9ddbcaa76f20485a272b2347, +255,f360308206fb441c7713b1a24ba4096a2fa0d5401411198b7008f82ae85257fe,3d4aa6a71a8a734e014b4d9e6b62989f022c1e2238ae476b11465cb86fe8cf7243db6f9472e188590705cf9b35121e06e57cb106a6043ab147b7c73871da8222,f0ebc3c872339622fbf2ab1b8aa2117c4d752b64eac9203962c03a47497a89c0dd298348e5bb63d3433c48ed6da6bc2e2dbe78f7b91247dd29f1f51a858d464a,0,b766200432932708a77dd15337bf70ca58397907a1cd31ecd1b43fab27fa0de0e85d5c4dea99543e79a75b149d325044934efccf679a764f683b2fbcb7c6dc4baea9797554779aff937f5195c172892c38dc423bc809885e5a19d07733e7c5f5806ffb865074cf2c46fbb5be4f9b5833c6829b8217ccb301dad7cb49e4fbcad1,1,,1,29bf8fe2cbd12835d3e6652840b8b1a2acf99d7b44610e738aafd7fd207c9b25,8f088a98122e3ffae5fee255fbfdf653a1f830f85dfe595707a1f4a7f74dab76,07eff272cd331aeb14db342b82f6df98303b01471f4dbe71028b127577216d9b,74ee2a5f9221cb386e587ac9a0c724bc6f65ea04cf3b0686c10b3e39e66bca02,35d93b912c54f3d28f834ee96a787f76f84b543fc231a45242fa4953b89cfc9f,70c4abb811bb6c209c6f108be383f67c8a14cd2dd25815f6156e6c3edd7d1e3d,3a16c6f3ff6f2b735b89d2af77c94b9dd328f5330e1283627835d32c5c856446,e09f7df050a3f76bc8d5a21697fefb9b,b8951fd528743d2e8625de363d9ae0e7,b1d1e3ae7d9337f31a410986fe6e377726eb0f2334f24d66b38ec4d29529d1a5,98178b6e498f808c90b098c8ceb09c5630d50925323d051d379adb85be9e3b7d3e5a4c0eafa3fb69abcf60e631262278395c4ec017b1a2c8b4aa6a25e65afa99ea3e73038d152b392b2f754a655f3fd034fd633e7889072c3e1351bff97494a6737785a00016c294e0f62219eb6becfcd14e5f81841118275a460780178b050615ab02e56efc0c777844620ba3de42bb54674842, +512,073f53403256e2b699e32cd4cebadfab63d9076a7cd541d9656e27b1baff66bb,5c9c90c4e216f8a4c2642535d1f699364f9054ca01bca0239fa65bcaf0ec0278e5a36bc85eae96850feff889b66c9106c170fe655f973f533ee3557bd3cb6e64,e9221c9698cb69b63c5a4e224132389d346fd2f0f3262218301be51687b8de846c652ea8aa7425a5c08a7bd52078168d28ecf42196e33e155e215553ce6aee83,1,196391ebfe9af3a9186d82692a00e485d6653c8408050e2efbfd864642860022af68053ee4230f69ea565fee775778bc231307b5b534545878f864364bb2690acc9e8991fed5a777eb2850c3c54cca94a5bc2cb92729bcd4e27c57ebddbdf14974030115bc5a8a600b207a4884f568d6a9d3d9367977410577674601d1cc5f1f672f4e54d4944e1f7807416159eb5ece5b805c8a23e6735351a8cf8de654d87228ba21baf815190ef026b29612498121fe85480d9e0050d4781fa9f0e60cab5195,1,,0,0ce4860107efd6deb9e8fc71cfc2522b4a5a0dc171746fb995ce485570449ab5,d87966cc3cbdcc14ce06a1ef6c28125cec3136647a499d4b4465c925a5f85efd,88cf0eb49ee4b7b46cd39fb3f4126b285750d897fdcba72b08d9da351167e227,df6857d7fbb822069d3f284973cdc6677a539d81844247ca2ac174b818623550,4f1c0b4b834681298ef127067369747074e571c68fc69966f3ad20673f786b82,5b9aa4239daed582b04d316f0550fdf1efc5309544349b01d62ea4f045e3425f,0c1d30189bf24a5032a93add5335fcbf351b2071870fd1626b66e23be99e1df5,ece7e13c65def883efc1f0dac6d55974,efca4cefee7a95602ebab090875e4212,afde967955012c17bfa7bea218bff3aa1aef10a49139c66080e9e7c567706409,5400e5add3682ea8c5587dbaec8867c54b7dc97e07533db32b5f68ff9eeccf68db30c5013b276374e1b60dd417df516e375a995b45811817b326c6bfbaaec589d82415bc48bc8f1eee5b9ff430b486cc951752e943dccef384a66bc6d906c7f0e839772ffce47928bb73a8f828ac82dca6f8f4f8340f11f4ef849575fd16ed32e5d450249b89004164918fe739a83f2b5dae04f7a8ae32682779f65edaef9c80090f581c7d9000cef48bed0089b5eb8767cc963ee2bda2d00716a463ee5413036bd2a055c0f5e3f72791e0526ac5e35bd269b71117, +769,810159fc6708a85aa9d6c8e7c4f8c587056594910174c0309b2c323055efaa6a,2a875927b98fd441d8c469f6902c167eb440e52d3331a4b7406f21cad216e80917401ddb8795a9706fe42a7ddfca70fee7240b1e918b9f32414b8b26e611d571,758bcf0381c0a1c35a174503a43b08f79eb407aa61eb9e6579a62400d4a13f8d3cef884728c34cb79c7f088b4d4e735ce796361e71bd8b66d637f56326b49af3,0,0f492bc40bc635ca20a46c6fd97b7de536f8326e677e0dcf9ed91e4c7873ec903198010f7cf0ff1595,97561,,0,27cdbeb6c8ef5f97982a7af00018a16ba243176fe6bb5d5c30c8a466a0193a47,85bbb016a00056ffd3878b2a5cfac4352d581bfec5a0407f0733585513d4b463,17624a0ed455d13430bf27337e27a1d55402cb1c7ebb32a4a66b3ef2f9947f1d,aeb3befd6841f8ec867e154424b5c6d49ad3fc1f789e7d3048750302c5d89c09,80033fb9014f1a407e46d35cf36a7c4245e55e6a810abaaad88ec5d25f89443f,65b0f93ac2a34327a4aacf14c2c54d92210294b425c3b6bb4ced8c44dad80457,4893a9b0ec706fcc7a05c1fed011ced86afd7324c63537e49ec2974df481a83c,330b7aae0e4d13f5806bc1f696042155,d514d7861e65ced36c7ea6ad2a8f6938,2ad4f52fd2a9cd078c0664dc4ba33904095d4affb5227fbc779662ca6140376c,,c05bf91046901716cab14414ee73dbd7f17a6e4cf0bc3ba22e22d40198fbd1527726a99c006378ba3079e9da8dcc68ecd8a0a23a692eb775cf11d97e16847b3398e11ee1ddab092d6a994a7246802bb3140ecbd4d8495f36abb5aa3e0aa325f02b5be69e4ad546356c453003949ea9d2adfb169004fe37da65b247ffbf021e9109d6d090b224bd4f51b803955be2fd7fdd0e198f89d903deba9be904cd6d769bbd4f1b5b609be95a9b6db2c2a6fcff029899cea13196330a433277c96a069fa8b6590d921da84172adf1b23fb76eb6cec95f8bcd6b497777eb2b44dd15440f430d3f9ea8729ea5598df46b299cff81729d3fca241872e61b84945c70189189f5 +1024,f7c11ca3b55137fa6124c49b25dea0287815b887760e1b986497e976444eb5bb,5a2a0ce42feb17e70a96db1e55bc380e26a40a589dfc453d6c2e82bbc4c2b161716a05df9039ccffb6df45183480119deb69299e44d48e38de746ad084156edd,2c402d53332d914e4f5501c8db682bec6738ed53c7410655d9346db99bae37642beb6a1d48394502941965ea7140e1172ce591923235640f964c0d597caae304,1,bc5fdee9e87d05b9723871a35823f643cc53c400851686d69d87433028c19cc295ceea1513d8056021800c86d886f27f6018e4053121df4db5216bff17160f7b1bc4d3be67354f0551f55a353de5f15add353605e2a0761bb0c1b3bb8a37787e797e619ebf902a8ed4fcf1c741c897c8469cf54565b21c85e2b4fac5ef6e948f2c36df269f7189d1f293d2a95a08a1b9d00528521ff407ff992726712c8c9d6273a878d1700912ff2ef5b1b6899e9b88f6999bc628c8a390b37d9be99bd742e16a1eb83b0d1b8bfb6858e3fddb33ce2d9ef40afefd29833fd59dbc0aef25c35771b17d62595b5de9dc7426f1d976deea78,69615,,1,6d89eb9e87319fd088ee1e77fa5b36d2d2d9e66fae8d11ab7bd70407d4aaba29,0b6c87c76983e5c84428bd646d24c133d9321af5f7cb4624ca1524bcab828ffd,2a4d8d7ab2d2e92c429c8c4cb0d78f0f170a244410d588b92c7fd8baf7c27e59,001f5a1254d1734551f7895221f370aa5eb2ea382dfefd586941becac178d8a2,acf0ffecff0851e065af2a149f1c0a0db21c8a885613ebd1c445957b56c3d705,42b3699eec52f5f4648bdb40c25c956944f0a3e9986552917a3498078a8de907,a721aa5cf8d2b4ce9f46f20693438d94f75130585b6ab137894b273a436c90d4,a5e8c7130b7b8cb34e303bc3da911230,0169b4c927c5a809bd3b0981887e7e0b,462c77437e78cb8620e0572e5a401d151e6ae45aed57d7638d924f569eccd73e,,d3a1508bf5455510d63279ef808f8eb5979b2793e481990f489046adbf9eb4247384912949eb8a9800fee8a3b25c7f3771a426b60b5ce40a60df4e7399ca9069f5833addad5f62dfff9171a964211489855b5aaef2f227b63d75e3d07b4ea9fc068b35497f70a7b708f1af662f435282ededcc0e20e38003733cf52703343f40f390b2cc38d10a8ea82434f2126ec841f67f54660f6ece22ae874a3a2c880e78dc87fbfbbcafa4bff042e78668855584386a11349a64e2018e8ca3857439345d1368998e3bc4995ece49634a75786c6ec06914181d35153fa29af610dc8db16531e601d8bba061accbf2c49ac567769d5c1b0607d71ecb34642d75b51bdb6776 diff --git a/bip-0324/reference.py b/bip-0324/reference.py new file mode 100644 index 0000000000..e07731b3a4 --- /dev/null +++ b/bip-0324/reference.py @@ -0,0 +1,575 @@ +import sys +import random +import hashlib +import hmac + +### BIP-340 tagged hash + +def TaggedHash(tag, data): + """Compute BIP-340 tagged hash with specified tag string of data.""" + ss = hashlib.sha256(tag.encode('utf-8')).digest() + ss += ss + ss += data + return hashlib.sha256(ss).digest() + +### HKDF-SHA256 + +def hmac_sha256(key, data): + """Compute HMAC-SHA256 from specified byte arrays key and data.""" + return hmac.new(key, data, hashlib.sha256).digest() + +def hkdf_sha256(length, ikm, salt, info): + """Derive a key using HKDF-SHA256.""" + if len(salt) == 0: + salt = bytes([0] * 32) + prk = hmac_sha256(salt, ikm) + t = b"" + okm = b"" + for i in range((length + 32 - 1) // 32): + t = hmac_sha256(prk, t + info + bytes([i + 1])) + okm += t + return okm[:length] + +### secp256k1 field/group elements + +def modinv(a, n): + """Compute the modular inverse of a modulo n using the extended Euclidean + Algorithm. See https://en.wikipedia.org/wiki/Extended_Euclidean_algorithm#Modular_integers. + """ + a = a % n + if a == 0: + return 0 + if sys.hexversion >= 0x3080000: + # More efficient version available in Python 3.8. + return pow(a, -1, n) + t1, t2 = 0, 1 + r1, r2 = n, a + while r2 != 0: + q = r1 // r2 + t1, t2 = t2, t1 - q * t2 + r1, r2 = r2, r1 - q * r2 + if r1 > 1: + return None + if t1 < 0: + t1 += n + return t1 + +class FE: + """Objects of this class represent elements of the field GF(2**256 - 2**32 - 977). + + They are represented internally in numerator / denominator form, in order to delay inversions. + """ + + SIZE = 2**256 - 2**32 - 977 + + def __init__(self, a=0, b=1): + """Initialize an FE as a/b; both a and b can be ints or field elements.""" + if isinstance(b, FE): + if isinstance(a, FE): + self.num = (a.num * b.den) % FE.SIZE + self.den = (a.den * b.num) % FE.SIZE + else: + self.num = (a * b.den) % FE.SIZE + self.den = a.num + else: + b = b % FE.SIZE + assert b != 0 + if isinstance(a, FE): + self.num = a.num + self.den = (a.den * b) % FE.SIZE + else: + self.num = a % FE.SIZE + self.den = b + + def __add__(self, a): + """Compute the sum of two field elements (second may be int).""" + if isinstance(a, FE): + return FE(self.num * a.den + self.den * a.num, self.den * a.den) + else: + return FE(self.num + self.den * a, self.den) + + def __radd__(self, a): + """Compute the sum of an integer and a field element.""" + return FE(self.num + self.den * a, self.den) + + def __sub__(self, a): + """Compute the difference of two field elements (second may be int).""" + if isinstance(a, FE): + return FE(self.num * a.den - self.den * a.num, self.den * a.den) + else: + return FE(self.num - self.den * a, self.den) + + def __rsub__(self, a): + """Compute the difference between an integer and a field element.""" + return FE(self.den * a - self.num, self.den) + + def __mul__(self, a): + """Compute the product of two field elements (second may be int).""" + if isinstance(a, FE): + return FE(self.num * a.num, self.den * a.den) + else: + return FE(self.num * a, self.den) + + def __rmul__(self, a): + """Compute the product of an integer with a field element.""" + return FE(self.num * a, self.den) + + def __truediv__(self, a): + """Compute the ratio of two field elements (second may be int).""" + return FE(self, a) + + def __rtruediv__(self, a): + """Compute the ratio of an integer and a field element.""" + return FE(a, self) + + def __pow__(self, a): + """Raise a field element to a (positive) integer power.""" + return FE(pow(self.num, a, FE.SIZE), pow(self.den, a, FE.SIZE)) + + def __neg__(self): + """Negate a field element.""" + return FE(-self.num, self.den) + + def __int__(self): + """Convert a field element to an integer. The result is cached.""" + if self.den != 1: + self.num = (self.num * modinv(self.den, FE.SIZE)) % FE.SIZE + self.den = 1 + return self.num + + def sqrt(self): + """Compute the square root of a field element. + + Due to the fact that our modulus is of the form (p % 4) == 3, the Tonelli-Shanks + algorithm (https://en.wikipedia.org/wiki/Tonelli-Shanks_algorithm) is simply + raising the argument to the power (p + 3) / 4.""" + v = int(self) + s = pow(v, (FE.SIZE + 1) // 4, FE.SIZE) + if s**2 % FE.SIZE == v: + return FE(s) + return None + + def is_square(self): + """Determine if this field element has a square root.""" + # Compute the Jacobi symbol of (self / p). Since our modulus is prime, this + # is the same as the Legendre symbol, which determines quadratic residuosity. + # See https://en.wikipedia.org/wiki/Jacobi_symbol for the algorithm. + n, k, t = (self.num * self.den) % FE.SIZE, FE.SIZE, 0 + if n == 0: + return True + while n != 0: + while n & 1 == 0: + n >>= 1 + r = k & 7 + t ^= (r == 3 or r == 5) + n, k = k, n + t ^= (n & k & 3 == 3) + n = n % k + assert k == 1 + return not t + + def __eq__(self, a): + """Check whether two field elements are equal (second may be an int).""" + if isinstance(a, FE): + return (self.num * a.den - self.den * a.num) % FE.SIZE == 0 + else: + return (self.num - self.den * a) % FE.SIZE == 0 + + def to_bytes(self): + """Convert a field element to 32-byte big endian encoding.""" + return int(self).to_bytes(32, 'big') + + @staticmethod + def from_bytes(b): + """Convert a 32-byte big endian encoding of a field element to an FE.""" + v = int.from_bytes(b, 'big') + if v >= FE.SIZE: + return None + return FE(v) + +class GE: + """Objects of this class represent points (group elements) on the secp256k1 curve. + + The point at infinity is represented as None.""" + + ORDER = 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEBAAEDCE6AF48A03BBFD25E8CD0364141 + ORDER_HALF = ORDER // 2 + + def __init__(self, x, y): + """Initialize a group element with specified x and y coordinates (must be on curve).""" + fx = FE(x) + fy = FE(y) + assert fy**2 == fx**3 + 7 + self.x = fx + self.y = fy + + def double(self): + """Compute the double of a point.""" + l = 3 * self.x**2 / (2 * self.y) + x3 = l**2 - 2 * self.x + y3 = l * (self.x - x3) - self.y + return GE(x3, y3) + + def __add__(self, a): + """Add two points, or a point and infinity, together.""" + if a is None: + # Adding point at infinity + return self + if self.x != a.x: + # Adding distinct x coordinates + l = (a.y - self.y) / (a.x - self.x) + x3 = l**2 - self.x - a.x + y3 = l * (self.x - x3) - self.y + return GE(x3, y3) + elif self.y == a.y: + # Adding point to itself + return self.double() + else: + # Adding point to its negation + return None + + def __radd__(self, a): + """Add infinity to a point.""" + assert a is None + return self + + def __mul__(self, a): + """Multiply a point with an integer (scalar multiplication).""" + r = None + for i in range(a.bit_length() - 1, -1, -1): + if r is not None: + r = r.double() + if (a >> i) & 1: + r += self + return r + + def __rmul__(self, a): + """Multiply an integer with a point (scalar multiplication).""" + return self * a + + @staticmethod + def lift_x(x): + """Take an FE, and return the point with that as X coordinate, and square Y.""" + y = (FE(x)**3 + 7).sqrt() + if y is None: + return None + return GE(x, y) + + @staticmethod + def is_valid_x(x): + """Determine whether the provided field element is a valid X coordinate.""" + return (FE(x)**3 + 7).is_square() + +SECP256K1_G = GE( + 0x79BE667EF9DCBBAC55A06295CE870B07029BFCDB2DCE28D959F2815B16F81798, + 0x483ADA7726A3C4655DA4FBFC0E1108A8FD17B448A68554199C47D08FFB10D4B8) + +### ElligatorSwift + +# Precomputed constant square root of -3 modulo p. +MINUS_3_SQRT = FE(-3).sqrt() + +def xswiftec(u, t): + """Decode field elements (u, t) to an X coordinate on the curve.""" + if u == 0: + u = FE(1) + if t == 0: + t = FE(1) + if u**3 + t**2 + 7 == 0: + t = 2 * t + X = (u**3 + 7 - t**2) / (2 * t) + Y = (X + t) / (MINUS_3_SQRT * u) + for x in (u + 4 * Y**2, (-X / Y - u) / 2, (X / Y - u) / 2): + if GE.is_valid_x(x): + return x + assert False + +def xswiftec_inv(x, u, case): + """Given x and u, find t such that xswiftec(u, t) = x, or return None. + + Case selects which of the up to 8 results to return.""" + + if case & 2 == 0: + if GE.is_valid_x(-x - u): + return None + v = x if case & 1 == 0 else -x - u + s = -(u**3 + 7) / (u**2 + u*v + v**2) + else: + s = x - u + if s == 0: + return None + r = (-s * (4 * (u**3 + 7) + 3 * s * u**2)).sqrt() + if r is None: + return None + if case & 1: + if r == 0: + return None + r = -r + v = (-u + r / s) / 2 + w = s.sqrt() + if w is None: + return None + if case & 4: + w = -w + return w * (u * (MINUS_3_SQRT - 1) / 2 - v) + +def xelligatorswift(x): + """Given a field element X on the curve, find (u, t) that encode them.""" + while True: + u = FE(random.randrange(1, GE.ORDER)) + case = random.randrange(0, 8) + t = xswiftec_inv(x, u, case) + if t is not None: + return u, t + +def ellswift_create(): + """Generate a (privkey, ellswift_pubkey) pair.""" + priv = random.randrange(1, GE.ORDER) + u, t = xelligatorswift((priv * SECP256K1_G).x) + return priv.to_bytes(32, 'big'), u.to_bytes() + t.to_bytes() + +def ellswift_ecdh_xonly(pubkey_theirs, privkey): + """Compute X coordinate of shared ECDH point between elswift pubkey and privkey.""" + u = FE(int.from_bytes(pubkey_theirs[:32], 'big')) + t = FE(int.from_bytes(pubkey_theirs[32:], 'big')) + d = int.from_bytes(privkey, 'big') + return (d * GE.lift_x(xswiftec(u, t))).x.to_bytes() + +### Poly1305 + +class Poly1305: + """Class representing a running poly1305 computation.""" + MODULUS = 2**130 - 5 + + def __init__(self, key): + self.r = int.from_bytes(key[:16], 'little') & 0xffffffc0ffffffc0ffffffc0fffffff + self.s = int.from_bytes(key[16:], 'little') + self.acc = 0 + + def add(self, msg, length=None, pad=False): + """Add a message of any length. Input so far must be a multiple of 16 bytes.""" + length = len(msg) if length is None else length + for i in range((length + 15) // 16): + chunk = msg[i * 16:i * 16 + min(16, length - i * 16)] + val = int.from_bytes(chunk, 'little') + 256**(16 if pad else len(chunk)) + self.acc = (self.r * (self.acc + val)) % Poly1305.MODULUS + return self + + def tag(self): + """Compute the poly1305 tag.""" + return ((self.acc + self.s) & 0xffffffffffffffffffffffffffffffff).to_bytes(16, 'little') + +### ChaCha20 + +CHACHA20_INDICES = ( + (0, 4, 8, 12), (1, 5, 9, 13), (2, 6, 10, 14), (3, 7, 11, 15), + (0, 5, 10, 15), (1, 6, 11, 12), (2, 7, 8, 13), (3, 4, 9, 14) +) + +CHACHA20_CONSTANTS = (0x61707865, 0x3320646e, 0x79622d32, 0x6b206574) + +def rotl32(v, bits): + """Rotate the 32-bit value v left by bits bits.""" + return ((v << bits) & 0xffffffff) | (v >> (32 - bits)) + +def chacha20_doubleround(s): + """Apply a ChaCha20 double round to 16-element state array s. + + See https://cr.yp.to/chacha/chacha-20080128.pdf and https://tools.ietf.org/html/rfc8439 + """ + for a, b, c, d in CHACHA20_INDICES: + s[a] = (s[a] + s[b]) & 0xffffffff + s[d] = rotl32(s[d] ^ s[a], 16) + s[c] = (s[c] + s[d]) & 0xffffffff + s[b] = rotl32(s[b] ^ s[c], 12) + s[a] = (s[a] + s[b]) & 0xffffffff + s[d] = rotl32(s[d] ^ s[a], 8) + s[c] = (s[c] + s[d]) & 0xffffffff + s[b] = rotl32(s[b] ^ s[c], 7) + +def chacha20_block(key, nonce, cnt): + """Compute the 64-byte output of the ChaCha20 block function. + + Takes as input a 32-byte key, 12-byte nonce, and 32-bit integer counter. + """ + # Initial state. + init = [0 for _ in range(16)] + for i in range(4): + init[i] = CHACHA20_CONSTANTS[i] + for i in range(8): + init[4 + i] = int.from_bytes(key[4 * i:4 * (i+1)], 'little') + init[12] = cnt + for i in range(3): + init[13 + i] = int.from_bytes(nonce[4 * i:4 * (i+1)], 'little') + # Perform 20 rounds. + state = [v for v in init] + for _ in range(10): + chacha20_doubleround(state) + # Add initial values back into state. + for i in range(16): + state[i] = (state[i] + init[i]) & 0xffffffff + # Produce byte output + return b''.join(state[i].to_bytes(4, 'little') for i in range(16)) + +### ChaCha20Poly1305 + +def aead_chacha20_poly1305_encrypt(key, nonce, aad, plaintext): + """Encrypt a plaintext using ChaCha20Poly1305.""" + ret = bytearray() + msg_len = len(plaintext) + for i in range((msg_len + 63) // 64): + now = min(64, msg_len - 64 * i) + keystream = chacha20_block(key, nonce, i + 1) + for j in range(now): + ret.append(plaintext[j + 64 * i] ^ keystream[j]) + poly1305 = Poly1305(chacha20_block(key, nonce, 0)[:32]) + poly1305.add(aad, pad=True).add(ret, pad=True) + poly1305.add(len(aad).to_bytes(8, 'little') + msg_len.to_bytes(8, 'little')) + ret += poly1305.tag() + return bytes(ret) + +def aead_chacha20_poly1305_decrypt(key, nonce, aad, ciphertext): + """Decrypt a ChaCha20Poly1305 ciphertext.""" + if len(ciphertext) < 16: + return None + msg_len = len(ciphertext) - 16 + poly1305 = Poly1305(chacha20_block(key, nonce, 0)[:32]) + poly1305.add(aad, pad=True) + poly1305.add(ciphertext, length=msg_len, pad=True) + poly1305.add(len(aad).to_bytes(8, 'little') + msg_len.to_bytes(8, 'little')) + if ciphertext[-16:] != poly1305.tag(): + return None + ret = bytearray() + for i in range((msg_len + 63) // 64): + now = min(64, msg_len - 64 * i) + keystream = chacha20_block(key, nonce, i + 1) + for j in range(now): + ret.append(ciphertext[j + 64 * i] ^ keystream[j]) + return bytes(ret) + +### FSChaCha20{,Poly1305} + +REKEY_INTERVAL = 224 # packets + +class FSChaCha20Poly1305: + """Rekeying wrapper AEAD around ChaCha20Poly1305.""" + + def __init__(self, initial_key): + self.key = initial_key + self.packet_counter = 0 + + def crypt(self, aad, text, is_decrypt): + nonce = ((self.packet_counter % REKEY_INTERVAL).to_bytes(4, 'little') + + (self.packet_counter // REKEY_INTERVAL).to_bytes(8, 'little')) + if is_decrypt: + ret = aead_chacha20_poly1305_decrypt(self.key, nonce, aad, text) + else: + ret = aead_chacha20_poly1305_encrypt(self.key, nonce, aad, text) + if (self.packet_counter + 1) % REKEY_INTERVAL == 0: + rekey_nonce = b"\xFF\xFF\xFF\xFF" + nonce[4:] + newkey1 = aead_chacha20_poly1305_encrypt(self.key, rekey_nonce, b"", b"\x00" * 32)[:32] + newkey2 = chacha20_block(self.key, rekey_nonce, 1)[:32] + assert newkey1 == newkey2 + self.key = newkey1 + self.packet_counter += 1 + return ret + + def decrypt(self, aad, ciphertext): + return self.crypt(aad, ciphertext, True) + + def encrypt(self, aad, plaintext): + return self.crypt(aad, plaintext, False) + + +class FSChaCha20: + """Rekeying wrapper stream cipher around ChaCha20.""" + + def __init__(self, initial_key): + self.key = initial_key + self.block_counter = 0 + self.chunk_counter = 0 + self.keystream = b'' + + def get_keystream_bytes(self, nbytes): + while len(self.keystream) < nbytes: + nonce = ((0).to_bytes(4, 'little') + + (self.chunk_counter // REKEY_INTERVAL).to_bytes(8, 'little')) + self.keystream += chacha20_block(self.key, nonce, self.block_counter) + self.block_counter += 1 + ret = self.keystream[:nbytes] + self.keystream = self.keystream[nbytes:] + return ret + + def crypt(self, chunk): + ks = self.get_keystream_bytes(len(chunk)) + ret = bytes([ks[i] ^ chunk[i] for i in range(len(chunk))]) + if ((self.chunk_counter + 1) % REKEY_INTERVAL) == 0: + self.key = self.get_keystream_bytes(32) + self.block_counter = 0 + self.chunk_counter += 1 + return ret + +### Shared secret computation + +def v2_ecdh(priv, ellswift_theirs, ellswift_ours, initiating): + """Compute BIP324 shared secret.""" + + ecdh_point_x32 = ellswift_ecdh_xonly(ellswift_theirs, priv) + if initiating: + # Initiating, place our public key encoding first. + return TaggedHash("bip324_ellswift_xonly_ecdh", + ellswift_ours + ellswift_theirs + ecdh_point_x32) + else: + # Responding, place their public key encoding first. + return TaggedHash("bip324_ellswift_xonly_ecdh", + ellswift_theirs + ellswift_ours + ecdh_point_x32) + +### Key derivation + +NETWORK_MAGIC = b'\xf9\xbe\xb4\xd9' + +def initialize_v2_transport(ecdh_secret, initiating): + """Return a peer object with various BIP324 derived keys and ciphers.""" + + peer = {} + salt = b'bitcoin_v2_shared_secret' + NETWORK_MAGIC + for name, length in ( + ('initiator_L', 32), ('initiator_P', 32), ('responder_L', 32), ('responder_P', 32), + ('garbage_terminators', 32), ('session_id', 32)): + peer[name] = hkdf_sha256( + salt=salt, ikm=ecdh_secret, info=name.encode('utf-8'), length=length) + peer['initiator_garbage_terminator'] = peer['garbage_terminators'][:16] + peer['responder_garbage_terminator'] = peer['garbage_terminators'][16:] + del peer['garbage_terminators'] + if initiating: + peer['send_L'] = FSChaCha20(peer['initiator_L']) + peer['send_P'] = FSChaCha20Poly1305(peer['initiator_P']) + peer['send_garbage_terminator'] = peer['initiator_garbage_terminator'] + peer['recv_L'] = FSChaCha20(peer['responder_L']) + peer['recv_P'] = FSChaCha20Poly1305(peer['responder_P']) + peer['recv_garbage_terminator'] = peer['responder_garbage_terminator'] + else: + peer['send_L'] = FSChaCha20(peer['responder_L']) + peer['send_P'] = FSChaCha20Poly1305(peer['responder_P']) + peer['send_garbage_terminator'] = peer['responder_garbage_terminator'] + peer['recv_L'] = FSChaCha20(peer['initiator_L']) + peer['recv_P'] = FSChaCha20Poly1305(peer['initiator_P']) + peer['recv_garbage_terminator'] = peer['initiator_garbage_terminator'] + + return peer + +### Packet encryption + +LENGTH_FIELD_LEN = 3 +HEADER_LEN = 1 +IGNORE_BIT_POS = 7 + +def v2_enc_packet(peer, contents, aad=b'', ignore=False): + """Encrypt a BIP324 packet.""" + + assert len(contents) <= 2**24 - 1 + header = (ignore << IGNORE_BIT_POS).to_bytes(HEADER_LEN, 'little') + plaintext = header + contents + aead_ciphertext = peer['send_P'].encrypt(aad, plaintext) + enc_plaintext_len = peer['send_L'].crypt(len(contents).to_bytes(LENGTH_FIELD_LEN, 'little')) + return enc_plaintext_len + aead_ciphertext diff --git a/bip-0324/run_test_vectors.py b/bip-0324/run_test_vectors.py new file mode 100644 index 0000000000..ada7371a5e --- /dev/null +++ b/bip-0324/run_test_vectors.py @@ -0,0 +1,53 @@ +import csv +import os +import sys + +import reference + +with open(os.path.join(sys.path[0], 'packet_encoding_test_vectors.csv'), newline='') as csvfile: + reader = csv.reader(csvfile) + reader.__next__() + for row in reader: + in_idx, in_priv_ours, in_ellswift_ours, in_ellswift_theirs, in_initiating, in_content, in_multiply, in_aad, in_ignore, mid_x_ours, mid_x_shared, mid_shared_secret, mid_initiator_l, mid_initiator_p, mid_responder_l, mid_responder_p, mid_send_garbage_terminator, mid_recv_garbage_terminator, mid_session_id, out_ciphertext, out_ciphertext_endswith = row + + assert mid_x_ours == (int.from_bytes(bytes.fromhex(in_priv_ours), 'big') * reference.SECP256K1_G).x.to_bytes().hex() + assert mid_x_shared == reference.ellswift_ecdh_xonly(bytes.fromhex(in_ellswift_theirs), bytes.fromhex(in_priv_ours)).hex() + assert mid_shared_secret == reference.v2_ecdh(bytes.fromhex(in_priv_ours), bytes.fromhex(in_ellswift_theirs), bytes.fromhex(in_ellswift_ours), int(in_initiating)).hex() + + peer = reference.initialize_v2_transport(bytes.fromhex(mid_shared_secret), int(in_initiating)) + assert mid_initiator_l == peer['initiator_L'].hex() + assert mid_initiator_p == peer['initiator_P'].hex() + assert mid_responder_l == peer['responder_L'].hex() + assert mid_responder_p == peer['responder_P'].hex() + assert mid_send_garbage_terminator == peer['send_garbage_terminator'].hex() + assert mid_recv_garbage_terminator == peer['recv_garbage_terminator'].hex() + assert mid_session_id == peer['session_id'].hex() + for _ in range(int(in_idx)): + reference.v2_enc_packet(peer, b"") + ciphertext = reference.v2_enc_packet(peer, bytes.fromhex(in_content) * int(in_multiply), bytes.fromhex(in_aad), int(in_ignore)) + if len(out_ciphertext): + assert out_ciphertext == ciphertext.hex() + if len(out_ciphertext_endswith): + assert ciphertext.hex().endswith(out_ciphertext_endswith) + +with open(os.path.join(sys.path[0], 'xswiftec_test_vectors.csv'), newline='') as csvfile: + reader = csv.reader(csvfile) + reader.__next__() + for row in reader: + u = reference.FE.from_bytes(bytes.fromhex(row[0])) + x = reference.FE.from_bytes(bytes.fromhex(row[1])) + for case in range(8): + ret = reference.xswiftec_inv(x, u, case) + if ret is None: + assert row[2 + case] == "" + else: + assert row[2 + case] == ret.to_bytes().hex() + assert reference.xswiftec(u, ret) == x + +with open(os.path.join(sys.path[0], 'xelligatorswift_test_vectors.csv'), newline='') as csvfile: + reader = csv.reader(csvfile) + reader.__next__() + for row in reader: + ellswift = bytes.fromhex(row[0]) + x = bytes.fromhex(row[1]) + assert reference.ellswift_ecdh_xonly(ellswift, (1).to_bytes(32, 'big')) == x diff --git a/bip-0324/xelligatorswift_test_vectors.csv b/bip-0324/xelligatorswift_test_vectors.csv new file mode 100644 index 0000000000..253a076d1f --- /dev/null +++ b/bip-0324/xelligatorswift_test_vectors.csv @@ -0,0 +1,17 @@ +ellswift,x +26b25d457597a7b0463f9620f666dd10aa2c4373a505967c7c8d70922a2d6eceffffffffffffffffffffffffffffffffffffffffffffffffffffffffb2dabde1,240b740607e14d8cb767f53c9dacf5becde98abe73ffa36f096971215280dc58 +5a3e80a37915b1601c363acd1601df7ef257d5d32c664004a2ec0484a4f60628ffffffffffffffffffffffffffffffffffffffffffffffffffffffff15d5f3cd,4deaeb3cfbd2abbc9d57fdd83d825a05c45d773d96e247bda136e154769c1f8b +6641161dc1faf1293662e9d81dc994fed6a720d6e0e1ab5702c6a866254a9076ffffffffffffffffffffffffffffffffffffffffffffffffffffffff5f44671f,32f5e32639066d09d5184e36cfca82b9f16076666edb2597bf6c8ca0f9423799 +bf5e8ffa51a9e748985800c1d3d7f1a2a6ae7435136593ca8d9637e3f87c699c76cc5805dab9b4eacefdb477f498020fd82bccdbc9c6a2d9ce10586ac85512b4,5579653da55ae6af8c92b0ab623bfede27756fdba141124c72aec43bc5b746e5 +df3f619804a92fdb4057192dc43dd748ea778adc52bc498ce80524c014b81119b40711a88c7039756fb8a73827eabe2c0fe5a0346ca7e0a104adc0fc764f528d,e838221abd40251a45646c40f62550e0acb8ab1ab292df7a9d4f28d72316bd3a +f0caf11f8aea622a396127c3e7e67a6a854dccb736fcdc1270fc071592083e6da839c820778a009421bb1d1eee17cdea622828bd0d065d5b4adb6c0033570a37,bfae8740fc4926b0387803a8db03fa8b9d8b53ec30713a8227bf421b23b11571 +f1473fa4fb09147ba9d07832c92ccc0bcd651b696ff463931964066a4c849d12ffffffffffffffffffffffffffffffffffffffffffffffffffffffffd7ac238b,de26c723c76ec977f4cf79b3ba3e27800041930000ee7a74337d0e64fe164937 +fd50cee538a3798d17dde484f9d935860a88fe8dd6cd2341254ab5d558b0b67f5c5ec4b2af7c601e0f4b8d3893192292759a5c3b0a760c0589e5337bfb4e8a2d,0969798ab212485d36a0f007f744a17bffbc4fa9c3e73afcb4e7a27fb3580de9 +ffffffffffffffffffffffffffffffffffffffffffffffffffffffff3d60a4a9252c0b6b080fa045acfcd1437f693f3be2be2ac8223ea525d492fa19ab028942,c163b493f047704ba83e241472ebb2a05f95ef47c6bf5feedd8da33504866d68 +ffffffffffffffffffffffffffffffffffffffffffffffffffffffff4f51ebdbafa7518106309c22d325df6d2663249d158d2f36f1976269d6d4104d9198a108,37d7c5665514f85fe6e4cca488e8abdfc6bc4b3e87ff01ac08eb2504180296e9 +ffffffffffffffffffffffffffffffffffffffffffffffffffffffff72a7e655ffffffffffffffffffffffffffffffffffffffffffffffffffffffff1dd15ad9,34818ed876cbbb6710eb832627de9eb7c468846f26bfc336303601593bbb706d +ffffffffffffffffffffffffffffffffffffffffffffffffffffffff92e6fb5cf32ceb01b42ea21ecdacc88a0e59dfbf72692b68d76924ba59f0a81f373d2cee,438c40e9cc47e577f56932b9bea91433acc7be309c017ff8f45a46046ed5aa9f +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffba7d0816157655bf7c7eaf74e26c4fb12043675dcce7580ea49d60317a546c3df2e14f9f,11d52804cc52a73185697681ebb8713dfe4204864fb9989b28e5a3696907710c +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffd4b84378fffffffffffffffffffffffffffffffffffffffffffffffffffffffff69a56d1,523e0758ee088690c9b95c604ef4d143e4fd3f2d1ac9084e3086750a9686f9bc +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffdac35742ffffffffffffffffffffffffffffffffffffffffffffffffffffffff99d5d507,db7f9b113af6796d460dfc12bef75f947fa1e0102686cf58de6ad5c0af752f82 +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffeeee1f01fffffffffffffffffffffffffffffffffffffffffffffffffffffffff43363e8,c0c123902ec734bde1c6410a93e5d0033e0540120d5be9f555476b842fd2d245 diff --git a/bip-0324/xswiftec_test_vectors.csv b/bip-0324/xswiftec_test_vectors.csv new file mode 100644 index 0000000000..985235fb6b --- /dev/null +++ b/bip-0324/xswiftec_test_vectors.csv @@ -0,0 +1,33 @@ +u,x,case0_t,case1_t,case2_t,case3_t,case4_t,case5_t,case6_t,case7_t +08da7c45cb204377e7e42249cda5713fa865116ddbb4cb5a1949b2e5b438a6ab,e087b707dabf2796b03b2fb4f976c3f2f5abb36110d00ef656432117f2c93f0a,,,,,,,, +0a6361b3a802f55cd5ae06101c88a1e216320fe11cc0cfe1d791eed08a1200fd,a0223bc98997647daf4d520129bdb66e4937a00d1533af1fa29645fb96fb5bb5,60a3ed14bd9df0bfb89ada9372a7b5790b123a66bf130f5788237e8cd5225de4,9c4ee4629f10220fda49532d0c859a539dec5148eefc78bf48d93d2828027a9c,fc5e72f042fd1792cbf88728a374a2cc1e03e1f9ec8813fa3692e497cfa7d5e6,cb39fac005f26dc0a383ea64cb9b3b0b26767f20232cae4486f32904df4f04e3,9f5c12eb42620f404765256c8d584a86f4edc59940ecf0a877dc81722add9e4b,63b11b9d60efddf025b6acd2f37a65ac6213aeb711038740b726c2d6d7fd8193,03a18d0fbd02e86d340778d75c8b5d33e1fc1e061377ec05c96d1b6730582649,34c6053ffa0d923f5c7c159b3464c4f4d98980dfdcd351bb790cd6fa20b0f74c +102b51b9765a56a3e899f7cf0ee38e5251f9c503b357b330a49183eb7b155604,102b51b9765a56a3e899f7cf0ee38e5251f9c503b357b330a49183eb7b155604,bdb5bd58ca96eae36147a6c55bc2bef2cee55a757ee193cb619edc8d3590f90a,bda953c1da02059350e740b83f59149628e0be50c24ac8dc6908a2225931b4a0,,,424a42a73569151c9eb8593aa43d410d311aa58a811e6c349e612371ca6f0325,4256ac3e25fdfa6caf18bf47c0a6eb69d71f41af3db5372396f75ddca6ce478f,, +2921a11f25dadaa24aa79a548e4e81508c2e5e56af2d833d65e2bcce448ce2f5,3a70c472406b83d9f1c4398b8ecef786499bc44a3b30c34ac30f2d8a418bffa3,b9c76c21d3fabb948fa0326bf9e999068e9eed56ee4e76cb81558aa26969c56c,ef7dd84338732a0cac3a8995f3bacf9b2896582b8d3317ed508e5d9a5a3447af,,,463893de2c05446b705fcd94061666f9716112a911b189347eaa755c969636c3,108227bcc78cd5f353c5766a0c453064d769a7d472cce812af71a264a5cbb480,, +33b67cb5385ceddad93d0ee960679041613bed34b8b4a5e6362fe7539ba2d3ce,0105c74958a165e016502eeb87835195505d89714c95272b6fa88fe6c60b33ac,,,069e1b3b155c6da989b9b6a8735bba3c5c1049dcf01fe4474772244db89cf9ca,c77b10bca540e95ee66c1f57ab6297787849a89b2b883116e700593e3c0fe66d,,,f961e4c4eaa39256764649578ca445c3a3efb6230fe01bb8b88ddbb147630265,3884ef435abf16a11993e0a8549d688787b65764d477cee918ffa6c0c3f015c2 +3a898eecdae167231275338e9a79153cbe53f7bf99943eeb72ee64e57bb58699,41ffd7362aaa7b90fe03936deeebe9afafd9c18967122d8f972db2c050d4f07b,60abf7ed2a7ffd3d2ac242a782331ea663d55ca157af994e5e964e9c79a0db40,3c3c39dc37753ab9160dfbc2e0596c3a5114784690caa1836e12036814453da3,adcd3f100de60723f127278998c591fbf081af8e0a77f2a9090bed67d8aa2aa3,,9f540812d58002c2d53dbd587dcce1599c2aa35ea85066b1a169b162865f20ef,c3c3c623c88ac546e9f2043d1fa693c5aeeb87b96f355e7c91edfc96ebbabe8c,5232c0eff219f8dc0ed8d876673a6e040f7e5071f5880d56f6f412972755d18c, +46e04d129d7b45d054469ce34e24069a1426b3e34f1b68a3d1bff1e070aee192,c6ce9611bd908c16eba5c599e5219de2d18d82c96aafb0180b23ee315513618f,,,,,,,, +47dc540c94ceb704a23875c11273e16bb0b8a87aed84de911f2133568115f254,13964717dbc998964d7c19ec3d9981fe1d4a9a80845552a98fb9352898532844,,,,,,,, +4cab73ce2a7e6220975001c8a354143267a3c1ce8bf7692313e654481e616a93,9114cf2edd3b53dbb6581290a5cca532db38b4e9ceeacc9b0437a0e49bf97211,903b600ed648d4ddc48f0f628829c8992c88fab44b692413fb8b3d783854f9a2,2952afe39557606d08c311345788a5071413580917207c86ea7cb829cf2f2c6d,05f414320d0c4004cff10f798c3fda6c4fc335b5a2db940993b3d78147a25c18,48e2531c7e3ec99f807210d6c5330114b4f04d7345535ca5a6e6abf478bdb723,6fc49ff129b72b223b70f09d77d63766d377054bb496dbec0474c286c7ab028d,d6ad501c6aa89f92f73ceecba8775af8ebeca7f6e8df8379158347d530d0cfc2,fa0bebcdf2f3bffb300ef08673c02593b03cca4a5d246bf66c4c287db85da017,b71dace381c136607f8def293accfeeb4b0fb28cbaaca35a5919540a8742450c +5aeca385d8b781825b07bbec7c858b7170426c88088935850bc13dd6402368a5,a5135c7a27487e7da4f84413837a748e8fbd9377f776ca7af43ec228bfdc938a,8da4f71fb2700758f623d73c24ac91747da43f2302fce16c8d438a769c63495f,6b8f345fc0a25a76455541ddbf2791ff4b943c98b16db2b6eb6cea94a6b19afb,,,725b08e04d8ff8a709dc28c3db536e8b825bc0dcfd031e9372bc7588639cb2d0,9470cba03f5da589baaabe2240d86e00b46bc3674e924d491493156a594e6134,, +707bf0b938f307b5c222e670598b865d5e1f8a8003df82c7abbf7c9f8fa4d720,8f840f46c70cf84a3ddd198fa67479a2a1e0757ffc207d385440835f705b250f,,,eab90fb459bace62d3ce8fbd69c9f1039f0627d0e93e2f42bffd87889cb236a4,157c26578b226c66daf8edfa56f7560f1131f41d1685175e6d76cc95b4f89f10,,,1546f04ba645319d2c31704296360efc60f9d82f16c1d0bd40027876634dc58b,ea83d9a874dd939925071205a908a9f0eece0be2e97ae8a1928933694b075d1f +766caa663e1025b9accd7ededd24fbc8193180e028eedae2f41d6bb0b1d36468,22825ee826f8b76c27220e43c79c884a8518bc20f4978cc15f83f9c48346a314,,,8fe95c178da66d1dd249ea6a4dc614a6d46d79c83cbc4beafee518090263e48a,7b044cb756eb207226db302ba05e164781c2f5161dccd72607282cb9ad86a282,,,7016a3e8725992e22db61595b239eb592b928637c343b415011ae7f5fd9c17a5,84fbb348a914df8dd924cfd45fa1e9b87e3d0ae9e23328d9f8d7d345527959ad +78a23af8da46b1b37e8767921a2d3f528fdc8eca37cea8aea775fd2b283d3776,73d5f35d96f3ce1ef5802ead8edc10787700c593b5e0ddcc3bfb2720b9d36de3,8465ad20bd0f2b4a2d37106769af46288a109bc10b527c3b033c930c0e4b1025,1b7f03bd2c915bb736622aec85601bcabec89268c98945e19a0de4126ed62524,,,7b9a52df42f0d4b5d2c8ef989650b9d775ef643ef4ad83c4fcc36cf2f1b4ec0a,e480fc42d36ea448c99dd5137a9fe43541376d973676ba1e65f21bec9129d70b,, +78b4be1f9eeef9da65c393e4385f67edd142709b400ca7d900bd952e0c3cf727,089329e17a58a91e71ffe6ddd851e8a352e85a29fcc289b34a3bfdeaf958fe91,,,6008d703955b38da0166bd975ad3535af3b701b2efdf653fc5e7e6eb6afff0a3,,,,9ff728fc6aa4c725fe994268a52caca50c48fe4d10209ac03a18191395000b8c, +7a2a7c0a81d1bd595dff09b918f8ecb5b5e8493654a4f83496956ed8eb017674,85d583f57e2e42a6a200f646e707134a4a17b6c9ab5b07cb696a912614fe85bb,,,,,,,, +913da1f8df6f8fd47593840d533ba0458cc9873996bf310460abb495b34c232a,a7803f8e02b70718443a06db502c67925640e936b3fa46dd2ed6b8f7c80fa329,67d916ba2cc154464d87ff4e0cfe3bb816b22a961831c2daf62597a8b0681e87,a4b84520f8853e5482ee7689732ed7dd7da59945d26edeee0bf5f55d3507192f,,,9826e945d33eabb9b27800b1f301c447e94dd569e7ce3d2509da68564f97dda8,5b47badf077ac1ab7d1189768cd12822825a66ba2d912111f40a0aa1caf8e300,, +96a296d224f285c67bee93c30f8a309157f0daa35dc5b87e410b78630a09cfc7,7684ab3b1a43e20a97a7b5520e5b5347841a7d95984fd76b2478a2b710f1a2ce,,,,,,,, +99be5efb88ca2013bd8e4eb035fd42d5245468fe9afa70d8ba9c1c419a48c4e8,08ee83ae5c7af0c9b2341e595fe347537272d94f2fe9f10b9a8f913279fc6230,,,,,,,, +9b4fb24edd6d1d8830e272398263cdbf026b97392cc35387b991dc0248a628f9,80e81d40a50b53712a8dac5f468b0903c05219544a56af70aa152ebf17887701,,,6e94af5a32ac100c5230f1e119c538742b7051934b02f3850522cff26bd32d97,e9bd309fbf041342311be3d5bab0b9d16c9f80c6640eb47e311d3178c2adc75d,,,916b50a5cd53eff3adcf0e1ee63ac78bd48fae6cb4fd0c7afadd300c942cce98,1642cf6040fbecbdcee41c2a454f462e93607f399bf14b81cee2ce863d5234d2 +9def996cb1ea87e596b6cadccca3839a352e99d9ce07e635cdb239f38ca294f8,294850a665ab014a0e75eb4b52ee66dd8a8d2b5e453074e58afacb5e019ee90a,b1a29367b95e1996f7e393fb389e7ace812d4135f6ddcdcd77467fc000dfca8c,a340aabc95b4000e3043ba6139178c450046c985fbf09676c440bc6430ddaa5b,4c4cd400d0be335dd651370c5565c2b742a298016212a8605187b3c0751a811e,d90fa208bbb5f3f6e16c5a42b419188ec1951c1eb358f04741b7b48df9e55f79,4e5d6c9846a1e669081c6c04c76185317ed2beca0922323288b9803eff2031a3,5cbf55436a4bfff1cfbc459ec6e873baffb9367a040f69893bbf439acf2251d4,b3b32bff2f41cca229aec8f3aa9a3d48bd5d67fe9ded579fae784c3e8ae57b11,26f05df7444a0c091e93a5bd4be6e7713e6ae3e14ca70fb8be484b71061a9cb6 +a2c4aed1cf757cd9a509734a267ffc7b1166b55f4c8f9c3e3550c56e743328fc,a2c4aed1cf757cd9a509734a267ffc7b1166b55f4c8f9c3e3550c56e743328fc,,,,,,,, +a8e437abf9c0e74dc6d51eabf2d261a00e785c7e21efeac1f322b610273ba066,5a64cce4be767964e7dba23e78e30149326c539353b647e0d5d7cc361943b13b,,,6f73bdd6b748790b5f788935ca02aee3b9e560c4ba6caf47d716fbde1dd6e92c,b1ff705694188e672f58c6a05eeecc379dd1b60fd3cb9f19fcb02b1d9cab4bc5,,,908c422948b786f4a08776ca35fd511c461a9f3b459350b828e90420e2291303,4e008fa96be77198d0a7395fa11133c8622e49f02c3460e6034fd4e16354b06a +bf60e4349cace6bce0d552e8d783428db66d0d649bd9e430a3627e2ee14ac839,409f1bcb635319431f2aad17287cbd724992f29b64261bcf5c9d81d01eb533f6,,,,,,,, +c0ba8a33ac67f44abff5984dfbb6f56c46b880ac2b86e1f23e7fa9c402c53ae7,4767c4cab0d08133980a8e66c3f93a055c8ae62f89a92f8dcfa47607cee0bc57,4c21052f5ffccadb4f707aa1cba828ef384d7861af1690c59d638dfee9f368e7,dbcc8fe22896478161452d44688a6b138050a4d0964470c175a521dcecc5519a,,,b3defad0a0033524b08f855e3457d710c7b2879e50e96f3a629c7200160c9348,2433701dd769b87e9ebad2bb977594ec7faf5b2f69bb8f3e8a5ade22133aaa95,, +cbe2268747c9c8072c7f9926f2288f270637dc55bb9d14d3368361d5e47d25be,0e4e25736b614910c4984843e606b1e229def08bfd672ab61e2707cde8248c6d,,,c30567184201fac8e1cb9e776d921e17d28cdb7333223abd1c8f860a16393df1,,,,3cfa98e7bdfe05371e346188926de1e82d73248cccddc542e37079f4e9c6be3e, +ceb827ad3d3884fd4d50ae6099d6d50c09a21e72ebd309708e8b69d93df19e55,a6a0c8c94462f16f1b92502c3d5f9d1618f12ffa756227d5b19b01b9373cd940,,,,,,,, +d57e9d4f5842134f140032eaf38b5333638e8c4b145fcf86a23d48d3e9acc0f8,2a8162b0a7bdecb0ebffcd150c74accc9c7173b4eba030795dc2b72b16533b37,349a9a592d2c56e5378ae869d646043fc09ffb8fe5fd9debd83a11274da08892,9875f58028cc991cafab9fb1183b350bc1d8d5ce5723813cc2b8434ed1a2100f,,,cb6565a6d2d3a91ac875179629b9fbc03f6004701a02621427c5eed7b25f739d,678a0a7fd73366e35054604ee7c4caf43e272a31a8dc7ec33d47bcb02e5dec20,, +d94e7f1e9bb1f8a9b90996ba12c461b84956f0e7f230145cc594c2f80b067aa0,b4f4632803cff65c013a566748cd3386d58cd3a28f5b4721056cbe9d278a67a4,,,fad51eda7d418ee2785df9f3788ac9152576312177fc0fd83c65036750581620,749259382784be63f86cc927a5defa6aa8cecb98e38d68f6b7a7e958303c94ad,,,052ae12582be711d87a2060c877536eada89cede8803f027c39afc97afa7e60f,8b6da6c7d87b419c079336d85a210595573134671c729709485816a6cfc36782 +e545d395bb3fd971f91bf9a2b6722831df704efae6c1aa9da0989ed0970b77bb,760486143a1d512da5219d3e5febc7c5c9990d21ca7a501ed23f86c91ddee4cf,,,090892960a84c69967fe5a5d014d3ca19173e4cb72a908586fbce9d1e531a265,42a47f65d00ff2004faa98865ee8ed4f8a9a5ddc9f75042d728de335664bb546,,,f6f76d69f57b39669801a5a2feb2c35e6e8c1b348d56f7a79043162d1ace59ca,bd5b809a2ff00dffb0556779a11712b07565a223608afbd28d721cc999b446e9 +e9f86cefcfd61558fe75da7d4ea48a6c82d93191c6d49579aab49f99e543dcad,5db7371325a7bb83b030691b2d87cd9f199f43d91e302568391ac48181b7cea6,,,,,,,, +eec4121f2a07b61aba16414812aa9afc39ab0a136360a5ace2240dc19b0464eb,0b623c5296c13218a1eb24e79d00b04bf15788f6c2f7ec100a4a16f1473124a2,,,,,,,, +f566cc6fccc657365c0197accf3a7d6f80f85209ff666ff774f4dcbc524aa842,0a9933903339a8c9a3fe685330c582907f07adf6009990088b0b2342adb553ed,3ab8dc4ecbc0441c685436ac0d76f16393769c353be6092bd6ec4ce094106bd8,3bd189b4ef3d1baa5610f2b14cb4a2b377eb171511e6f36ef6a05a2c7c52e368,1594764c6296402aadd123675d81f3505d35f2a52c52881568eadb7b675b53f0,c64fbf71138e66de8ce0abdf3b6f51d151ca8e1037ab5b979e62b2faa15be81c,c54723b1343fbbe397abc953f2890e9c6c8963cac419f6d42913b31e6bef9057,c42e764b10c2e455a9ef0d4eb34b5d4c8814e8eaee190c91095fa5d283ad18c7,ea6b89b39d69bfd5522edc98a27e0cafa2ca0d5ad3ad77ea9715248398a4a83f,39b0408eec719921731f5420c490ae2eae3571efc854a468619d4d045ea41413 From cc177ab7bc5abcdcdf9c956ee88afd1052053328 Mon Sep 17 00:00:00 2001 From: Pieter Wuille Date: Wed, 11 Jan 2023 17:39:32 -0500 Subject: [PATCH 030/454] BIP324 updates Includes: * Simpler (but equivalent) ElligatorSwift encoding function & spec * Improved test vectors * Test vector generation code * Code for converting test vectors for libsecp256k1 code. * Code for running test vectors against SwiftEC paper authors' code. * Miscellaneous reference code improvements (style, comments). --- bip-0324.mediawiki | 16 +- bip-0324/ellswift_decode_test_vectors.csv | 77 ++++ bip-0324/gen_test_vectors.py | 418 ++++++++++++++++++++++ bip-0324/packet_encoding_test_vectors.csv | 16 +- bip-0324/reference.py | 150 ++++++-- bip-0324/run_test_vectors.py | 86 +++-- bip-0324/secp256k1_test_vectors.py | 52 +++ bip-0324/test_sage_decoding.py | 78 ++++ bip-0324/xelligatorswift_test_vectors.csv | 17 - bip-0324/xswiftec_inv_test_vectors.csv | 33 ++ 10 files changed, 837 insertions(+), 106 deletions(-) create mode 100644 bip-0324/ellswift_decode_test_vectors.csv create mode 100644 bip-0324/gen_test_vectors.py create mode 100644 bip-0324/secp256k1_test_vectors.py create mode 100644 bip-0324/test_sage_decoding.py delete mode 100644 bip-0324/xelligatorswift_test_vectors.csv create mode 100644 bip-0324/xswiftec_inv_test_vectors.csv diff --git a/bip-0324.mediawiki b/bip-0324.mediawiki index 8a8861a5ce..47032ddccb 100644 --- a/bip-0324.mediawiki +++ b/bip-0324.mediawiki @@ -247,19 +247,19 @@ To find encodings of a given X coordinate ''x'', we first need the inverse of '' * ''XSwiftECInv(x, u, case)'': ** If ''case & 2 = 0'': *** If ''lift_x(-x - u)'' succeeds, return ''None''. -*** Let ''v = x'' if ''case & 1 = 0''; let ''v = -x - u (mod p)'' otherwise. +*** Let ''v = x''. *** Let ''s = -(u3 + 7)/(u2 + uv + v2) (mod p)''. ** If ''case & 2 = 2'': *** Let ''s = x - u (mod p)''. *** If ''s = 0'', return ''None''. *** Let ''r'' be the square root of ''-s(4(u3 + 7) + 3u2s) (mod p).'''''How to compute a square root mod ''p''?''' Due to the structure of ''p'', a candidate for the square root of ''a'' mod ''p'' can be computed as ''x = a(p+1)/4 mod p''. If ''a'' is not a square mod ''p'', this formula returns the square root of ''-a mod p'' instead, so it is necessary to verify that ''x2 mod p = a''. If that is the case ''-x mod p'' is a solution too, but we define "the" square root to be equal to that expression (the square root will therefore always be a square itself, as ''(p+1)/4'' is even). This algorithm is a specialization of the [https://en.wikipedia.org/wiki/Tonelli%E2%80%93Shanks_algorithm Tonelli-Shanks algorithm]. Return ''None'' if it does not exist. -*** If ''case & 1 = 1'': -**** If ''r = 0'', return ''None''. -**** let ''r = -r (mod p)''. +** If ''case & 1 = 1'' and ''r = 0'', return ''None''. *** Let ''v = (-u + r/s)/2''. ** Let ''w'' be the square root of ''s (mod p)''. Return ''None'' if it does not exist. -** If ''case & 4 = 4'', let ''w = -w (mod p)''. -** Return ''w(u(c - 1)/2 - v)''. +** If ''case & 5 = 0'', return ''-w(u(1 - c)/2 + v)''. +** If ''case & 5 = 1'', return ''w(u(1 + c)/2 + v)''. +** If ''case & 5 = 4'', return ''w(u(1 - c)/2 + v)''. +** If ''case & 5 = 5'', return ''-w(u(1 + c)/2 + v)''. The overall ''XElligatorSwift'' algorithm, matching the name used in the paper, then uses this inverse to randomly'''''Can the ElligatorSwift encoding be used to construct public key encodings that satisfy a certain structure (and not pseudorandom)?''' The algorithm chooses the first 32 bytes (i.e., the value ''u'') and then computes a corresponding ''t'' such that the mapping to the curve point holds. In general, picking ''u'' from a uniformly random distribution provides pseudorandomness. But we can also fix any of the 32 bytes in ''u'', and the algorithm will still find a corresponding ''t''. The fact that it is possible to fix the first 32 bytes, combined with the garbage bytes in the handshake, provides a limited but very simple method of parroting other protocols such as [https://tls13.xargs.org/ TLS 1.3], which can be deployed by one of the peers without explicit support from the other peer. More general methods of parroting, e.g., introduced by defining new protocol or a protocol upgrade, are not precluded. sample encodings of ''x'': @@ -586,8 +586,8 @@ Peers supporting the v2 transport protocol signal support by advertising the =p +0000000000000000000000000000000000000000000000000000000000000000ffffffffffffffffffffffffffffffffffffffffffffffffffffffff2664bbd5,50873db31badcc71890e4f67753a65757f97aaa7dd5f1e82b753ace32219064b,u%p=0;valid_x(x3);valid_x(x2);valid_x(x1);t>=p +0000000000000000000000000000000000000000000000000000000000000000ffffffffffffffffffffffffffffffffffffffffffffffffffffffff7028de7d,1eea9cc59cfcf2fa151ac6c274eea4110feb4f7b68c5965732e9992e976ef68e,u%p=0;valid_x(x2);t>=p +0000000000000000000000000000000000000000000000000000000000000000ffffffffffffffffffffffffffffffffffffffffffffffffffffffffcbcfb7e7,12303941aedc208880735b1f1795c8e55be520ea93e103357b5d2adb7ed59b8e,u%p=0;valid_x(x1);t>=p +0000000000000000000000000000000000000000000000000000000000000000fffffffffffffffffffffffffffffffffffffffffffffffffffffffff3113ad9,7eed6b70e7b0767c7d7feac04e57aa2a12fef5e0f48f878fcbb88b3b6b5e0783,u%p=0;valid_x(x3);t>=p +0a2d2ba93507f1df233770c2a797962cc61f6d15da14ecd47d8d27ae1cd5f8530000000000000000000000000000000000000000000000000000000000000000,532167c11200b08c0e84a354e74dcc40f8b25f4fe686e30869526366278a0688,t%p=0;(u'^3+t'^2+7)%p=0;valid_x(x3);valid_x(x2);valid_x(x1) +0a2d2ba93507f1df233770c2a797962cc61f6d15da14ecd47d8d27ae1cd5f853fffffffffffffffffffffffffffffffffffffffffffffffffffffffefffffc2f,532167c11200b08c0e84a354e74dcc40f8b25f4fe686e30869526366278a0688,t%p=0;(u'^3+t'^2+7)%p=0;valid_x(x3);valid_x(x2);valid_x(x1);t>=p +0ffde9ca81d751e9cdaffc1a50779245320b28996dbaf32f822f20117c22fbd6c74d99efceaa550f1ad1c0f43f46e7ff1ee3bd0162b7bf55f2965da9c3450646,74e880b3ffd18fe3cddf7902522551ddf97fa4a35a3cfda8197f947081a57b8f,valid_x(x3) +0ffde9ca81d751e9cdaffc1a50779245320b28996dbaf32f822f20117c22fbd6ffffffffffffffffffffffffffffffffffffffffffffffffffffffff156ca896,377b643fce2271f64e5c8101566107c1be4980745091783804f654781ac9217c,valid_x(x2);t>=p +123658444f32be8f02ea2034afa7ef4bbe8adc918ceb49b12773b625f490b368ffffffffffffffffffffffffffffffffffffffffffffffffffffffff8dc5fe11,ed16d65cf3a9538fcb2c139f1ecbc143ee14827120cbc2659e667256800b8142,(u'^3-t'^2+7)%p=0;valid_x(x3);valid_x(x2);valid_x(x1);t>=p +146f92464d15d36e35382bd3ca5b0f976c95cb08acdcf2d5b3570617990839d7ffffffffffffffffffffffffffffffffffffffffffffffffffffffff3145e93b,0d5cd840427f941f65193079ab8e2e83024ef2ee7ca558d88879ffd879fb6657,(u'^3+t'^2+7)%p=0;valid_x(x3);t>=p +15fdf5cf09c90759add2272d574d2bb5fe1429f9f3c14c65e3194bf61b82aa73ffffffffffffffffffffffffffffffffffffffffffffffffffffffff04cfd906,16d0e43946aec93f62d57eb8cde68951af136cf4b307938dd1447411e07bffe1,(u'^3+t'^2+7)%p=0;valid_x(x2);t>=p +1f67edf779a8a649d6def60035f2fa22d022dd359079a1a144073d84f19b92d50000000000000000000000000000000000000000000000000000000000000000,025661f9aba9d15c3118456bbe980e3e1b8ba2e047c737a4eb48a040bb566f6c,t%p=0;valid_x(x2) +1f67edf779a8a649d6def60035f2fa22d022dd359079a1a144073d84f19b92d5fffffffffffffffffffffffffffffffffffffffffffffffffffffffefffffc2f,025661f9aba9d15c3118456bbe980e3e1b8ba2e047c737a4eb48a040bb566f6c,t%p=0;valid_x(x2);t>=p +1fe1e5ef3fceb5c135ab7741333ce5a6e80d68167653f6b2b24bcbcfaaaff507fffffffffffffffffffffffffffffffffffffffffffffffffffffffefffffc2f,98bec3b2a351fa96cfd191c1778351931b9e9ba9ad1149f6d9eadca80981b801,t%p=0;(u'^3-t'^2+7)%p=0;valid_x(x3);valid_x(x2);valid_x(x1);t>=p +4056a34a210eec7892e8820675c860099f857b26aad85470ee6d3cf1304a9dcf375e70374271f20b13c9986ed7d3c17799698cfc435dbed3a9f34b38c823c2b4,868aac2003b29dbcad1a3e803855e078a89d16543ac64392d122417298cec76e,(u'^3-t'^2+7)%p=0;valid_x(x3) +4197ec3723c654cfdd32ab075506648b2ff5070362d01a4fff14b336b78f963fffffffffffffffffffffffffffffffffffffffffffffffffffffffffb3ab1e95,ba5a6314502a8952b8f456e085928105f665377a8ce27726a5b0eb7ec1ac0286,(u'^3+t'^2+7)%p=0;valid_x(x1);t>=p +47eb3e208fedcdf8234c9421e9cd9a7ae873bfbdbc393723d1ba1e1e6a8e6b24ffffffffffffffffffffffffffffffffffffffffffffffffffffffff7cd12cb1,d192d52007e541c9807006ed0468df77fd214af0a795fe119359666fdcf08f7c,(u'^3+t'^2+7)%p=0;valid_x(x3);valid_x(x2);valid_x(x1);t>=p +5eb9696a2336fe2c3c666b02c755db4c0cfd62825c7b589a7b7bb442e141c1d693413f0052d49e64abec6d5831d66c43612830a17df1fe4383db896468100221,ef6e1da6d6c7627e80f7a7234cb08a022c1ee1cf29e4d0f9642ae924cef9eb38,(u'^3+t'^2+7)%p=0;valid_x(x1) +7bf96b7b6da15d3476a2b195934b690a3a3de3e8ab8474856863b0de3af90b0e0000000000000000000000000000000000000000000000000000000000000000,50851dfc9f418c314a437295b24feeea27af3d0cd2308348fda6e21c463e46ff,t%p=0;valid_x(x1) +7bf96b7b6da15d3476a2b195934b690a3a3de3e8ab8474856863b0de3af90b0efffffffffffffffffffffffffffffffffffffffffffffffffffffffefffffc2f,50851dfc9f418c314a437295b24feeea27af3d0cd2308348fda6e21c463e46ff,t%p=0;valid_x(x1);t>=p +851b1ca94549371c4f1f7187321d39bf51c6b7fb61f7cbf027c9da62021b7a65fc54c96837fb22b362eda63ec52ec83d81bedd160c11b22d965d9f4a6d64d251,3e731051e12d33237eb324f2aa5b16bb868eb49a1aa1fadc19b6e8761b5a5f7b,(u'^3+t'^2+7)%p=0;valid_x(x2) +943c2f775108b737fe65a9531e19f2fc2a197f5603e3a2881d1d83e4008f91250000000000000000000000000000000000000000000000000000000000000000,311c61f0ab2f32b7b1f0223fa72f0a78752b8146e46107f8876dd9c4f92b2942,t%p=0;valid_x(x3);valid_x(x2);valid_x(x1) +943c2f775108b737fe65a9531e19f2fc2a197f5603e3a2881d1d83e4008f9125fffffffffffffffffffffffffffffffffffffffffffffffffffffffefffffc2f,311c61f0ab2f32b7b1f0223fa72f0a78752b8146e46107f8876dd9c4f92b2942,t%p=0;valid_x(x3);valid_x(x2);valid_x(x1);t>=p +a0f18492183e61e8063e573606591421b06bc3513631578a73a39c1c3306239f2f32904f0d2a33ecca8a5451705bb537d3bf44e071226025cdbfd249fe0f7ad6,97a09cf1a2eae7c494df3c6f8a9445bfb8c09d60832f9b0b9d5eabe25fbd14b9,valid_x(x1) +a1ed0a0bd79d8a23cfe4ec5fef5ba5cccfd844e4ff5cb4b0f2e71627341f1c5b17c499249e0ac08d5d11ea1c2c8ca7001616559a7994eadec9ca10fb4b8516dc,65a89640744192cdac64b2d21ddf989cdac7500725b645bef8e2200ae39691f2,valid_x(x2) +ba94594a432721aa3580b84c161d0d134bc354b690404d7cd4ec57c16d3fbe98ffffffffffffffffffffffffffffffffffffffffffffffffffffffffea507dd7,5e0d76564aae92cb347e01a62afd389a9aa401c76c8dd227543dc9cd0efe685a,valid_x(x1);t>=p +bcaf7219f2f6fbf55fe5e062dce0e48c18f68103f10b8198e974c184750e1be3932016cbf69c4471bd1f656c6a107f1973de4af7086db897277060e25677f19a,2d97f96cac882dfe73dc44db6ce0f1d31d6241358dd5d74eb3d3b50003d24c2b,valid_x(x3);valid_x(x2);valid_x(x1) +bcaf7219f2f6fbf55fe5e062dce0e48c18f68103f10b8198e974c184750e1be3ffffffffffffffffffffffffffffffffffffffffffffffffffffffff6507d09a,e7008afe6e8cbd5055df120bd748757c686dadb41cce75e4addcc5e02ec02b44,valid_x(x3);valid_x(x2);valid_x(x1);t>=p +c5981bae27fd84401c72a155e5707fbb811b2b620645d1028ea270cbe0ee225d4b62aa4dca6506c1acdbecc0552569b4b21436a5692e25d90d3bc2eb7ce24078,948b40e7181713bc018ec1702d3d054d15746c59a7020730dd13ecf985a010d7,(u'^3+t'^2+7)%p=0;valid_x(x3) +c894ce48bfec433014b931a6ad4226d7dbd8eaa7b6e3faa8d0ef94052bcf8cff336eeb3919e2b4efb746c7f71bbca7e9383230fbbc48ffafe77e8bcc69542471,f1c91acdc2525330f9b53158434a4d43a1c547cff29f15506f5da4eb4fe8fa5a,(u'^3-t'^2+7)%p=0;valid_x(x3);valid_x(x2);valid_x(x1) +cbb0deab125754f1fdb2038b0434ed9cb3fb53ab735391129994a535d925f6730000000000000000000000000000000000000000000000000000000000000000,872d81ed8831d9998b67cb7105243edbf86c10edfebb786c110b02d07b2e67cd,t%p=0;(u'^3-t'^2+7)%p=0;valid_x(x3);valid_x(x2);valid_x(x1) +d917b786dac35670c330c9c5ae5971dfb495c8ae523ed97ee2420117b171f41effffffffffffffffffffffffffffffffffffffffffffffffffffffff2001f6f6,e45b71e110b831f2bdad8651994526e58393fde4328b1ec04d59897142584691,valid_x(x3);t>=p +e28bd8f5929b467eb70e04332374ffb7e7180218ad16eaa46b7161aa679eb4260000000000000000000000000000000000000000000000000000000000000000,66b8c980a75c72e598d383a35a62879f844242ad1e73ff12edaa59f4e58632b5,t%p=0;valid_x(x3) +e28bd8f5929b467eb70e04332374ffb7e7180218ad16eaa46b7161aa679eb426fffffffffffffffffffffffffffffffffffffffffffffffffffffffefffffc2f,66b8c980a75c72e598d383a35a62879f844242ad1e73ff12edaa59f4e58632b5,t%p=0;valid_x(x3);t>=p +e7ee5814c1706bf8a89396a9b032bc014c2cac9c121127dbf6c99278f8bb53d1dfd04dbcda8e352466b6fcd5f2dea3e17d5e133115886eda20db8a12b54de71b,e842c6e3529b234270a5e97744edc34a04d7ba94e44b6d2523c9cf0195730a50,(u'^3+t'^2+7)%p=0;valid_x(x3);valid_x(x2);valid_x(x1) +f292e46825f9225ad23dc057c1d91c4f57fcb1386f29ef10481cb1d22518593fffffffffffffffffffffffffffffffffffffffffffffffffffffffff7011c989,3cea2c53b8b0170166ac7da67194694adacc84d56389225e330134dab85a4d55,(u'^3-t'^2+7)%p=0;valid_x(x3);t>=p +fffffffffffffffffffffffffffffffffffffffffffffffffffffffefffffc2f0000000000000000000000000000000000000000000000000000000000000000,edd1fd3e327ce90cc7a3542614289aee9682003e9cf7dcc9cf2ca9743be5aa0c,u%p=0;t%p=0;valid_x(x2);u>=p +fffffffffffffffffffffffffffffffffffffffffffffffffffffffefffffc2f01d3475bf7655b0fb2d852921035b2ef607f49069b97454e6795251062741771,b5da00b73cd6560520e7c364086e7cd23a34bf60d0e707be9fc34d4cd5fdfa2c,u%p=0;valid_x(x1);u>=p +fffffffffffffffffffffffffffffffffffffffffffffffffffffffefffffc2f4218f20ae6c646b363db68605822fb14264ca8d2587fdd6fbc750d587e76a7ee,aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa9fffffd6b,u%p=0;(u'^3-t'^2+7)%p=0;valid_x(x3);u>=p +fffffffffffffffffffffffffffffffffffffffffffffffffffffffefffffc2f82277c4a71f9d22e66ece523f8fa08741a7c0912c66a69ce68514bfd3515b49f,f482f2e241753ad0fb89150d8491dc1e34ff0b8acfbb442cfe999e2e5e6fd1d2,u%p=0;valid_x(x3);valid_x(x2);valid_x(x1);u>=p +fffffffffffffffffffffffffffffffffffffffffffffffffffffffefffffc2f8421cc930e77c9f514b6915c3dbe2a94c6d8f690b5b739864ba6789fb8a55dd0,9f59c40275f5085a006f05dae77eb98c6fd0db1ab4a72ac47eae90a4fc9e57e0,u%p=0;valid_x(x2);u>=p +fffffffffffffffffffffffffffffffffffffffffffffffffffffffefffffc2fd19c182d2759cd99824228d94799f8c6557c38a1c0d6779b9d4b729c6f1ccc42,70720db7e238d04121f5b1afd8cc5ad9d18944c6bdc94881f502b7a3af3aecff,u%p=0;valid_x(x3);u>=p +fffffffffffffffffffffffffffffffffffffffffffffffffffffffefffffc2ffffffffffffffffffffffffffffffffffffffffffffffffffffffffefffffc2f,edd1fd3e327ce90cc7a3542614289aee9682003e9cf7dcc9cf2ca9743be5aa0c,u%p=0;t%p=0;valid_x(x2);u>=p;t>=p +fffffffffffffffffffffffffffffffffffffffffffffffffffffffefffffc2fffffffffffffffffffffffffffffffffffffffffffffffffffffffff2664bbd5,50873db31badcc71890e4f67753a65757f97aaa7dd5f1e82b753ace32219064b,u%p=0;valid_x(x3);valid_x(x2);valid_x(x1);u>=p;t>=p +fffffffffffffffffffffffffffffffffffffffffffffffffffffffefffffc2fffffffffffffffffffffffffffffffffffffffffffffffffffffffff7028de7d,1eea9cc59cfcf2fa151ac6c274eea4110feb4f7b68c5965732e9992e976ef68e,u%p=0;valid_x(x2);u>=p;t>=p +fffffffffffffffffffffffffffffffffffffffffffffffffffffffefffffc2fffffffffffffffffffffffffffffffffffffffffffffffffffffffffcbcfb7e7,12303941aedc208880735b1f1795c8e55be520ea93e103357b5d2adb7ed59b8e,u%p=0;valid_x(x1);u>=p;t>=p +fffffffffffffffffffffffffffffffffffffffffffffffffffffffefffffc2ffffffffffffffffffffffffffffffffffffffffffffffffffffffffff3113ad9,7eed6b70e7b0767c7d7feac04e57aa2a12fef5e0f48f878fcbb88b3b6b5e0783,u%p=0;valid_x(x3);u>=p;t>=p +ffffffffffffffffffffffffffffffffffffffffffffffffffffffff13cea4a70000000000000000000000000000000000000000000000000000000000000000,649984435b62b4a25d40c6133e8d9ab8c53d4b059ee8a154a3be0fcf4e892edb,t%p=0;valid_x(x1);u>=p +ffffffffffffffffffffffffffffffffffffffffffffffffffffffff13cea4a7fffffffffffffffffffffffffffffffffffffffffffffffffffffffefffffc2f,649984435b62b4a25d40c6133e8d9ab8c53d4b059ee8a154a3be0fcf4e892edb,t%p=0;valid_x(x1);u>=p;t>=p +ffffffffffffffffffffffffffffffffffffffffffffffffffffffff15028c590063f64d5a7f1c14915cd61eac886ab295bebd91992504cf77edb028bdd6267f,3fde5713f8282eead7d39d4201f44a7c85a5ac8a0681f35e54085c6b69543374,(u'^3+t'^2+7)%p=0;valid_x(x2);u>=p +ffffffffffffffffffffffffffffffffffffffffffffffffffffffff2715de860000000000000000000000000000000000000000000000000000000000000000,3524f77fa3a6eb4389c3cb5d27f1f91462086429cd6c0cb0df43ea8f1e7b3fb4,t%p=0;valid_x(x3);valid_x(x2);valid_x(x1);u>=p +ffffffffffffffffffffffffffffffffffffffffffffffffffffffff2715de86fffffffffffffffffffffffffffffffffffffffffffffffffffffffefffffc2f,3524f77fa3a6eb4389c3cb5d27f1f91462086429cd6c0cb0df43ea8f1e7b3fb4,t%p=0;valid_x(x3);valid_x(x2);valid_x(x1);u>=p;t>=p +ffffffffffffffffffffffffffffffffffffffffffffffffffffffff2c2c5709e7156c417717f2feab147141ec3da19fb759575cc6e37b2ea5ac9309f26f0f66,d2469ab3e04acbb21c65a1809f39caafe7a77c13d10f9dd38f391c01dc499c52,(u'^3-t'^2+7)%p=0;valid_x(x3);valid_x(x2);valid_x(x1);u>=p +ffffffffffffffffffffffffffffffffffffffffffffffffffffffff3a08cc1efffffffffffffffffffffffffffffffffffffffffffffffffffffffff760e9f0,38e2a5ce6a93e795e16d2c398bc99f0369202ce21e8f09d56777b40fc512bccc,valid_x(x3);u>=p;t>=p +ffffffffffffffffffffffffffffffffffffffffffffffffffffffff3e91257d932016cbf69c4471bd1f656c6a107f1973de4af7086db897277060e25677f19a,864b3dc902c376709c10a93ad4bbe29fce0012f3dc8672c6286bba28d7d6d6fc,valid_x(x3);u>=p +ffffffffffffffffffffffffffffffffffffffffffffffffffffffff795d6c1c322cadf599dbb86481522b3cc55f15a67932db2afa0111d9ed6981bcd124bf44,766dfe4a700d9bee288b903ad58870e3d4fe2f0ef780bcac5c823f320d9a9bef,(u'^3+t'^2+7)%p=0;valid_x(x1);u>=p +ffffffffffffffffffffffffffffffffffffffffffffffffffffffff8e426f0392389078c12b1a89e9542f0593bc96b6bfde8224f8654ef5d5cda935a3582194,faec7bc1987b63233fbc5f956edbf37d54404e7461c58ab8631bc68e451a0478,valid_x(x1);u>=p +ffffffffffffffffffffffffffffffffffffffffffffffffffffffff91192139ffffffffffffffffffffffffffffffffffffffffffffffffffffffff45f0f1eb,ec29a50bae138dbf7d8e24825006bb5fc1a2cc1243ba335bc6116fb9e498ec1f,valid_x(x2);u>=p;t>=p +ffffffffffffffffffffffffffffffffffffffffffffffffffffffff98eb9ab76e84499c483b3bf06214abfe065dddf43b8601de596d63b9e45a166a580541fe,1e0ff2dee9b09b136292a9e910f0d6ac3e552a644bba39e64e9dd3e3bbd3d4d4,(u'^3-t'^2+7)%p=0;valid_x(x3);u>=p +ffffffffffffffffffffffffffffffffffffffffffffffffffffffff9b77b7f2c74d99efceaa550f1ad1c0f43f46e7ff1ee3bd0162b7bf55f2965da9c3450646,8b7dd5c3edba9ee97b70eff438f22dca9849c8254a2f3345a0a572ffeaae0928,valid_x(x2);u>=p +ffffffffffffffffffffffffffffffffffffffffffffffffffffffff9b77b7f2ffffffffffffffffffffffffffffffffffffffffffffffffffffffff156ca896,0881950c8f51d6b9a6387465d5f12609ef1bb25412a08a74cb2dfb200c74bfbf,valid_x(x3);valid_x(x2);valid_x(x1);u>=p;t>=p +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffa2f5cd838816c16c4fe8a1661d606fdb13cf9af04b979a2e159a09409ebc8645d58fde02,2f083207b9fd9b550063c31cd62b8746bd543bdc5bbf10e3a35563e927f440c8,(u'^3+t'^2+7)%p=0;valid_x(x3);valid_x(x2);valid_x(x1);u>=p +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffb13f75c00000000000000000000000000000000000000000000000000000000000000000,4f51e0be078e0cddab2742156adba7e7a148e73157072fd618cd60942b146bd0,t%p=0;valid_x(x3);u>=p +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffb13f75c0fffffffffffffffffffffffffffffffffffffffffffffffffffffffefffffc2f,4f51e0be078e0cddab2742156adba7e7a148e73157072fd618cd60942b146bd0,t%p=0;valid_x(x3);u>=p;t>=p +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffe7bc1f8d0000000000000000000000000000000000000000000000000000000000000000,16c2ccb54352ff4bd794f6efd613c72197ab7082da5b563bdf9cb3edaafe74c2,t%p=0;valid_x(x2);u>=p +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffe7bc1f8dfffffffffffffffffffffffffffffffffffffffffffffffffffffffefffffc2f,16c2ccb54352ff4bd794f6efd613c72197ab7082da5b563bdf9cb3edaafe74c2,t%p=0;valid_x(x2);u>=p;t>=p +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffef64d162750546ce42b0431361e52d4f5242d8f24f33e6b1f99b591647cbc808f462af51,d41244d11ca4f65240687759f95ca9efbab767ededb38fd18c36e18cd3b6f6a9,(u'^3+t'^2+7)%p=0;valid_x(x3);u>=p +fffffffffffffffffffffffffffffffffffffffffffffffffffffffff0e5be52372dd6e894b2a326fc3605a6e8f3c69c710bf27d630dfe2004988b78eb6eab36,64bf84dd5e03670fdb24c0f5d3c2c365736f51db6c92d95010716ad2d36134c8,valid_x(x3);valid_x(x2);valid_x(x1);u>=p +fffffffffffffffffffffffffffffffffffffffffffffffffffffffffefbb982fffffffffffffffffffffffffffffffffffffffffffffffffffffffff6d6db1f,1c92ccdfcf4ac550c28db57cff0c8515cb26936c786584a70114008d6c33a34b,valid_x(x1);u>=p;t>=p diff --git a/bip-0324/gen_test_vectors.py b/bip-0324/gen_test_vectors.py new file mode 100644 index 0000000000..05b30a8335 --- /dev/null +++ b/bip-0324/gen_test_vectors.py @@ -0,0 +1,418 @@ +"""Generate the BIP-0324 test vectors.""" + +import csv +import hashlib +import os +import sys +from reference import ( + FE, + GE, + MINUS_3_SQRT, + hkdf_sha256, + SECP256K1_G, + ellswift_decode, + ellswift_ecdh_xonly, + xswiftec_inv, + xswiftec, + v2_ecdh, + initialize_v2_transport, + v2_enc_packet +) + +FILENAME_PACKET_TEST = os.path.join(sys.path[0], 'packet_encoding_test_vectors.csv') +FILENAME_XSWIFTEC_INV_TEST = os.path.join(sys.path[0], 'xswiftec_inv_test_vectors.csv') +FILENAME_ELLSWIFT_DECODE_TEST = os.path.join(sys.path[0], 'ellswift_decode_test_vectors.csv') + +def xswiftec_flagged(u, t, simplified=False): + """A variant of xswiftec which also returns 'flags', describing conditions encountered.""" + flags = [] + if u == 0: + flags.append("u%p=0") + u = FE(1) + if t == 0: + flags.append("t%p=0") + t = FE(1) + if u**3 + t**2 + 7 == 0: + flags.append("(u'^3+t'^2+7)%p=0") + t = 2 * t + X = (u**3 + 7 - t**2) / (2 * t) + Y = (X + t) / (MINUS_3_SQRT * u) + if X == 0: + if not simplified: + flags.append("(u'^3-t'^2+7)%p=0") + x3 = u + 4 * Y**2 + if GE.is_valid_x(x3): + flags.append("valid_x(x3)") + x2 = (-X / Y - u) / 2 + if GE.is_valid_x(x2): + flags.append("valid_x(x2)") + x1 = (X / Y - u) / 2 + if GE.is_valid_x(x1): + flags.append("valid_x(x1)") + for x in (x3, x2, x1): + if GE.is_valid_x(x): + break + return x, flags + + +def ellswift_create_deterministic(seed, features): + """This is a variant of ellswift_create which doesn't use randomness. + + features is an integer selecting some properties of the result: + - (f & 3) == 0: only x1 is valid on decoding (see xswiftec{_flagged}) + - (f & 3) == 1: only x2 is valid on decoding + - (f & 3) == 2: only x3 is valid on decoding + - (f & 3) == 3: x1,x2,x3 are all valid on decoding + - (f & 4) == 4: u >= p + - (f & 8) == 8: u mod n == 0 + + Returns privkey, ellswift + """ + + cnt = 0 + while True: + sec = hkdf_sha256(32, seed, (cnt).to_bytes(4, 'little'), b"sec") + xval = (int.from_bytes(sec, 'big') * SECP256K1_G).x + cnt += 1 + if features & 8: + u = 0 + if features & 4: + u += FE.SIZE + else: + udat = hkdf_sha256(64, seed, (cnt).to_bytes(4, 'little'), b"u") + if features & 4: + u = FE.SIZE + 1 + int.from_bytes(udat, 'big') % (2**256 - FE.SIZE - 1) + else: + u = 1 + int.from_bytes(udat, 'big') % (FE.SIZE - 1) + case = hkdf_sha256(1, seed, (cnt).to_bytes(4, 'little'), b"case")[0] & 7 + coru = FE(u) + ((features & 8) == 8) + t = xswiftec_inv(xval, coru, case) + if t is None: + continue + assert xswiftec(FE(u), t) == xval + x2, flags = xswiftec_flagged(FE(u), t) + assert x2 == xval + have_x1 = "valid_x(x1)" in flags + have_x2 = "valid_x(x2)" in flags + have_x3 = "valid_x(x3)" in flags + if (features & 4) == 0 and not (have_x1 and not have_x2 and not have_x3): + continue + if (features & 4) == 1 and not (not have_x1 and have_x2 and not have_x3): + continue + if (features & 4) == 2 and not (not have_x1 and not have_x2 and have_x3): + continue + if (features & 4) == 3 and not (have_x1 and have_x2 and have_x3): + continue + return sec, u.to_bytes(32, 'big') + t.to_bytes() + +def ellswift_decode_flagged(ellswift, simplified=False): + """Decode a 64-byte ElligatorSwift encoded coordinate, returning byte array + flag string.""" + uv = int.from_bytes(ellswift[:32], 'big') + tv = int.from_bytes(ellswift[32:], 'big') + x, flags = xswiftec_flagged(FE(uv), FE(tv)) + if not simplified: + if uv >= FE.SIZE: + flags.append("u>=p") + if tv >= FE.SIZE: + flags.append("t>=p") + return int(x).to_bytes(32, 'big'), ";".join(flags) + +def random_fe_int(_, seed, i, p): + """Function to use in tuple_expand, generating a random integer in 0..p-1.""" + rng_out = hkdf_sha256(64, seed, i.to_bytes(4, 'little'), b"v%i_fe" % p) + return int.from_bytes(rng_out, 'big') % FE.SIZE + +def random_fe_int_high(_, seed, i, p): + """Function to use in tuple_expand, generating a random integer in p..2^256-1.""" + rng_out = hkdf_sha256(64, seed, i.to_bytes(4, 'little'), b"v%i_fe_high" % p) + return FE.SIZE + int.from_bytes(rng_out, 'big') % (2**256 - FE.SIZE) + +def fn_of(p_in, fn): + """Function to use in tuple_expand, to pick one variable in function of another.""" + def inner(vs, _seed, _i, p): + assert p != p_in + if isinstance(vs[p_in], int): + return fn(vs[p_in]) + return None + return inner + +def tuple_expand(out, tuplespec, prio, seed=None, cnt=1): + """Given a tuple specification, expand it cnt times, and add results to out. + + Expansion is defined recursively: + - If any of the spec elements is a list, each element of the list results + in an expansion (by replacing the list with its element). + - If any of the spec elements is a function, that function is invoked with + (spec, seed, expansion count, index in spec) as arguments. If the function + needs to wait for other indices to be expanded, it can return None. + + The output consists of (prio, expansion count, SHA256(result), result, seed) + tuples.""" + + def recurse(vs, seed, i, change_pos=None, change=None): + if change_pos is not None: + vs = list(vs) + vs[change_pos] = change + for p, v in enumerate(vs): + if v is None: + return + if isinstance(v, list): + for ve in v: + recurse(vs, seed, i, p, ve) + return + if callable(v): + res = v(vs, seed, i, p) + if res is not None: + recurse(vs, seed, i, p, res) + return + h = hashlib.sha256() + for v in vs: + h.update(int(v).to_bytes(32, 'big')) + out.append((prio, i, h.digest(), vs, seed)) + for i in range(cnt): + recurse(tuplespec, seed, i) + +def gen_ellswift_decode_cases(seed, simplified=False): + """Generate a set of interesting (ellswift, x, flags) ellswift decoding cases.""" + inputs = [] + + # Aggregate for use in tuple_expand, expanding to int in 0..p-1, and one in p..2^256-1. + RANDOM_VAL = [random_fe_int, random_fe_int_high] + # Aggregate for use in tuple_expand, expanding to integers which %p equal 0. + ZERO_VAL = [0, FE.SIZE] + # Helpers for constructing u and t values such that u^3+t^2+7=0 or u^3-t^2+7=0. + T_FOR_SUM_ZERO = fn_of(0, lambda u: (-FE(u)**3 - 7).sqrts()) + T_FOR_DIFF_ZERO = fn_of(0, lambda u: (FE(u)**3 + 7).sqrts()) + U_FOR_SUM_ZERO = fn_of(1, lambda t: (-FE(t)**2 - 7).cbrts()) + U_FOR_DIFF_ZERO = fn_of(1, lambda t: (FE(t)**2 - 7).cbrts()) + + tuple_expand(inputs, [RANDOM_VAL, RANDOM_VAL], 0, seed + b"random", 64) + tuple_expand(inputs, [RANDOM_VAL, T_FOR_SUM_ZERO], 1, seed + b"t=sqrt(-u^3-7)", 64) + tuple_expand(inputs, [U_FOR_SUM_ZERO, RANDOM_VAL], 1, seed + b"u=cbrt(-t^2-7)", 64) + tuple_expand(inputs, [RANDOM_VAL, T_FOR_DIFF_ZERO], 1, seed + b"t=sqrt(u^3+7)", 64) + tuple_expand(inputs, [U_FOR_DIFF_ZERO, RANDOM_VAL], 1, seed + b"u=cbrt(t^2-7)", 64) + tuple_expand(inputs, [ZERO_VAL, RANDOM_VAL], 2, seed + b"u=0", 64) + tuple_expand(inputs, [RANDOM_VAL, ZERO_VAL], 2, seed + b"t=0", 64) + tuple_expand(inputs, [ZERO_VAL, FE(8).sqrts()], 3, seed + b"u=0;t=sqrt(8)") + tuple_expand(inputs, [FE(-8).cbrts(), ZERO_VAL], 3, seed + b"t=0;u=cbrt(-8)") + tuple_expand(inputs, [FE(-6).cbrts(), ZERO_VAL], 3, seed + b"t=0;u=cbrt(-6)") + tuple_expand(inputs, [ZERO_VAL, ZERO_VAL], 3, seed + b"u=0;t=0") + # Unused. + tuple_expand(inputs, [ZERO_VAL, FE(-8).sqrts()], 4, seed + b"u=0;t=sqrt(-8)") + + seen = set() + cases = [] + for _prio, _cnt, _hash, vs, _seed in sorted(inputs): + inp = int(vs[0]).to_bytes(32, 'big') + int(vs[1]).to_bytes(32, 'big') + outp, flags = ellswift_decode_flagged(inp, simplified) + if flags not in seen: + cases.append((inp, outp, flags)) + seen.add(flags) + + return cases + +def gen_all_ellswift_decode_vectors(fil): + """Generate all xelligatorswift decoding test vectors.""" + + cases = gen_ellswift_decode_cases(b"") + writer = csv.DictWriter(fil, ["ellswift", "x", "comment"]) + writer.writeheader() + for val, x, flags in sorted(cases): + writer.writerow({"ellswift": val.hex(), "x": x.hex(), "comment": flags}) + +def xswiftec_inv_flagged(x, u, case): + """A variant of xswiftec_inv which also returns flags, describing conditions encountered.""" + + flags = [] + + if case & 2 == 0: + if GE.is_valid_x(-x - u): + flags.append("bad[valid_x(-x-u)]") + return None, flags + v = x if case & 1 == 0 else -x - u + if v == 0: + flags.append("info[v=0]") + s = -(u**3 + 7) / (u**2 + u*v + v**2) + assert s != 0 # would imply X=0 on curve + else: + s = x - u + if s == 0: + flags.append("bad[s=0]") + return None, flags + q = (-s * (4 * (u**3 + 7) + 3 * s * u**2)) + if q == 0: + flags.append("info[q=0]") + r = q.sqrt() + if r is None: + flags.append("bad[non_square(q)]") + return None, flags + if case & 1: + if r == 0: + flags.append("bad[r=0]") + return None, flags + r = -r + v = (-u + r / s) / 2 + if v == 0: + flags.append("info[v=0]") + w = s.sqrt() + assert w != 0 + if w is None: + flags.append("bad[non_square(s)]") + return None, flags + if case & 4: + w = -w + Y = w / 2 + assert Y != 0 + X = 2 * Y * (v + u / 2) + if X == 0: + flags.append("info[X=0]") + flags.append("ok") + return w * (u * (MINUS_3_SQRT - 1) / 2 - v), flags + +def xswiftec_inv_combo_flagged(x, u): + """Compute the aggregate results and flags from xswiftec_inv_flagged for case=0..7.""" + ts = [] + allflags = [] + for case in range(8): + t, flags = xswiftec_inv_flagged(x, u, case) + if t is not None: + assert x == xswiftec(u, t) + ts.append(t) + allflags.append(f"case{case}:{'&'.join(flags)}") + return ts, ";".join(allflags) + +def gen_all_xswiftec_inv_vectors(fil): + """Generate all xswiftec_inv test vectors.""" + + # Two constants used below. Compute them only once. + C1 = (FE(MINUS_3_SQRT) - 1) / 2 + C2 = (-FE(MINUS_3_SQRT) - 1) / 2 + # Helper functions that pick x and u with special properties. + TRIGGER_Q_ZERO = fn_of(1, lambda u: (FE(u)**3 + 28) / (FE(-3) * FE(u)**2)) + TRIGGER_DIVZERO_A = fn_of(1, lambda u: FE(u) * C1) + TRIGGER_DIVZERO_B = fn_of(1, lambda u: FE(u) * C2) + TRIGGER_V_ZERO = fn_of(1, lambda u: FE(-7) / FE(u)**2) + TRIGGER_X_ZERO = fn_of(0, lambda x: FE(-2) * FE(x)) + + inputs = [] + tuple_expand(inputs, [random_fe_int, random_fe_int], 0, b"uniform", 256) + tuple_expand(inputs, [TRIGGER_Q_ZERO, random_fe_int], 1, b"x=-(u^3+28)/(3*u^2)", 64) + tuple_expand(inputs, [TRIGGER_V_ZERO, random_fe_int], 1, b"x=-7/u^2", 512) + tuple_expand(inputs, [random_fe_int, fn_of(0, lambda x: x)], 2, b"u=x", 64) + tuple_expand(inputs, [random_fe_int, fn_of(0, lambda x: -FE(x))], 2, b"u=-x", 64) + # Unused. + tuple_expand(inputs, [TRIGGER_DIVZERO_A, random_fe_int], 3, b"x=u*(sqrt(-3)-1)/2", 64) + tuple_expand(inputs, [TRIGGER_DIVZERO_B, random_fe_int], 3, b"x=u*(-sqrt(-3)-1)/2", 64) + tuple_expand(inputs, [random_fe_int, TRIGGER_X_ZERO], 3, b"u=-2x", 64) + + seen = set() + cases = [] + for _prio, _cnt, _hash, vs, _seed in sorted(inputs): + x, u = FE(vs[0]), FE(vs[1]) + if u == 0: + continue + if not GE.is_valid_x(x): + continue + ts, flags = xswiftec_inv_combo_flagged(x, u) + if flags not in seen: + cases.append((int(u), int(x), ts, flags)) + seen.add(flags) + + writer = csv.DictWriter(fil, ["u", "x"] + [f"case{c}_t" for c in range(8)] + ["comment"]) + writer.writeheader() + for u, x, ts, flags in sorted(cases): + row = {"u": FE(u), "x": FE(x), "comment": flags} + for c in range(8): + if ts[c] is not None: + row[f"case{c}_t"] = FE(ts[c]) + writer.writerow(row) + +def gen_packet_encoding_vector(case): + """Given a dict case with specs, construct a packet_encoding test vector as a CSV line.""" + ikm = str(case).encode('utf-8') + in_initiating = case["init"] + in_ignore = int(case["ignore"]) + in_priv_ours, in_ellswift_ours = ellswift_create_deterministic(ikm, case["features"]) + mid_x_ours = (int.from_bytes(in_priv_ours, 'big') * SECP256K1_G).x.to_bytes() + assert mid_x_ours == ellswift_decode(in_ellswift_ours) + in_ellswift_theirs = case["theirs"] + in_contents = hkdf_sha256(case["contentlen"], ikm, b"contents", b"") + contents = in_contents * case["multiply"] + in_aad = hkdf_sha256(case["aadlen"], ikm, b"aad", b"") + mid_shared_secret = v2_ecdh(in_priv_ours, in_ellswift_theirs, in_ellswift_ours, in_initiating) + + peer = initialize_v2_transport(mid_shared_secret, in_initiating) + for _ in range(case["idx"]): + v2_enc_packet(peer, b"") + ciphertext = v2_enc_packet(peer, contents, in_aad, case["ignore"]) + long_msg = len(ciphertext) > 128 + + return { + "in_idx": case['idx'], + "in_priv_ours": in_priv_ours.hex(), + "in_ellswift_ours": in_ellswift_ours.hex(), + "in_ellswift_theirs": in_ellswift_theirs.hex(), + "in_initiating": int(in_initiating), + "in_contents": in_contents.hex(), + "in_multiply": case['multiply'], + "in_aad": in_aad.hex(), + "in_ignore": in_ignore, + "mid_x_ours": mid_x_ours.hex(), + "mid_x_theirs": ellswift_decode(in_ellswift_theirs).hex(), + "mid_x_shared": ellswift_ecdh_xonly(in_ellswift_theirs, in_priv_ours).hex(), + "mid_shared_secret": mid_shared_secret.hex(), + "mid_initiator_l": peer['initiator_L'].hex(), + "mid_initiator_p": peer['initiator_P'].hex(), + "mid_responder_l": peer['responder_L'].hex(), + "mid_responder_p": peer['responder_P'].hex(), + "mid_send_garbage_terminator": peer["send_garbage_terminator"].hex(), + "mid_recv_garbage_terminator": peer["recv_garbage_terminator"].hex(), + "out_session_id": peer["session_id"].hex(), + "out_ciphertext": "" if long_msg else ciphertext.hex(), + "out_ciphertext_endswith": ciphertext[-128:].hex() if long_msg else "" + } + +def gen_all_packet_encoding_vectors(fil): + """Return a list of CSV lines, one for each packet encoding vector.""" + + ellswift = gen_ellswift_decode_cases(b"simplified_", simplified=True) + ellswift.sort(key=lambda x: hashlib.sha256(b"simplified:" + x[0]).digest()) + + fields = [ + "in_idx", "in_priv_ours", "in_ellswift_ours", "in_ellswift_theirs", "in_initiating", + "in_contents", "in_multiply", "in_aad", "in_ignore", "mid_x_ours", "mid_x_theirs", + "mid_x_shared", "mid_shared_secret", "mid_initiator_l", "mid_initiator_p", + "mid_responder_l", "mid_responder_p", "mid_send_garbage_terminator", + "mid_recv_garbage_terminator", "out_session_id", "out_ciphertext", "out_ciphertext_endswith" + ] + + writer = csv.DictWriter(fil, fields) + writer.writeheader() + for case in [ + {"init": True, "contentlen": 1, "multiply": 1, "aadlen": 0, "ignore": False, "idx": 1, + "theirs": ellswift[0][0], "features": 0}, + {"init": False, "contentlen": 17, "multiply": 1, "aadlen": 0, "ignore": False, "idx": 999, + "theirs": ellswift[1][0], "features": 1}, + {"init": True, "contentlen": 63, "multiply": 1, "aadlen": 4095, "ignore": False, "idx": 0, + "theirs": ellswift[2][0], "features": 2}, + {"init": False, "contentlen": 128, "multiply": 1, "aadlen": 0, "ignore": True, "idx": 223, + "theirs": ellswift[3][0], "features": 3}, + {"init": True, "contentlen": 193, "multiply": 1, "aadlen": 0, "ignore": False, "idx": 448, + "theirs": ellswift[4][0], "features": 4}, + {"init": False, "contentlen": 41, "multiply": 97561, "aadlen": 0, "ignore": False, + "idx": 673, "theirs": ellswift[5][0], "features": 5}, + {"init": True, "contentlen": 241, "multiply": 69615, "aadlen": 0, "ignore": True, + "idx": 1024, "theirs": ellswift[6][0], "features": 6}, + ]: + writer.writerow(gen_packet_encoding_vector(case)) + +if __name__ == "__main__": + print(f"Generating {FILENAME_PACKET_TEST}...") + with open(FILENAME_PACKET_TEST, "w", encoding="utf-8") as fil_packet: + gen_all_packet_encoding_vectors(fil_packet) + print(f"Generating {FILENAME_XSWIFTEC_INV_TEST}...") + with open(FILENAME_XSWIFTEC_INV_TEST, "w", encoding="utf-8") as fil_xswiftec_inv: + gen_all_xswiftec_inv_vectors(fil_xswiftec_inv) + print(f"Generating {FILENAME_ELLSWIFT_DECODE_TEST}...") + with open(FILENAME_ELLSWIFT_DECODE_TEST, "w", encoding="utf-8") as fil_ellswift_decode: + gen_all_ellswift_decode_vectors(fil_ellswift_decode) diff --git a/bip-0324/packet_encoding_test_vectors.csv b/bip-0324/packet_encoding_test_vectors.csv index 519b77a925..4f70b92daf 100644 --- a/bip-0324/packet_encoding_test_vectors.csv +++ b/bip-0324/packet_encoding_test_vectors.csv @@ -1,8 +1,8 @@ -in_idx,in_priv_ours,in_ellswift_ours,in_ellswift_theirs,in_initiating,in_content,in_multiply,in_aad,in_ignore,mid_x_ours,mid_x_shared,mid_shared_secret,mid_initiator_l,mid_initiator_p,mid_responder_l,mid_responder_p,mid_send_garbage_terminator,mid_recv_garbage_terminator,mid_session_id,out_ciphertext,out_ciphertext_endswith -1,e79f04ad4c684525ff3e3cf7c19f4cdb11193d387d7f3fe82a948a0c3165f5fe,4eff53ea1945e57b5d170565e760d771e5d496101c1005c302fd687af80d8b858c5a681c474fc4c0546ee464a1b95899ecb9d4f50c2c0854fe029fc054ae6777,824a1da0530fa695b95b375fee2a56ec96ce375ddd2fcf8367cc8ec1c0b751a3304bbef5dc96543acaac50c24be8cb39906ef8521727de0c6e96c2060a026bd7,1,1f,1,,0,b63341693587b4944b865485cffcc34707b3e0760a6ba8d1d402fc1c996c4e91,961fa6c9491bde887a6e67898c9335579d1931b435af16d969f3c9f12e58c698,05ac09c882b2cddd57fd4a1a14f93ae78d78a2ab2adb8cb6d67176cdb3101e15,c845747c92a2f0d83058ccceee69322cfd84cf3b086c30790f2a8789b303defc,3d0c55fa080de10236da830c7b092f63f6897c5243259adcedc4288a847ee9bc,f32949925481a88ad5246c408aeb8b9c0dc5dbc21fd6e5484331e1c0cd0ef6d6,5b94f3fce2b276e9d7ef5646657e61dbbc8ea27a9bf531ce23c553de1fdfd27d,38d7b65a6d58a08b2506e799caacd4f6,d6156094782d98fa27f37758dcd0677f,4418cf03c0d7cd5849022a7976014f234b4d4f5c18a6d3a6540c11e01a7180c1,d88ea86cdd6b61592e038741b474eeef0de0802412, -999,53a915e6d8f6c5bbb93e537081085e9e642dc525649acf05be74e3a825e20921,715d7b8357dd4d15a07b3f8c6764ebd9927140f75047fb50478c33ea8889d710511cdf39aa0fd6b1e94ea660d87f9d97bffc548646f9e2aaebc1468fe563fb97,cea7abc3112397b894bd3e89a615248af473f897bbdd30997c20e53e7ce499a295e55c4c5655cd3d21191e76c8af0aa1bbea10fd1b540a42d0fbed388dc59877,0,e4,1,,0,533bbaefc711f303be5e8271fdecfd31d03abd42128ff73479e2a427059e4a74,ed679745127d32714ff84bcce7651a14b9f275bf4b18bc8e880ff51cd7ac012b,08cbe6a86ff92a9757b2aeea92b8b2f4d78426786a2caec99c3cc73d7dda47ab,953a372f0d3933afef342fec533fa4fed644cc1cbc9252d31883e10fbca9b81a,e8c1759d865d59f37e5cf0404296fb0530f0fc601ad783853791e5459ca7f135,52925c95091e7dac8e580e9a0548e18915e01919a416c5aac22096b8bab17c31,ba778684047d705839590c466daef7c0ac53a3f8790b9744f154712e5644c647,0442c66254045c5018d828d42afaa69f,930c6d7cbf8c7c2006ed287c2ba6d941,9619dd4731d6160617da82da407c80732455a67b59ad7be07f86252aadb79440,0d5892533b0453c777d5ff3f217c94297e7927bb45, -0,dcf45714d450a32cdd05997b75acd34e8786969dfcff34295c287a13ba3225f0,feaa1ef8bb05296a8d5153855357868835fc5bc59d96dcbccb108e0e2dd671676c5683ad566ee4290ede5236ba6259ab47668e25853d64c0678641d27d5d0eed,c8067851ccc5df7331e9f137e66ebce1220306c4644266ff3e38436a1036ea36582dac8ce2c30de59a890f81611f866f659c1334bdd82cce1ea20ab0128b7f56,1,d3ed40688778a439928b38f1f67e04afb94843625ce1932590fe0606fcabffad25df7d2476214dc1d06aa368a4dc1e6d940a974307836e291c54f6948623ce,1,3c208efa88a545dbd29d71bbf41268fe3d123eac7e20e92be7f227b93166ee3cfd2f26639b27f20513ec5fe25c4e762096b3e49c29110a5b0d170eb9292e1ecdd3d3bab3660f9970811330d6a0f7112709666bb9d3443c9f35a84e7bde9bf2b5e29b903c64e86aca86bb5799fcf6a7416f48d98668749852c49e4cb2f3325c44d63995cea48af98bb42bcf4fbe03681bb552cf5d51b424bd53f1ffb6d6cb70af606debbe07124aeb14b28f2b26e63f3421c6ac512d5cdb7f97540f2ae64487d84dc57fb8c97f5785b60bcf12a22225988007c4dcc8895301a6e36c59f3a33ab5fa099945b1dd4d6e0a3822ffea087b01f9fb27b38c7711211c523b0e153422a5e06c8200ed45560ed4eb1317b7b730b5d31096bd3ac5cfc1e876a178851d297bec38b7a753013d7590533b5f6d654add3b38ca046d932d9739a5f0fbe6cda89cc97597a046d08b66fde7533fcb0528562960832f623dadbbe35d2d54ff15e1a9a260477169e2d8a95ec66e6ed8ccc2366f5ded2fddc2b351d6475c4b3831b6dd5c330917ea1b0b229ce719b5bd6d839861e5374f51a176b500e7546a2b4b1325be9615305d591605783279a73f28b9a281b17a45bb79029a30bf3c0b248945f4523979bbb57d69df4881d8030a4146080dbf13255b712919fb4fa016c66dd323d7a5c56b3ceeb57c4120fd554719a3851b9f3e810c4ad35b141ebff6b7c7038fdfa784681f20dcf99773721d4ec07e58a312d638fa7a90c1afbb282f30ea74d7002288441c93263eebb593f2b36cf795a8a0ee7cc119d28caa13332fdb6f2f5a6011e26e1f33941fa275d2d75af014c7739b9a999f018c7c96b854332225cb9104c016f94ff255191ab93df7c1ac29e566d672e8ccb1a4b1f53f201d583da6c410df98fc502f3b366d7624cd812cb9dedce92329b6e591366bb83c7b84c1fb30301f0199ee9ec727a33d3a9a0382af1fcf1f42e945a5acf1ea8db30a03856b8d4e0361c08028bcfc05c5204fd508e67b9924600526a1f297efd091e3a0bdc6de5a46229792069c08af9b7961ec890a3ecd6af6b08ae08f3892084a8224dd5ac50b99a7034ba48b6f599ab3e3f9fe30734229558694b8e3091161f8bd425cc2e63635c1ff82e6b6b6c89d3ea4a0dc4193b80e6014f87571bc8499107576a910f0aa50d471fb35fa07dfd0488a404ef9907ee767b1f3786415561c445e0487feed348da527bd5e8adad8de928159fb32cfac4430f51dcf710507baedf326597d8039cbecd07e9cde781d0e307d589d52b5ac262a69b366541efc78e9398dc69345f00004268c9c6ae079f09aa4e4afb830ae35715623451ee2520ef201cb5885030aec9a24d9968f8c6f25d234c69cb2f569ae2a91029b6401110fed798b2289de1e7e8621dcbe466a2fef44f09176e252dae6707ecc35695a156f6b97ab4cbaabd325fd8eb941248490824f2520f49aae6eaab95a1cf92c061c57c90910873f1866b8763b78f90b2b737020527ad16c33938ab438f0eb7845a034aec20253e71ab717c4243dbcc084f4b09a87ceeb8ef124755ac8802a66b02cf9396a700a661e16b418cf838ea1262935bb7bdeec1648f0cacb1c3236ec1856d93f172c5a9a938246606db326336425c27e2adfa428f347b9f7aa4cf1648dd4e7e66f5e8a858d499c95dc2092a0a9c8b80a05c93bd359ba5b1acc714be5a1c26be118abe8abafce45d0b9bb668a8204fccf166bb85ce17f70330c0c8ca8dc7394beee22a52624558b69b81e223c779447ee09d822dc44226432a0c86f9b25e7d85a98e187d879a4ddeeb2463d12bce3eb137e227d41e2a3df55dad1219cf18129dd23ad50930286b732037cbe7d474d06ae9f7d93f7285d2db44a8e72011460e3d34381bfe6d3221f49915312d00a5a2c7ef98ab829c995081abf9dc5551f472f34f9b39607b8e55bdb047e68582d27d2582afb9a07549c7a134a34f7d0e5a1a046cb2c3959feb98fe7a698291a2defa5fbb32473b9c9ed02d02284559325e12cda1bf0bc24ea9849fc4c87eaed71f2537242b8635fdc969872b1017d218943647fca47f9430af3b78ae2c39882118612c288d474b0298de3c3ec1efd23c65554f6d6813b4ccbf604250d295f795b679fe0ecceef5b4739eb6b418376d2fd47f95685a259cd2e2e7c00c18e93329a80a467a2a0aeb22e361732c943beb0c3dc7ca57699b690d26e6314d0b28082f8f26894c249d1587b8895dd1c5e8863bbe31cdebbce06b1d6aa17f64a125f4cbad47f2e02761259973ea164b22a580d74413d900023f03d2b2587bca60501f639050262b61a67bec83246d6ec7726f5a8a62d99c582a159db6a539ae88732f8d101d324550c9fa2dd9ba60c449d329cba823ec4b3d80d613d8df5256b3ce6ffec42ab23e5e27c001aec29d080fb519a6cce5b974f65375870c22577a2f6e76760870de047ff65dca90bfd6a303b4605b6f90631d57a8f66969ec7b96749c1f1a4ee70e8915396e114100fde651700416239d82ce7e32be5f20e5886510a37b3cd3eefe78c40ccb0425f03bcaab1aa9eeffa2f4681b7938a813f49f10a34c280de09345ffe00af340a451ebdae630ddade51a6510fdda44c3fcacfaf3f2f748d8bfe48ff71871eaec9b1790df27d4ae913d1ad16b0b33a04266540a49cb5acb8d2e16df7a35933bba7c5af1ac1f522419e76c58cddee219cf5d3229d5a27af4411ae890b4329ae5699820766b0d73841baddc11c24802684c7f7c738bf4843595dd508850b69dbd38671a385ea39188a04e7b489daabf860f4747a7172cb72a578b9903ce161e7b8a7f31ea7e8630f97571bae93f51186b94cf3c697839a6dcb2f53de9893e53a7bc2f94c9a33b2dd112cdae81f60019b7c20aa7c4921f72492329afb8841a4c80a42d1a12fcc09cf7094cadf6a48ffd6f200bd64ec17906cf4ceda6f10313bdc9ce23eba2d8d8bdba728fac90321b4893a0a61e443f611ce16486aa477ed59ccd27b58bf01a5d6d396ffa249c0728eaf87f1c41dd56c7cbc1491b369aec1a576e286fceb37746891aa37da87fa77db443bbc2df63c589f928532c6e8f4e6e3186441dca4c7118d1bfdd0a1e24087837d7dabff8d64f7df1d4cd1628eb312d6c631f092ac0172642de2f2c3c1a71573de41d2165b8f3164db59070593d8c16dd6c161303a6523a33da328fd88929e434da4d102c0ef7303eafeb6a0c3583f74bc277ae1fac36efe68b98af3340a766b0ddb61e268f3dfdc6d858a90aab491e00e010ef195bbe12435a6f225395a1c3d0ba05a094cb2c6610353fb5bdda198c6c6a1564ddf21ab51b2e13e735969d109acf4ff05ac0071d018e98b42b18692ff2dff6bb1fdc6aa630d2a978b652fa6944fbf693a251db943e10cdabfd7e26276ef16844024432286400d36d15c6acf43cb6247c6316b0729ad2a465ed215a97c937e9f9a405ae9f520d91a198cd18077e7d6134f268741b73c6ad16d1e2164102e8bd276237599ff5811837faa0b1b4ac6b61092c14da64ee83904d62c57d336b80f4476f5a9fa6f0ce6ba6b34454906bf5af60b5e42170bc358bb90927c20f753b8d69d80e5aff23daee4727bdf16e01cb549783816b9a066ade19c26bf2e30aad9f3faf35c5e17c81062f53fdb9f57c2608f6c638f0f2e8c071581107bba371eb0cfec67bd823c3d892d21d14e65b366343839bddb2b7da0d7af7e7b3b927c4d71441ecbf14f5276d0da11cf33723a10fbf1e5a97b1f95072de9872932d7bfc200080043cec2dbf2f0840be85933d8f0cb6862316d1dc18292b90b8a583df01464fe1d6a4720ea361ff2280398df7008023f364989692c86bd2ceb94e466febe2fae6bb2635c1cfcdde45c4d3b6ff55106a432a64e6827f52cc0a25f4581a058c962e99ee9b3ca2c10e32eb93729690b3066d9b9343be9863faaa0599b99daddb2e53704002cc3dc09d5df8f3bb783b37e3ef85f01b272d84073576352428720ee08b9bc527020413346c0bb7f7040fd9b149197bdc4988eebc4e012e73d75bc4f4d2d2a3cc30dae96836c590e5a5976f0392102e1c592da1fd373be252fc3b0d34a6dec22725dd697ac55d4d50e07ccba88f70a44b75abb5dfececacb1b5483760e5d40b84255455fdb93faecbc24ae3b30d73311d6afd5fbad5b6e61e64530e7645cc43adc3053a40d6fc0e63d6c664df163f197d2d3efbb5a5abcf4a7ad69d07bb866876fc22d9c7a2fe529260153283cdbe1fc5768d625ad09a9bdb60442a744d22a827264d2722baae4549097f745bcf0de7f21c80951cc5ed8a48e4099663dbf6ac1f995e7ab3d6c8fe2c3e817e13b26741f2a7f33bad56bb002ebf0c69282dc763e1e9cb44bc0a0814170116d2dc16fdf1e08158fc571c5a5285242ab6376f9c213953e3a0a315eff722831cc27e426b0fe299fb325933ba9631be00ffd51f7bb3d13d962f5b6a0a01ad0c60455993699b9ec594cb749c82c870dc443c7466db518e4a5ebc7c530539ae48bea63d77c0e175d673edff001511bbdbddf30f2c231cba0565f043aa52c584fc05069728a95e040893d4e9c6c8d3b7bae906be38b9e1480f8e4665f157f4b347be01d1c355c94576b32a335864f6cd341857a696fe5f8af10a4ae87246cd119d33205bb969009655e36db394f750382fd58648aee80179bb3f1df7f291b4de27edf056c3968aca546e0e81d131b3fb52ae8b3fdedf297289420c4aa1aa74560aae150f623e120b08592c0304dbf7ff2e432e737227ac1e7e9e65485b30d058b30f81807a18fba48822baaf2e7ec6c88a604495a000e62340273db9079c2a7123a8a197b63d9616e7e9ebef572ba3efec09fb038a57adceffeffcbbb6c4e0e9bd73c1d1e82d26d39bda2420a45fb2463218b2988b5fbd316b3f4e81e7b0728d700637333fe5448b395e384169c4bfc57ff6062c962ac4f13e66cd5b6166a7a049b6459291d2d2a632d749060d8070b9e2db3159db8047e8024bc12c92562c7b4ee953b426c551d1b9064551833c758683693a57e724bed8a5c05e55d8e5f27d22b4adc246116747f23cc8ec35b51148168cd27dfb8a466cb8f4b1980209735694e411184875da7254a2ff850a73377c1f9f0b87f808b76a9f0882231fcc4446ed01c9876edf92fc505040583d9ccd0fcaf3935f215dd45022a9464835a505022cdd54de634fe207b5e202f7bcad463e00312952d3d4b421cc77be0cac587426f0239b8d3d94c0c24141b10cc8ab33aa655388fa5a323016e7a1fe2470d4dad92cb19acf779ce1c48f64bf588c99a766010252b983edcd4725ff16c15683bd7be62323c39405358358fcff306182a3a147c025dc91801258f4d71e1888b0a19f4e52a8c5885cc99474e94448c0081d1ce2a7110e1a6c7e23184cd76a44c806b0f1ea3de321cfdf8569dd35221e9ab1ccbcf6dee81cc611d0731226228d71e98abf05a0db761bf6807d4c0400a39835f33b144f85ddcdee7945e63027d3cd25d44b7e9fdda2548284497af9b57dc72b3e026d49e86950b434fc9a9713f5be858500b54614d5d4c79186289d744fa0df3d655f9fb79ec60f49dc72eea538515b53f74c578f9d4ffc9e79063e19f3a38d9dde42f7c3910ac5ca16f60afefcccd4a49b1d93032b7e82189caebd2993991f7f4f1610d3b7cd4b8dbf895523b28d0a3e672232412145649b1a28570d9c114a851f10e6761f52ade202167d94fb69135f3d2932849a85267b998a23f6c6229697e0098097cb6a6dc4f84cff4c7da997d5631b694,0,d23f19ad26c7ab984c682c5b1475f5a7df0452a05dd29a164974d2027a6e488a,6f8420ebf786ee13dcf65855b11428db43061cb599e6fe9ed79e59d9f273dc44,33a1ef8464def100bf031dae882ae4b7837b481f6adbc63c44baa8ef61c102eb,8edefd89c5ddb77db6333981740b83fd4d9c246639e0dcfd1ea2a26d4a26f508,6b0aae6192e7a92c7a3b5de8ab1349d26637b17e500da162cf25df13c85d35df,87a8da66207605720c64d5267b5ce90becb01248a60808a921c5eff59013d59f,e9292dc44be3294db04cf689a3141bbe0d0dbaca2dd8d8fb606a45b8d7d8e089,57b8c1343aea943714ff848970b2a89b,ce7988ab7ce5c93b89328ff815ae803b,a306c86bea9e6befa7f72bd5cde761d5f4f86cfbc8749c1e844100c540a6cefc,a844ddeb465f302c4b408a6ab972d4ff4035109bc25fb8fe88d4892bccefc238cf93e5a61459f9c0cb4877cb03967d592c5d8dc6d4c4b5f489005a645b2f7a2ee368749f0b172b9ddbcaa76f20485a272b2347, -255,f360308206fb441c7713b1a24ba4096a2fa0d5401411198b7008f82ae85257fe,3d4aa6a71a8a734e014b4d9e6b62989f022c1e2238ae476b11465cb86fe8cf7243db6f9472e188590705cf9b35121e06e57cb106a6043ab147b7c73871da8222,f0ebc3c872339622fbf2ab1b8aa2117c4d752b64eac9203962c03a47497a89c0dd298348e5bb63d3433c48ed6da6bc2e2dbe78f7b91247dd29f1f51a858d464a,0,b766200432932708a77dd15337bf70ca58397907a1cd31ecd1b43fab27fa0de0e85d5c4dea99543e79a75b149d325044934efccf679a764f683b2fbcb7c6dc4baea9797554779aff937f5195c172892c38dc423bc809885e5a19d07733e7c5f5806ffb865074cf2c46fbb5be4f9b5833c6829b8217ccb301dad7cb49e4fbcad1,1,,1,29bf8fe2cbd12835d3e6652840b8b1a2acf99d7b44610e738aafd7fd207c9b25,8f088a98122e3ffae5fee255fbfdf653a1f830f85dfe595707a1f4a7f74dab76,07eff272cd331aeb14db342b82f6df98303b01471f4dbe71028b127577216d9b,74ee2a5f9221cb386e587ac9a0c724bc6f65ea04cf3b0686c10b3e39e66bca02,35d93b912c54f3d28f834ee96a787f76f84b543fc231a45242fa4953b89cfc9f,70c4abb811bb6c209c6f108be383f67c8a14cd2dd25815f6156e6c3edd7d1e3d,3a16c6f3ff6f2b735b89d2af77c94b9dd328f5330e1283627835d32c5c856446,e09f7df050a3f76bc8d5a21697fefb9b,b8951fd528743d2e8625de363d9ae0e7,b1d1e3ae7d9337f31a410986fe6e377726eb0f2334f24d66b38ec4d29529d1a5,98178b6e498f808c90b098c8ceb09c5630d50925323d051d379adb85be9e3b7d3e5a4c0eafa3fb69abcf60e631262278395c4ec017b1a2c8b4aa6a25e65afa99ea3e73038d152b392b2f754a655f3fd034fd633e7889072c3e1351bff97494a6737785a00016c294e0f62219eb6becfcd14e5f81841118275a460780178b050615ab02e56efc0c777844620ba3de42bb54674842, -512,073f53403256e2b699e32cd4cebadfab63d9076a7cd541d9656e27b1baff66bb,5c9c90c4e216f8a4c2642535d1f699364f9054ca01bca0239fa65bcaf0ec0278e5a36bc85eae96850feff889b66c9106c170fe655f973f533ee3557bd3cb6e64,e9221c9698cb69b63c5a4e224132389d346fd2f0f3262218301be51687b8de846c652ea8aa7425a5c08a7bd52078168d28ecf42196e33e155e215553ce6aee83,1,196391ebfe9af3a9186d82692a00e485d6653c8408050e2efbfd864642860022af68053ee4230f69ea565fee775778bc231307b5b534545878f864364bb2690acc9e8991fed5a777eb2850c3c54cca94a5bc2cb92729bcd4e27c57ebddbdf14974030115bc5a8a600b207a4884f568d6a9d3d9367977410577674601d1cc5f1f672f4e54d4944e1f7807416159eb5ece5b805c8a23e6735351a8cf8de654d87228ba21baf815190ef026b29612498121fe85480d9e0050d4781fa9f0e60cab5195,1,,0,0ce4860107efd6deb9e8fc71cfc2522b4a5a0dc171746fb995ce485570449ab5,d87966cc3cbdcc14ce06a1ef6c28125cec3136647a499d4b4465c925a5f85efd,88cf0eb49ee4b7b46cd39fb3f4126b285750d897fdcba72b08d9da351167e227,df6857d7fbb822069d3f284973cdc6677a539d81844247ca2ac174b818623550,4f1c0b4b834681298ef127067369747074e571c68fc69966f3ad20673f786b82,5b9aa4239daed582b04d316f0550fdf1efc5309544349b01d62ea4f045e3425f,0c1d30189bf24a5032a93add5335fcbf351b2071870fd1626b66e23be99e1df5,ece7e13c65def883efc1f0dac6d55974,efca4cefee7a95602ebab090875e4212,afde967955012c17bfa7bea218bff3aa1aef10a49139c66080e9e7c567706409,5400e5add3682ea8c5587dbaec8867c54b7dc97e07533db32b5f68ff9eeccf68db30c5013b276374e1b60dd417df516e375a995b45811817b326c6bfbaaec589d82415bc48bc8f1eee5b9ff430b486cc951752e943dccef384a66bc6d906c7f0e839772ffce47928bb73a8f828ac82dca6f8f4f8340f11f4ef849575fd16ed32e5d450249b89004164918fe739a83f2b5dae04f7a8ae32682779f65edaef9c80090f581c7d9000cef48bed0089b5eb8767cc963ee2bda2d00716a463ee5413036bd2a055c0f5e3f72791e0526ac5e35bd269b71117, -769,810159fc6708a85aa9d6c8e7c4f8c587056594910174c0309b2c323055efaa6a,2a875927b98fd441d8c469f6902c167eb440e52d3331a4b7406f21cad216e80917401ddb8795a9706fe42a7ddfca70fee7240b1e918b9f32414b8b26e611d571,758bcf0381c0a1c35a174503a43b08f79eb407aa61eb9e6579a62400d4a13f8d3cef884728c34cb79c7f088b4d4e735ce796361e71bd8b66d637f56326b49af3,0,0f492bc40bc635ca20a46c6fd97b7de536f8326e677e0dcf9ed91e4c7873ec903198010f7cf0ff1595,97561,,0,27cdbeb6c8ef5f97982a7af00018a16ba243176fe6bb5d5c30c8a466a0193a47,85bbb016a00056ffd3878b2a5cfac4352d581bfec5a0407f0733585513d4b463,17624a0ed455d13430bf27337e27a1d55402cb1c7ebb32a4a66b3ef2f9947f1d,aeb3befd6841f8ec867e154424b5c6d49ad3fc1f789e7d3048750302c5d89c09,80033fb9014f1a407e46d35cf36a7c4245e55e6a810abaaad88ec5d25f89443f,65b0f93ac2a34327a4aacf14c2c54d92210294b425c3b6bb4ced8c44dad80457,4893a9b0ec706fcc7a05c1fed011ced86afd7324c63537e49ec2974df481a83c,330b7aae0e4d13f5806bc1f696042155,d514d7861e65ced36c7ea6ad2a8f6938,2ad4f52fd2a9cd078c0664dc4ba33904095d4affb5227fbc779662ca6140376c,,c05bf91046901716cab14414ee73dbd7f17a6e4cf0bc3ba22e22d40198fbd1527726a99c006378ba3079e9da8dcc68ecd8a0a23a692eb775cf11d97e16847b3398e11ee1ddab092d6a994a7246802bb3140ecbd4d8495f36abb5aa3e0aa325f02b5be69e4ad546356c453003949ea9d2adfb169004fe37da65b247ffbf021e9109d6d090b224bd4f51b803955be2fd7fdd0e198f89d903deba9be904cd6d769bbd4f1b5b609be95a9b6db2c2a6fcff029899cea13196330a433277c96a069fa8b6590d921da84172adf1b23fb76eb6cec95f8bcd6b497777eb2b44dd15440f430d3f9ea8729ea5598df46b299cff81729d3fca241872e61b84945c70189189f5 -1024,f7c11ca3b55137fa6124c49b25dea0287815b887760e1b986497e976444eb5bb,5a2a0ce42feb17e70a96db1e55bc380e26a40a589dfc453d6c2e82bbc4c2b161716a05df9039ccffb6df45183480119deb69299e44d48e38de746ad084156edd,2c402d53332d914e4f5501c8db682bec6738ed53c7410655d9346db99bae37642beb6a1d48394502941965ea7140e1172ce591923235640f964c0d597caae304,1,bc5fdee9e87d05b9723871a35823f643cc53c400851686d69d87433028c19cc295ceea1513d8056021800c86d886f27f6018e4053121df4db5216bff17160f7b1bc4d3be67354f0551f55a353de5f15add353605e2a0761bb0c1b3bb8a37787e797e619ebf902a8ed4fcf1c741c897c8469cf54565b21c85e2b4fac5ef6e948f2c36df269f7189d1f293d2a95a08a1b9d00528521ff407ff992726712c8c9d6273a878d1700912ff2ef5b1b6899e9b88f6999bc628c8a390b37d9be99bd742e16a1eb83b0d1b8bfb6858e3fddb33ce2d9ef40afefd29833fd59dbc0aef25c35771b17d62595b5de9dc7426f1d976deea78,69615,,1,6d89eb9e87319fd088ee1e77fa5b36d2d2d9e66fae8d11ab7bd70407d4aaba29,0b6c87c76983e5c84428bd646d24c133d9321af5f7cb4624ca1524bcab828ffd,2a4d8d7ab2d2e92c429c8c4cb0d78f0f170a244410d588b92c7fd8baf7c27e59,001f5a1254d1734551f7895221f370aa5eb2ea382dfefd586941becac178d8a2,acf0ffecff0851e065af2a149f1c0a0db21c8a885613ebd1c445957b56c3d705,42b3699eec52f5f4648bdb40c25c956944f0a3e9986552917a3498078a8de907,a721aa5cf8d2b4ce9f46f20693438d94f75130585b6ab137894b273a436c90d4,a5e8c7130b7b8cb34e303bc3da911230,0169b4c927c5a809bd3b0981887e7e0b,462c77437e78cb8620e0572e5a401d151e6ae45aed57d7638d924f569eccd73e,,d3a1508bf5455510d63279ef808f8eb5979b2793e481990f489046adbf9eb4247384912949eb8a9800fee8a3b25c7f3771a426b60b5ce40a60df4e7399ca9069f5833addad5f62dfff9171a964211489855b5aaef2f227b63d75e3d07b4ea9fc068b35497f70a7b708f1af662f435282ededcc0e20e38003733cf52703343f40f390b2cc38d10a8ea82434f2126ec841f67f54660f6ece22ae874a3a2c880e78dc87fbfbbcafa4bff042e78668855584386a11349a64e2018e8ca3857439345d1368998e3bc4995ece49634a75786c6ec06914181d35153fa29af610dc8db16531e601d8bba061accbf2c49ac567769d5c1b0607d71ecb34642d75b51bdb6776 +in_idx,in_priv_ours,in_ellswift_ours,in_ellswift_theirs,in_initiating,in_contents,in_multiply,in_aad,in_ignore,mid_x_ours,mid_x_theirs,mid_x_shared,mid_shared_secret,mid_initiator_l,mid_initiator_p,mid_responder_l,mid_responder_p,mid_send_garbage_terminator,mid_recv_garbage_terminator,out_session_id,out_ciphertext,out_ciphertext_endswith +1,61062ea5071d800bbfd59e2e8b53d47d194b095ae5a4df04936b49772ef0d4d7,ec0adff257bbfe500c188c80b4fdd640f6b45a482bbc15fc7cef5931deff0aa186f6eb9bba7b85dc4dcc28b28722de1e3d9108b985e2967045668f66098e475b,a4a94dfce69b4a2a0a099313d10f9f7e7d649d60501c9e1d274c300e0d89aafaffffffffffffffffffffffffffffffffffffffffffffffffffffffff8faf88d5,1,8e,1,,0,19e965bc20fc40614e33f2f82d4eeff81b5e7516b12a5c6c0d6053527eba0923,0c71defa3fafd74cb835102acd81490963f6b72d889495e06561375bd65f6ffc,4eb2bf85bd00939468ea2abb25b63bc642e3d1eb8b967fb90caa2d89e716050e,c6992a117f5edbea70c3f511d32d26b9798be4b81a62eaee1a5acaa8459a3592,9a6478b5fbab1f4dd2f78994b774c03211c78312786e602da75a0d1767fb55cf,7d0c7820ba6a4d29ce40baf2caa6035e04f1e1cefd59f3e7e59e9e5af84f1f51,17bc726421e4054ac6a1d54915085aaa766f4d3cf67bbd168e6080eac289d15e,9f0fc1c0e85fd9a8eee07e6fc41dba2ff54c7729068a239ac97c37c524cca1c0,faef555dfcdb936425d84aba524758f3,02cb8ff24307a6e27de3b4e7ea3fa65b,ce72dffb015da62b0d0f5474cab8bc72605225b0cee3f62312ec680ec5f41ba5,7530d2a18720162ac09c25329a60d75adf36eda3c3, +999,1f9c581b35231838f0f17cf0c979835baccb7f3abbbb96ffcc318ab71e6e126f,a1855e10e94e00baa23041d916e259f7044e491da6171269694763f018c7e63693d29575dcb464ac816baa1be353ba12e3876cba7628bd0bd8e755e721eb0140,fffffffffffffffffffffffffffffffffffffffffffffffffffffffefffffc2f0000000000000000000000000000000000000000000000000000000000000000,0,3eb1d4e98035cfd8eeb29bac969ed3824a,1,,0,45b6f1f684fd9f2b16e2651ddc47156c0695c8c5cd2c0c9df6d79a1056c61120,edd1fd3e327ce90cc7a3542614289aee9682003e9cf7dcc9cf2ca9743be5aa0c,c40eb6190caf399c9007254ad5e5fa20d64af2b41696599c59b2191d16992955,a0138f564f74d0ad70bc337dacc9d0bf1d2349364caf1188a1e6e8ddb3b7b184,b82a0a7ce7219777f914d2ab873c5c487c56bd7b68622594d67fe029a8fa7def,d760ba8f62dd3d29d7d5584e310caf2540285edc6b51c640f9497e99c3536fd2,9db0c6f9a903cbab5d7b3c58273a3421eec0001814ec53236bd405131a0d8e90,23d2b5e653e6a3a8db160a2ca03d11cb5a79983babba861fcb57c38413323c0c,efb64fd80acd3825ac9bc2a67216535a,b3cb553453bceb002897e751ff7588bf,9267c54560607de73f18c563b76a2442718879c52dd39852885d4a3c9912c9ea,1da1bcf589f9b61872f45b7fa5371dd3f8bdf5d515b0c5f9fe9f0044afb8dc0aa1cd39a8c4, +0,0286c41cd30913db0fdff7a64ebda5c8e3e7cef10f2aebc00a7650443cf4c60d,d1ee8a93a01130cbf299249a258f94feb5f469e7d0f2f28f69ee5e9aa8f9b54a60f2c3ff2d023634ec7f4127a96cc11662e402894cf1f694fb9a7eaa5f1d9244,ffffffffffffffffffffffffffffffffffffffffffffffffffffffff22d5e441524d571a52b3def126189d3f416890a99d4da6ede2b0cde1760ce2c3f98457ae,1,054290a6c6ba8d80478172e89d32bf690913ae9835de6dcf206ff1f4d652286fe0ddf74deba41d55de3edc77c42a32af79bbea2c00bae7492264c60866ae5a,1,84932a55aac22b51e7b128d31d9f0550da28e6a3f394224707d878603386b2f9d0c6bcd8046679bfed7b68c517e7431e75d9dd34605727d2ef1c2babbf680ecc8d68d2c4886e9953a4034abde6da4189cd47c6bb3192242cf714d502ca6103ee84e08bc2ca4fd370d5ad4e7d06c7fbf496c6c7cc7eb19c40c61fb33df2a9ba48497a96c98d7b10c1f91098a6b7b16b4bab9687f27585ade1491ae0dba6a79e1e2d85dd9d9d45c5135ca5fca3f0f99a60ea39edbc9efc7923111c937913f225d67788d5f7e8852b697e26b92ec7bfcaa334a1665511c2b4c0a42d06f7ab98a9719516c8fd17f73804555ee84ab3b7d1762f6096b778d3cb9c799cbd49a9e4a325197b4e6cc4a5c4651f8b41ff88a92ec428354531f970263b467c77ed11312e2617d0d53fe9a8707f51f9f57a77bfb49afe3d89d85ec05ee17b9186f360c94ab8bb2926b65ca99dae1d6ee1af96cad09de70b6767e949023e4b380e66669914a741ed0fa420a48dbc7bfae5ef2019af36d1022283dd90655f25eec7151d471265d22a6d3f91dc700ba749bb67c0fe4bc0888593fbaf59d3c6fff1bf756a125910a63b9682b597c20f560ecb99c11a92c8c8c3f7fbfaa103146083a0ccaecf7a5f5e735a784a8820155914a289d57d8141870ffcaf588882332e0bcd8779efa931aa108dab6c3cce76691e345df4a91a03b71074d66333fd3591bff071ea099360f787bbe43b7b3dff2a59c41c7642eb79870222ad1c6f2e5a191ed5acea51134679587c9cf71c7d8ee290be6bf465c4ee47897a125708704ad610d8d00252d01959209d7cd04d5ecbbb1419a7e84037a55fefa13dee464b48a35c96bcb9a53e7ed461c3a1607ee00c3c302fd47cd73fda7493e947c9834a92d63dcfbd65aa7c38c3e3a2748bb5d9a58e7495d243d6b741078c8f7ee9c8813e473a323375702702b0afae1550c8341eedf5247627343a95240cb02e3e17d5dca16f8d8d3b2228e19c06399f8ec5c5e9dbe4caef6a0ea3ffb1d3c7eac03ae030e791fa12e537c80d56b55b764cadf27a8701052df1282ba8b5e3eb62b5dc7973ac40160e00722fa958d95102fc25c549d8c0e84bed95b7acb61ba65700c4de4feebf78d13b9682c52e937d23026fb4c6193e6644e2d3c99f91f4f39a8b9fc6d013f89c3793ef703987954dc0412b550652c01d922f525704d32d70d6d4079bc3551b563fb29577b3aecdc9505011701dddfd94830431e7a4918927ee44fb3831ce8c4513839e2deea1287f3fa1ab9b61a256c09637dbc7b4f0f8fbb783840f9c24526da883b0df0c473cf231656bd7bc1aaba7f321fec0971c8c2c3444bff2f55e1df7fea66ec3e440a612db9aa87bb505163a59e06b96d46f50d8120b92814ac5ab146bc78dbbf91065af26107815678ce6e33812e6bf3285d4ef3b7b04b076f21e7820dcbfdb4ad5218cf4ff6a65812d8fcb98ecc1e95e2fa58e3efe4ce26cd0bd400d6036ab2ad4f6c713082b5e3f1e04eb9e3b6c8f63f57953894b9e220e0130308e1fd91f72d398c1e7962ca2c31be83f31d6157633581a0a6910496de8d55d3d07090b6aa087159e388b7e7dec60f5d8a60d93ca2ae91296bd484d916bfaaa17c8f45ea4b1a91b37c82821199a2b7596672c37156d8701e7352aa48671d3b1bbbd2bd5f0a2268894a25b0cb2514af39c8743f8cce8ab4b523053739fd8a522222a09acf51ac704489cf17e4b7125455cb8f125b4d31af1eba1f8cf7f81a5a100a141a7ee72e8083e065616649c241f233645c5fc865d17f0285f5c52d9f45312c979bfb3ce5f2a1b951deddf280ffb3f370410cffd1583bfa90077835aa201a0712d1dcd1293ee177738b14e6b5e2a496d05220c3253bb6578d6aff774be91946a614dd7e879fb3dcf7451e0b9adb6a8c44f53c2c464bcc0019e9fad89cac7791a0a3f2974f759a9856351d4d2d7c5612c17cfc50f8479945df57716767b120a590f4bf656f4645029a525694d8a238446c5f5c2c1c995c09c1405b8b1eb9e0352ffdf766cc964f8dcf9f8f043dfab6d102cf4b298021abd78f1d9025fa1f8e1d710b38d9d1652f2d88d1305874ec41609b6617b65c5adb19b6295dc5c5da5fdf69f28144ea12f17c3c6fcce6b9b5157b3dfc969d6725fa5b098a4d9b1d31547ed4c9187452d281d0a5d456008caf1aa251fac8f950ca561982dc2dc908d3691ee3b6ad3ae3d22d002577264ca8e49c523bd51c4846be0d198ad9407bf6f7b82c79893eb2c05fe9981f687a97a4f01fe45ff8c8b7ecc551135cd960a0d6001ad35020be07ffb53cb9e731522ca8ae9364628914b9b8e8cc2f37f03393263603cc2b45295767eb0aac29b0930390eb89587ab2779d2e3decb8042acece725ba42eda650863f418f8d0d50d104e44fbbe5aa7389a4a144a8cecf00f45fb14c39112f9bfb56c0acbd44fa3ff261f5ce4acaa5134c2c1d0cca447040820c81ab1bcdc16aa075b7c68b10d06bbb7ce08b5b805e0238f24402cf24a4b4e00701935a0c68add3de090903f9b85b153cb179a582f57113bfc21c2093803f0cfa4d9d4672c2b05a24f7e4c34a8e9101b70303a7378b9c50b6cddd46814ef7fd73ef6923feceab8fc5aa8b0d185f2e83c7a99dcb1077c0ab5c1f5d5f01ba2f0420443f75c4417db9ebf1665efbb33dca224989920a64b44dc26f682cc77b4632c8454d49135e52503da855bc0f6ff8edc1145451a9772c06891f41064036b66c3119a0fc6e80dffeb65dc456108b7ca0296f4175fff3ed2b0f842cd46bd7e86f4c62dfaf1ddbf836263c00b34803de164983d0811cebfac86e7720c726d3048934c36c23189b02386a722ca9f0fe00233ab50db928d3bccea355cc681144b8b7edcaae4884d5a8f04425c0890ae2c74326e138066d8c05f4c82b29df99b034ea727afde590a1f2177ace3af99cfb1729d6539ce7f7f7314b046aab74497e63dd399e1f7d5f16517c23bd830d1fdee810f3c3b77573dd69c4b97d80d71fb5a632e00acdfa4f8e829faf3580d6a72c40b28a82172f8dcd4627663ebf6069736f21735fd84a226f427cd06bb055f94e7c92f31c48075a2955d82a5b9d2d0198ce0d4e131a112570a8ee40fb80462a81436a58e7db4e34b6e2c422e82f934ecda9949893da5730fc5c23c7c920f363f85ab28cc6a4206713c3152669b47efa8238fa826735f17b4e78750276162024ec85458cd5808e06f40dd9fd43775a456a3ff6cae90550d76d8b2899e0762ad9a371482b3e38083b1274708301d6346c22fea9bb4b73db490ff3ab05b2f7f9e187adef139a7794454b7300b8cc64d3ad76c0e4bc54e08833a4419251550655380d675bc91855aeb82585220bb97f03e976579c08f321b5f8f70988d3061f41465517d53ac571dbf1b24b94443d2e9a8e8a79b392b3d6a4ecdd7f626925c365ef6221305105ce9b5f5b6ecc5bed3d702bd4b7f5008aa8eb8c7aa3ade8ecf6251516fbefeea4e1082aa0e1848eddb31ffe44b04792d296054402826e4bd054e671f223e5557e4c94f89ca01c25c44f1a2ff2c05a70b43408250705e1b858bf0670679fdcd379203e36be3500dd981b1a6422c3cf15224f7fefdef0a5f225c5a09d15767598ecd9e262460bb33a4b5d09a64591efabc57c923d3be406979032ae0bc0997b65336a06dd75b253332ad6a8b63ef043f780a1b3fb6d0b6cad98b1ef4a02535eb39e14a866cfc5fc3a9c5deb2261300d71280ebe66a0776a151469551c3c5fa308757f956655278ec6330ae9e3625468c5f87e02cd9a6489910d4143c1f4ee13aa21a6859d907b788e28572fecee273d44e4a900fa0aa668dd861a60fb6b6b12c2c5ef3c8df1bd7ef5d4b0d1cdb8c15fffbb365b9784bd94abd001c6966216b9b67554ad7cb7f958b70092514f7800fc40244003e0fd1133a9b850fb17f4fcafde07fc87b07fb510670654a5d2d6fc9876ac74728ea41593beef003d6858786a52d3a40af7529596767c17000bfaf8dc52e871359f4ad8bf6e7b2853e5229bdf39657e213580294a5317c5df172865e1e17fe37093b585e04613f5f078f761b2b1752eb32983afda24b523af8851df9a02b37e77f543f18888a782a994a50563334282bf9cdfccc183fdf4fcd75ad86ee0d94f91ee2300a5befbccd14e03a77fc031a8cfe4f01e4c5290f5ac1da0d58ea054bd4837cfd93e5e34fc0eb16e48044ba76131f228d16cde9b0bb978ca7cdcd10653c358bdb26fdb723a530232c32ae0a4cecc06082f46e1c1d596bfe60621ad1e354e01e07b040cc7347c016653f44d926d13ca74e6cbc9d4ab4c99f4491c95c76fff5076b3936eb9d0a286b97c035ca88a3c6309f5febfd4cdaac869e4f58ed409b1e9eb4192fb2f9c2f12176d460fd98286c9d6df84598f260119fd29c63f800c07d8df83d5cc95f8c2fea2812e7890e8a0718bb1e031ecbebc0436dcf3e3b9a58bcc06b4c17f711f80fe1dffc3326a6eb6e00283055c6dabe20d311bfd5019591b7954f8163c9afad9ef8390a38f3582e0a79cdf0353de8eeb6b5f9f27b16ffdef7dd62869b4840ee226ccdce95e02c4545eb981b60571cd83f03dc5eaf8c97a0829a4318a9b3dc06c0e003db700b2260ff1fa8fee66890e637b109abb03ec901b05ca599775f48af50154c0e67d82bf0f558d7d3e0778dc38bea1eb5f74dc8d7f90abdf5511a424be66bf8b6a3cacb477d2e7ef4db68d2eba4d5289122d851f9501ba7e9c4957d8eba3be3fc8e785c4265a1d65c46f2809b70846c693864b169c9dcb78be26ea14b8613f145b01887222979a9e67aee5f800caa6f5c4229bdeefc901232ace6143c9865e4d9c07f51aa200afaf7e48a7d1d8faf366023beab12906ffcb3eaf72c0eb68075e4daf3c080e0c31911befc16f0cc4a09908bb7c1e26abab38bd7b788e1a09c0edf1a35a38d2ff1d3ed47fcdaae2f0934224694f5b56705b9409b6d3d64f3833b686f7576ec64bbdd6ff174e56c2d1edac0011f904681a73face26573fbba4e34652f7ae84acfb2fa5a5b3046f98178cd0831df7477de70e06a4c00e305f31aafc026ef064dd68fd3e4252b1b91d617b26c6d09b6891a00df68f105b5962e7f9d82da101dd595d286da721443b72b2aba2377f6e7772e33b3a5e3753da9c2578c5d1daab80187f55518c72a64ee150a7cb5649823c08c9f62cd7d020b45ec2cba8310db1a7785a46ab24785b4d54ff1660b5ca78e05a9a55edba9c60bf044737bc468101c4e8bd1480d749be5024adefca1d998abe33eaeb6b11fbb39da5d905fdd3f611b2e51517ccee4b8af72c2d948573505590d61a6783ab7278fc43fe55b1fcc0e7216444d3c8039bb8145ef1ce01c50e95a3f3feab0aee883fdb94cc13ee4d21c542aa795e18932228981690f4d4c57ca4db6eb5c092e29d8a05139d509a8aeb48baa1eb97a76e597a32b280b5e9d6c36859064c98ff96ef5126130264fa8d2f49213870d9fb036cff95da51f270311d9976208554e48ffd486470d0ecdb4e619ccbd8226147204baf8e235f54d8b1cba8fa34a9a4d055de515cdf180d2bb6739a175183c472e30b5c914d09eeb1b7dafd6872b38b48c6afc146101200e6e6a44fe5684e220adc11f5c403ddb15df8051e6bdef09117a3a5349938513776286473a3cf1d2788bb875052a2e6459fa7926da33380149c7f98d7700528a60c954e6f5ecb65842fde69d614be69eaa2040a4819ae6e756accf936e14c1e894489744a79c1f2c1eb295d13e2d767c09964b61f9cfe497649f712,0,33a32d10066fa3963a9518a14d1bd1cb5ccaceaeaaeddb4d7aead90c08395bfd,568146140669e69646a6ffeb3793e8010e2732209b4c34ec13e209a070109183,a1017beaa8784f283dee185cd847ae3a327a981e62ae21e8c5face175fc97e9b,250b93570d411149105ab8cb0bc5079914906306368c23e9d77c2a33265b994c,4ec7daf7294a4a2c717442dd21cf2f052a3bfe9d535b55da0f66fecf87a27534,52ab4db9c4b06621f8ded3405691eb32465b1360d15a6b127ded4d15f9cde466,ba9906da802407ddedf6733e29f3996c62425e79d3cbfeebbd6ec4cdc7c976a8,ee661e18c97319ad071106bf35fe1085034832f70718d92f887932128b6100c7,d4e3f18ac2e2095edb5c3b94236118ad,4faa6c4233d9fd53d170ede4172142a8,23f154ac43cfc59c4243e9fc68aeec8f19ad3942d74108e833b36f0dd3dcd357,8da7de6ea7bf2a81a396a42880ba1f5756734c4821309ac9aeffa2a26ce86873b9dc4935a772de6ec5162c6d075b14536800fb174841153511bfb597e992e2fe8a450c4bce102cc550bb37fd564c4d60bf884e, +223,6c77432d1fda31e9f942f8af44607e10f3ad38a65f8a4bddae823e5eff90dc38,d2685070c1e6376e633e825296634fd461fa9e5bdf2109bcebd735e5a91f3e587c5cb782abb797fbf6bb5074fd1542a474f2a45b673763ec2db7fb99b737bbb9,56bd0c06f10352c3a1a9f4b4c92f6fa2b26df124b57878353c1fc691c51abea77c8817daeeb9fa546b77c8daf79d89b22b0e1b87574ece42371f00237aa9d83a,0,7e0e78eb6990b059e6cf0ded66ea93ef82e72aa2f18ac24f2fc6ebab561ae557420729da103f64cecfa20527e15f9fb669a49bbbf274ef0389b3e43c8c44e5f60bf2ac38e2b55e7ec4273dba15ba41d21f8f5b3ee1688b3c29951218caf847a97fb50d75a86515d445699497d968164bf740012679b8962de573be941c62b7ef,1,,1,193d019db571162e52567e0cfdf9dd6964394f32769ae2edc4933b03b502d771,2dd7b9cc85524f8670f695c3143ac26b45cebcabb2782a85e0fe15aee3956535,5e35f94adfd57976833bffec48ef6dde983d18a55501154191ea352ef06732ee,1918b741ef5f9d1d7670b050c152b4a4ead2c31be9aecb0681c0cd4324150853,97124c56236425d792b1ec85e34b846e8d88c9b9f1d4f23ac6cdcc4c177055a0,8c71b468c61119415e3c1dfdd184134211951e2f623199629a46bff9673611f2,b43b8791b51ed682f56d64351601be28e478264411dcf963b14ee60b9ae427fa,794dde4b38ef04250c534a7fa638f2e8cc8b6d2c6110ec290ab0171fdf277d51,cf2e25f23501399f30738d7eee652b90,225a477a28a54ea7671d2b217a9c29db,7ec02fea8c1484e3d0875f978c5f36d63545e2e4acf56311394422f4b66af612,,729847a3e9eba7a5bff454b5de3b393431ee360736b6c030d7a5bd01d1203d2e98f528543fd2bf886ccaa1ada5e215a730a36b3f4abfc4e252c89eb01d9512f94916dae8a76bf16e4da28986ffe159090fe5267ee3394300b7ccf4dfad389a26321b3a3423e4594a82ccfbad16d6561ecb8772b0cb040280ff999a29e3d9d4fd +448,a6ec25127ca1aa4cf16b20084ba1e6516baae4d32422288e9b36d8bddd2de35a,ffffffffffffffffffffffffffffffffffffffffffffffffffffffff053d7ecca53e33e185a8b9be4e7699a97c6ff4c795522e5918ab7cd6b6884f67e683f3dc,ffffffffffffffffffffffffffffffffffffffffffffffffffffffffa7730be30000000000000000000000000000000000000000000000000000000000000000,1,00cf68f8f7ac49ffaa02c4864fdf6dfe7bbf2c740b88d98c50ebafe32c92f3427f57601ffcb21a3435979287db8fee6c302926741f9d5e464c647eeb9b7acaeda46e00abd7506fc9a719847e9a7328215801e96198dac141a15c7c2f68e0690dd1176292a0dded04d1f548aad88f1aebdc0a8f87da4bb22df32dd7c160c225b843e83f6525d6d484f502f16d923124fc538794e21da2eb689d18d87406ecced5b9f92137239ed1d37bcfa7836641a83cf5e0a1cf63f51b06f158e499a459ede41c,1,,0,02b225089255f7b02b20276cfe9779144df8fb1957b477bff3239d802d1256e9,5232c4b6bde9d3d45d7b763ebd7495399bb825cc21de51011761cd81a51bdc84,379223d2f1ea7f8a22043c4ce4122623098309e15b1ce58286ebe3d3bf40f4e1,dd210aa6629f20bb328e5d89daa6eb2ac3d1c658a725536ff154f31b536c23b2,393472f85a5cc6b0f02c4bd466db7a2dc5b91fc9dcb15c0dd6dc21116ece8bca,c80b87b793db47320b2795db66d331bd3021cc24e360d59d0fa8974f54687e0c,ef16a43d77e2b270b0a145ee1618d35f3c943cc7877d6cfcff2287d41692be39,20d4b62e2d982c61bb0cc39a93283d98af36530ef12331d44b2477b0e521b490,fead69be77825a23daec377c362aa560,511d4980526c5e64aa7187462faeafdd,acb8f084ea763ddd1b92ac4ed23bf44de20b84ab677d4e4e6666a6090d40353d,,77b4656934a82de1a593d8481f020194ddafd8cac441f9d72aeb8721e6a14f49698ca6d9b2b6d59d07a01aa552fd4d5b68d0d1617574c77dea10bfadbaa31b83885b7ceac2fd45e3e4a331c51a74e7b1698d81b64c87c73c5b9258b4d83297f9debc2e9aa07f8572ff434dc792b83ecf07b3197de8dc9cf7be56acb59c66cff5 +673,0af952659ed76f80f585966b95ab6e6fd68654672827878684c8b547b1b94f5a,ffffffffffffffffffffffffffffffffffffffffffffffffffffffffc81017fd92fd31637c26c906b42092e11cc0d3afae8d9019d2578af22735ce7bc469c72d,9652d78baefc028cd37a6a92625b8b8f85fde1e4c944ad3f20e198bef8c02f19fffffffffffffffffffffffffffffffffffffffffffffffffffffffff2e91870,0,5c6272ee55da855bbbf7b1246d9885aa7aa601a715ab86fa46c50da533badf82b97597c968293ae04e,97561,,0,4b1767466fe2fb8deddf2dc52cc19c7e2032007e19bfb420b30a80152d0f22d6,64c383e0e78ac99476ddff2061683eeefa505e3666673a1371342c3e6c26981d,5bcfeac98d87e87e158bf839f1269705429f7af2a25b566a25811b5f9aef9560,3568f2aea2e14ef4ee4a3c2a8b8d31bc5e3187ba86db10739b4ff8ec92ff6655,c7df866a62b7d404eb530b2be245a7aece0fb4791402a1de8f33530cbf777cc1,8f732e4aae2ba9314e0982492fa47954de9c189d92fbc549763b27b1b47642ce,992085edfecb92c62a3a7f96ea416f853f34d0dfe065b966b6968b8b87a83081,c5ba5eaf9e1c807154ebab3ea472499e815a7be56dfaf0c201cf6e91ffeca8e6,5e2375ac629b8df1e4ff3617c6255a70,70bcbffcb62e4d29d2605d30bceef137,7332e92a3f9d2792c4d444fac5ed888c39a073043a65eefb626318fd649328f8,,657a4a19711ce593c3844cb391b224f60124aba7e04266233bc50cafb971e26c7716b76e98376448f7d214dd11e629ef9a974d60e3770a695810a61c4ba66d78b936ee7892b98f0b48ddae9fcd8b599dca1c9b43e9b95e0226cf8d4459b8a7c2c4e6db80f1d58c7b20dd7208fa5c1057fb78734223ee801dbd851db601fee61e +1024,f90e080c64b05824c5a24b2501d5aeaf08af3872ee860aa80bdcd430f7b63494,ffffffffffffffffffffffffffffffffffffffffffffffffffffffff115173765dc202cf029ad3f15479735d57697af12b0131dd21430d5772e4ef11474d58b9,12a50f3fafea7c1eeada4cf8d33777704b77361453afc83bda91eef349ae044d20126c6200547ea5a6911776c05dee2a7f1a9ba7dfbabbbd273c3ef29ef46e46,1,5f67d15d22ca9b2804eeab0a66f7f8e3a10fa5de5809a046084348cbc5304e843ef96f59a59c7d7fdfe5946489f3ea297d941bac326225df316a25fc90f0e65b0d31a9c497e960fdbf8c482516bc8a9c1c77b7f6d0e1143810c737f76f9224e6f2c9af5186b4f7259c7e8d165b6e4fe3d38a60bdbdd4d06ecdcaaf62086070dbb68686b802d53dfd7db14b18743832605f5461ad81e2af4b7e8ff0eff0867a25b93cec7becf15c43131895fed09a83bf1ee4a87d44dd0f02a837bf5a1232e201cb882734eb9643dc2dc4d4e8b5690840766212c7ac8f38ad8a9ec47c7a9b3e022ae3eb6a32522128b518bd0d0085dd81c5,69615,,1,8b8de966150bf872b4b695c9983df519c909811954d5d76e99ed0d5f1860247b,eef379db9bd4b1aa90fc347fad33f7d53083389e22e971036f59f4e29d325ac2,0a402d812314646ccc2565c315d1429ec1ed130ff92ff3f48d948f29c3762cf1,e25461fb0e4c162e18123ecde88342d54d449631e9b75a266fd9260c2bb2f41d,97771ce2ce17a25c3d65bf9f8e4acb830dce8d41392be3e4b8ed902a3106681a,2e7022b4eae9152942f68160a93e25d3e197a557385594aa587cb5e431bb470d,613f85a82d783ce450cfd7e91a027fcc4ad5610872f83e4dbe9e2202184c6d6e,cb5de4ed1083222e381401cf88e3167796bc9ab5b8aa1f27b718f39d1e6c0e87,b709dea25e0be287c50e3603482c2e98,1f677e9d7392ebe3633fd82c9efb0f16,889f339285564fd868401fac8380bb9887925122ec8f31c8ae51ce067def103b,,7c4b9e1e6c1ce69da7b01513cdc4588fd93b04dafefaf87f31561763d906c672bac3dfceb751ebd126728ac017d4d580e931b8e5c7d5dfe0123be4dc9b2d2238b655c8a7fadaf8082c31e310909b5b731efc12f0a56e849eae6bfeedcc86dd27ef9b91d159256aa8e8d2b71a311f73350863d70f18d0d7302cf551e4303c7733 diff --git a/bip-0324/reference.py b/bip-0324/reference.py index e07731b3a4..f02c44ac71 100644 --- a/bip-0324/reference.py +++ b/bip-0324/reference.py @@ -1,3 +1,5 @@ +"""Reference implementation for the cryptographic aspects of BIP-324""" + import sys import random import hashlib @@ -70,7 +72,7 @@ def __init__(self, a=0, b=1): self.den = (a.den * b.num) % FE.SIZE else: self.num = (a * b.den) % FE.SIZE - self.den = a.num + self.den = b.num else: b = b % FE.SIZE assert b != 0 @@ -85,8 +87,7 @@ def __add__(self, a): """Compute the sum of two field elements (second may be int).""" if isinstance(a, FE): return FE(self.num * a.den + self.den * a.num, self.den * a.den) - else: - return FE(self.num + self.den * a, self.den) + return FE(self.num + self.den * a, self.den) def __radd__(self, a): """Compute the sum of an integer and a field element.""" @@ -96,8 +97,7 @@ def __sub__(self, a): """Compute the difference of two field elements (second may be int).""" if isinstance(a, FE): return FE(self.num * a.den - self.den * a.num, self.den * a.den) - else: - return FE(self.num - self.den * a, self.den) + return FE(self.num - self.den * a, self.den) def __rsub__(self, a): """Compute the difference between an integer and a field element.""" @@ -107,8 +107,7 @@ def __mul__(self, a): """Compute the product of two field elements (second may be int).""" if isinstance(a, FE): return FE(self.num * a.num, self.den * a.den) - else: - return FE(self.num * a, self.den) + return FE(self.num * a, self.den) def __rmul__(self, a): """Compute the product of an integer with a field element.""" @@ -140,15 +139,57 @@ def __int__(self): def sqrt(self): """Compute the square root of a field element. - Due to the fact that our modulus is of the form (p % 4) == 3, the Tonelli-Shanks - algorithm (https://en.wikipedia.org/wiki/Tonelli-Shanks_algorithm) is simply - raising the argument to the power (p + 3) / 4.""" + Due to the fact that our modulus p is of the form p = 3 (mod 4), the + Tonelli-Shanks algorithm (https://en.wikipedia.org/wiki/Tonelli-Shanks_algorithm) + is simply raising the argument to the power (p + 1) / 4. + + To see why: p-1 = 0 (mod 2), so 2 divides the order of the multiplicative group, + and thus only half of the non-zero field elements are squares. An element a is + a (nonzero) square when Euler's criterion, a^((p-1)/2) = 1 (mod p), holds. We're + looking for x such that x^2 = a (mod p). Given a^((p-1)/2) = 1 (mod p), that is + equivalent to x^2 = a^(1 + (p-1)/2) (mod p). As (1 + (p-1)/2) is even, this is + equivalent to x = a^((1 + (p-1)/2)/2) (mod p), or x = a^((p+1)/4) (mod p).""" v = int(self) s = pow(v, (FE.SIZE + 1) // 4, FE.SIZE) if s**2 % FE.SIZE == v: return FE(s) return None + def sqrts(self): + """Compute all square roots of a field element, if any.""" + s = self.sqrt() + if s is None: + return [] + return [FE(s), -FE(s)] + + # The cube roots of 1 (mod p). + CBRT1 = [ + 1, + 0x851695d49a83f8ef919bb86153cbcb16630fb68aed0a766a3ec693d68e6afa40, + 0x7ae96a2b657c07106e64479eac3434e99cf0497512f58995c1396c28719501ee + ] + + + def cbrts(self): + """Compute all cube roots of a field element, if any. + + Due to the fact that our modulus p is of the form p = 7 (mod 9), one cube root + can always be computed by raising to the power (p + 2) / 9. The other roots + (if any) can be found by multiplying with the two non-trivial cube roots of 1. + + To see why: p-1 = 0 (mod 3), so 3 divides the order of the multiplicative group, + and thus only 1/3 of the non-zero field elements are cubes. An element a is a + (nonzero) cube when a^((p-1)/3) = 1 (mod p). We're looking for x such that + x^3 = a (mod p). Given a^((p-1)/3) = 1 (mod p), that is equivalent to + x^3 = a^(1 + (p-1)/3) (mod p). As (1 + (p-1)/3) is a multiple of 3, this is + equivalent to x = a^((1 + (p-1)/3)/3) (mod p), or x = a^((p+2)/9) (mod p).""" + v = int(self) + c = pow(v, (FE.SIZE + 2) // 9, FE.SIZE) + + if pow(c, 3, FE.SIZE) == v: + return [FE(c * f) for f in FE.CBRT1] + return [] + def is_square(self): """Determine if this field element has a square root.""" # Compute the Jacobi symbol of (self / p). Since our modulus is prime, this @@ -161,7 +202,7 @@ def is_square(self): while n & 1 == 0: n >>= 1 r = k & 7 - t ^= (r == 3 or r == 5) + t ^= (r in (3, 5)) n, k = k, n t ^= (n & k & 3 == 3) n = n % k @@ -172,8 +213,7 @@ def __eq__(self, a): """Check whether two field elements are equal (second may be an int).""" if isinstance(a, FE): return (self.num * a.den - self.den * a.num) % FE.SIZE == 0 - else: - return (self.num - self.den * a) % FE.SIZE == 0 + return (self.num - self.den * a) % FE.SIZE == 0 def to_bytes(self): """Convert a field element to 32-byte big endian encoding.""" @@ -187,6 +227,16 @@ def from_bytes(b): return None return FE(v) + def __str__(self): + """Convert this field element to a string.""" + return f"{int(self):064x}" + + def __repr__(self): + """Get a string representation of this field element.""" + return f"FE(0x{int(self):x})" + +assert all(pow(c, 3, FE.SIZE) == 1 for c in FE.CBRT1) + class GE: """Objects of this class represent points (group elements) on the secp256k1 curve. @@ -221,12 +271,11 @@ def __add__(self, a): x3 = l**2 - self.x - a.x y3 = l * (self.x - x3) - self.y return GE(x3, y3) - elif self.y == a.y: + if self.y == a.y: # Adding point to itself return self.double() - else: - # Adding point to its negation - return None + # Adding point to its negation + return None def __radd__(self, a): """Add infinity to a point.""" @@ -260,13 +309,21 @@ def is_valid_x(x): """Determine whether the provided field element is a valid X coordinate.""" return (FE(x)**3 + 7).is_square() + def __str__(self): + """Convert this group element to a string.""" + return f"({self.x},{self.y})" + + def __repr__(self): + """Get a string representation for this group element.""" + return f"GE(0x{int(self.x)},0x{int(self.y)})" + SECP256K1_G = GE( 0x79BE667EF9DCBBAC55A06295CE870B07029BFCDB2DCE28D959F2815B16F81798, 0x483ADA7726A3C4655DA4FBFC0E1108A8FD17B448A68554199C47D08FFB10D4B8) ### ElligatorSwift -# Precomputed constant square root of -3 modulo p. +# Precomputed constant square root of -3 (mod p). MINUS_3_SQRT = FE(-3).sqrt() def xswiftec(u, t): @@ -292,7 +349,7 @@ def xswiftec_inv(x, u, case): if case & 2 == 0: if GE.is_valid_x(-x - u): return None - v = x if case & 1 == 0 else -x - u + v = x s = -(u**3 + 7) / (u**2 + u*v + v**2) else: s = x - u @@ -301,17 +358,16 @@ def xswiftec_inv(x, u, case): r = (-s * (4 * (u**3 + 7) + 3 * s * u**2)).sqrt() if r is None: return None - if case & 1: - if r == 0: - return None - r = -r + if case & 1 and r == 0: + return None v = (-u + r / s) / 2 w = s.sqrt() if w is None: return None - if case & 4: - w = -w - return w * (u * (MINUS_3_SQRT - 1) / 2 - v) + if case & 5 == 0: return -w * (u * (1 - MINUS_3_SQRT) / 2 + v) + if case & 5 == 1: return w * (u * (1 + MINUS_3_SQRT) / 2 + v) + if case & 5 == 4: return w * (u * (1 - MINUS_3_SQRT) / 2 + v) + if case & 5 == 5: return -w * (u * (1 + MINUS_3_SQRT) / 2 + v) def xelligatorswift(x): """Given a field element X on the curve, find (u, t) that encode them.""" @@ -328,12 +384,17 @@ def ellswift_create(): u, t = xelligatorswift((priv * SECP256K1_G).x) return priv.to_bytes(32, 'big'), u.to_bytes() + t.to_bytes() +def ellswift_decode(ellswift): + """Convert ellswift encoded X coordinate to 32-byte xonly format.""" + u = FE(int.from_bytes(ellswift[:32], 'big')) + t = FE(int.from_bytes(ellswift[32:], 'big')) + return xswiftec(u, t).to_bytes() + def ellswift_ecdh_xonly(pubkey_theirs, privkey): """Compute X coordinate of shared ECDH point between elswift pubkey and privkey.""" - u = FE(int.from_bytes(pubkey_theirs[:32], 'big')) - t = FE(int.from_bytes(pubkey_theirs[32:], 'big')) d = int.from_bytes(privkey, 'big') - return (d * GE.lift_x(xswiftec(u, t))).x.to_bytes() + pub = ellswift_decode(pubkey_theirs) + return (d * GE.lift_x(FE.from_bytes(pub))).x.to_bytes() ### Poly1305 @@ -402,7 +463,7 @@ def chacha20_block(key, nonce, cnt): for i in range(3): init[13 + i] = int.from_bytes(nonce[4 * i:4 * (i+1)], 'little') # Perform 20 rounds. - state = [v for v in init] + state = list(init) for _ in range(10): chacha20_doubleround(state) # Add initial values back into state. @@ -459,6 +520,7 @@ def __init__(self, initial_key): self.packet_counter = 0 def crypt(self, aad, text, is_decrypt): + """Encrypt or decrypt the specified (plain/cipher)text.""" nonce = ((self.packet_counter % REKEY_INTERVAL).to_bytes(4, 'little') + (self.packet_counter // REKEY_INTERVAL).to_bytes(8, 'little')) if is_decrypt: @@ -474,12 +536,14 @@ def crypt(self, aad, text, is_decrypt): self.packet_counter += 1 return ret - def decrypt(self, aad, ciphertext): - return self.crypt(aad, ciphertext, True) - def encrypt(self, aad, plaintext): + """Encrypt the specified plaintext with provided AAD.""" return self.crypt(aad, plaintext, False) + def decrypt(self, aad, ciphertext): + """Decrypt the specified ciphertext with provided AAD.""" + return self.crypt(aad, ciphertext, True) + class FSChaCha20: """Rekeying wrapper stream cipher around ChaCha20.""" @@ -491,6 +555,7 @@ def __init__(self, initial_key): self.keystream = b'' def get_keystream_bytes(self, nbytes): + """Generate nbytes keystream bytes.""" while len(self.keystream) < nbytes: nonce = ((0).to_bytes(4, 'little') + (self.chunk_counter // REKEY_INTERVAL).to_bytes(8, 'little')) @@ -501,6 +566,7 @@ def get_keystream_bytes(self, nbytes): return ret def crypt(self, chunk): + """Encrypt or decypt chunk.""" ks = self.get_keystream_bytes(len(chunk)) ret = bytes([ks[i] ^ chunk[i] for i in range(len(chunk))]) if ((self.chunk_counter + 1) % REKEY_INTERVAL) == 0: @@ -509,6 +575,15 @@ def crypt(self, chunk): self.chunk_counter += 1 return ret + def encrypt(self, chunk): + """Encrypt chunk.""" + return self.crypt(chunk) + + def decrypt(self, chunk): + """Decrypt chunk.""" + return self.crypt(chunk) + + ### Shared secret computation def v2_ecdh(priv, ellswift_theirs, ellswift_ours, initiating): @@ -519,10 +594,9 @@ def v2_ecdh(priv, ellswift_theirs, ellswift_ours, initiating): # Initiating, place our public key encoding first. return TaggedHash("bip324_ellswift_xonly_ecdh", ellswift_ours + ellswift_theirs + ecdh_point_x32) - else: - # Responding, place their public key encoding first. - return TaggedHash("bip324_ellswift_xonly_ecdh", - ellswift_theirs + ellswift_ours + ecdh_point_x32) + # Responding, place their public key encoding first. + return TaggedHash("bip324_ellswift_xonly_ecdh", + ellswift_theirs + ellswift_ours + ecdh_point_x32) ### Key derivation @@ -571,5 +645,5 @@ def v2_enc_packet(peer, contents, aad=b'', ignore=False): header = (ignore << IGNORE_BIT_POS).to_bytes(HEADER_LEN, 'little') plaintext = header + contents aead_ciphertext = peer['send_P'].encrypt(aad, plaintext) - enc_plaintext_len = peer['send_L'].crypt(len(contents).to_bytes(LENGTH_FIELD_LEN, 'little')) + enc_plaintext_len = peer['send_L'].encrypt(len(contents).to_bytes(LENGTH_FIELD_LEN, 'little')) return enc_plaintext_len + aead_ciphertext diff --git a/bip-0324/run_test_vectors.py b/bip-0324/run_test_vectors.py index ada7371a5e..8e4b8f255b 100644 --- a/bip-0324/run_test_vectors.py +++ b/bip-0324/run_test_vectors.py @@ -1,53 +1,69 @@ +"""Run the BIP-324 test vectors.""" + import csv import os import sys import reference -with open(os.path.join(sys.path[0], 'packet_encoding_test_vectors.csv'), newline='') as csvfile: - reader = csv.reader(csvfile) - reader.__next__() - for row in reader: - in_idx, in_priv_ours, in_ellswift_ours, in_ellswift_theirs, in_initiating, in_content, in_multiply, in_aad, in_ignore, mid_x_ours, mid_x_shared, mid_shared_secret, mid_initiator_l, mid_initiator_p, mid_responder_l, mid_responder_p, mid_send_garbage_terminator, mid_recv_garbage_terminator, mid_session_id, out_ciphertext, out_ciphertext_endswith = row +FILENAME_PACKET_TEST = os.path.join(sys.path[0], 'packet_encoding_test_vectors.csv') +FILENAME_XSWIFTEC_INV_TEST = os.path.join(sys.path[0], 'xswiftec_inv_test_vectors.csv') +FILENAME_ELLSWIFT_DECODE_TEST = os.path.join(sys.path[0], 'ellswift_decode_test_vectors.csv') - assert mid_x_ours == (int.from_bytes(bytes.fromhex(in_priv_ours), 'big') * reference.SECP256K1_G).x.to_bytes().hex() - assert mid_x_shared == reference.ellswift_ecdh_xonly(bytes.fromhex(in_ellswift_theirs), bytes.fromhex(in_priv_ours)).hex() - assert mid_shared_secret == reference.v2_ecdh(bytes.fromhex(in_priv_ours), bytes.fromhex(in_ellswift_theirs), bytes.fromhex(in_ellswift_ours), int(in_initiating)).hex() +with open(FILENAME_PACKET_TEST, newline='', encoding='utf-8') as csvfile: + print(f"Running {FILENAME_PACKET_TEST} tests...") + reader = csv.DictReader(csvfile) + for row in reader: + in_initiating = int(row['in_initiating']) + bytes_priv_ours = bytes.fromhex(row['in_priv_ours']) + int_priv_ours = int.from_bytes(bytes_priv_ours, 'big') + assert row['mid_x_ours'] == (int_priv_ours * reference.SECP256K1_G).x.to_bytes().hex() + bytes_ellswift_ours = bytes.fromhex(row['in_ellswift_ours']) + assert row['mid_x_ours'] == reference.ellswift_decode(bytes_ellswift_ours).hex() + bytes_ellswift_theirs = bytes.fromhex(row['in_ellswift_theirs']) + assert row['mid_x_theirs'] == reference.ellswift_decode(bytes_ellswift_theirs).hex() + x_shared = reference.ellswift_ecdh_xonly(bytes_ellswift_theirs, bytes_priv_ours) + assert row['mid_x_shared'] == x_shared.hex() + shared_secret = reference.v2_ecdh(bytes_priv_ours, bytes_ellswift_theirs, + bytes_ellswift_ours, in_initiating) + assert row['mid_shared_secret'] == shared_secret.hex() - peer = reference.initialize_v2_transport(bytes.fromhex(mid_shared_secret), int(in_initiating)) - assert mid_initiator_l == peer['initiator_L'].hex() - assert mid_initiator_p == peer['initiator_P'].hex() - assert mid_responder_l == peer['responder_L'].hex() - assert mid_responder_p == peer['responder_P'].hex() - assert mid_send_garbage_terminator == peer['send_garbage_terminator'].hex() - assert mid_recv_garbage_terminator == peer['recv_garbage_terminator'].hex() - assert mid_session_id == peer['session_id'].hex() - for _ in range(int(in_idx)): + peer = reference.initialize_v2_transport(shared_secret, in_initiating) + assert row['mid_initiator_l'] == peer['initiator_L'].hex() + assert row['mid_initiator_p'] == peer['initiator_P'].hex() + assert row['mid_responder_l'] == peer['responder_L'].hex() + assert row['mid_responder_p'] == peer['responder_P'].hex() + assert row['mid_send_garbage_terminator'] == peer['send_garbage_terminator'].hex() + assert row['mid_recv_garbage_terminator'] == peer['recv_garbage_terminator'].hex() + assert row['out_session_id'] == peer['session_id'].hex() + for _ in range(int(row['in_idx'])): reference.v2_enc_packet(peer, b"") - ciphertext = reference.v2_enc_packet(peer, bytes.fromhex(in_content) * int(in_multiply), bytes.fromhex(in_aad), int(in_ignore)) - if len(out_ciphertext): - assert out_ciphertext == ciphertext.hex() - if len(out_ciphertext_endswith): - assert ciphertext.hex().endswith(out_ciphertext_endswith) + ciphertext = reference.v2_enc_packet( + peer, + bytes.fromhex(row['in_contents']) * int(row['in_multiply']), + bytes.fromhex(row['in_aad']), int(row['in_ignore'])) + if len(row['out_ciphertext']): + assert row['out_ciphertext'] == ciphertext.hex() + if len(row['out_ciphertext_endswith']): + assert ciphertext.hex().endswith(row['out_ciphertext_endswith']) -with open(os.path.join(sys.path[0], 'xswiftec_test_vectors.csv'), newline='') as csvfile: - reader = csv.reader(csvfile) - reader.__next__() +with open(FILENAME_XSWIFTEC_INV_TEST, newline='', encoding='utf-8') as csvfile: + print(f"Running {FILENAME_XSWIFTEC_INV_TEST} tests...") + reader = csv.DictReader(csvfile) for row in reader: - u = reference.FE.from_bytes(bytes.fromhex(row[0])) - x = reference.FE.from_bytes(bytes.fromhex(row[1])) + u = reference.FE.from_bytes(bytes.fromhex(row['u'])) + x = reference.FE.from_bytes(bytes.fromhex(row['x'])) for case in range(8): ret = reference.xswiftec_inv(x, u, case) if ret is None: - assert row[2 + case] == "" + assert row[f"case{case}_t"] == "" else: - assert row[2 + case] == ret.to_bytes().hex() + assert row[f"case{case}_t"] == ret.to_bytes().hex() assert reference.xswiftec(u, ret) == x -with open(os.path.join(sys.path[0], 'xelligatorswift_test_vectors.csv'), newline='') as csvfile: - reader = csv.reader(csvfile) - reader.__next__() +with open(FILENAME_ELLSWIFT_DECODE_TEST, newline='', encoding='utf-8') as csvfile: + print(f"Running {FILENAME_ELLSWIFT_DECODE_TEST} tests...") + reader = csv.DictReader(csvfile) for row in reader: - ellswift = bytes.fromhex(row[0]) - x = bytes.fromhex(row[1]) - assert reference.ellswift_ecdh_xonly(ellswift, (1).to_bytes(32, 'big')) == x + ellswift = bytes.fromhex(row['ellswift']) + assert reference.ellswift_decode(ellswift).hex() == row['x'] diff --git a/bip-0324/secp256k1_test_vectors.py b/bip-0324/secp256k1_test_vectors.py new file mode 100644 index 0000000000..57ae801cc7 --- /dev/null +++ b/bip-0324/secp256k1_test_vectors.py @@ -0,0 +1,52 @@ +"""Convert the BIP-324 test vectors to secp256k1 code.""" + +import csv +import reference +import os +import sys + +FILENAME_XSWIFTEC_INV_TEST = os.path.join(sys.path[0], 'xswiftec_inv_test_vectors.csv') +FILENAME_ELLSWIFT_DECODE_TEST = os.path.join(sys.path[0], 'ellswift_decode_test_vectors.csv') + +def format_int(v): + """Format 0 as "0", but other integers as 0x%08x.""" + if v == 0: + return "0" + return f"0x{v:08x}" + +def format_fe(fe): + """Format a field element constant as SECP256K1_FE_CONST code.""" + vals = [(int(fe) >> (32 * (7 - i))) & 0xffffffff for i in range(8)] + strs = ", ".join(format_int(v) for v in vals) + return f"SECP256K1_FE_CONST({strs})" + +def output_xswiftec_inv_cases(): + """Generate lines corresponding to the xswiftec_inv test cases.""" + with open(FILENAME_XSWIFTEC_INV_TEST, newline='', encoding='utf-8') as csvfile: + reader = csv.DictReader(csvfile) + print("xswiftec_inv cases:") + for row in reader: + u = int.from_bytes(bytes.fromhex(row['u']), 'big') + x = int.from_bytes(bytes.fromhex(row['x']), 'big') + pat = sum(1< Date: Thu, 12 Jan 2023 13:41:06 +0100 Subject: [PATCH 031/454] BIP341: Fix definition of NUMS point --- bip-0341.mediawiki | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/bip-0341.mediawiki b/bip-0341.mediawiki index 8d2af3ccc6..3cb19a24f0 100644 --- a/bip-0341.mediawiki +++ b/bip-0341.mediawiki @@ -152,7 +152,7 @@ Satisfying any of these conditions is sufficient to spend the output. '''Initial steps''' The first step is determining what the internal key and the organization of the rest of the scripts should be. The specifics are likely application dependent, but here are some general guidelines: * When deciding between scripts with conditionals (OP_IF etc.) and splitting them up into multiple scripts (each corresponding to one execution path through the original script), it is generally preferable to pick the latter. * When a single condition requires signatures with multiple keys, key aggregation techniques like MuSig can be used to combine them into a single key. The details are out of scope for this document, but note that this may complicate the signing procedure. -* If one or more of the spending conditions consist of just a single key (after aggregation), the most likely one should be made the internal key. If no such condition exists, it may be worthwhile adding one that consists of an aggregation of all keys participating in all scripts combined; effectively adding an "everyone agrees" branch. If that is inacceptable, pick as internal key a point with unknown discrete logarithm. One example of such a point is ''H = lift_x(0x0250929b74c1a04954b78b4b6035e97a5e078a5a0f28ec96d547bfee9ace803ac0)'' which is [https://github.com/ElementsProject/secp256k1-zkp/blob/11af7015de624b010424273be3d91f117f172c82/src/modules/rangeproof/main_impl.h#L16 constructed] by taking the hash of the standard uncompressed encoding of the [https://www.secg.org/sec2-v2.pdf secp256k1] base point ''G'' as X coordinate. In order to avoid leaking the information that key path spending is not possible it is recommended to pick a fresh integer ''r'' in the range ''0...n-1'' uniformly at random and use ''H + rG'' as internal key. It is possible to prove that this internal key does not have a known discrete logarithm with respect to ''G'' by revealing ''r'' to a verifier who can then reconstruct how the internal key was created. +* If one or more of the spending conditions consist of just a single key (after aggregation), the most likely one should be made the internal key. If no such condition exists, it may be worthwhile adding one that consists of an aggregation of all keys participating in all scripts combined; effectively adding an "everyone agrees" branch. If that is inacceptable, pick as internal key a point with unknown discrete logarithm. One example of such a point is ''H = lift_x(0x50929b74c1a04954b78b4b6035e97a5e078a5a0f28ec96d547bfee9ace803ac0)'' which is [https://github.com/ElementsProject/secp256k1-zkp/blob/11af7015de624b010424273be3d91f117f172c82/src/modules/rangeproof/main_impl.h#L16 constructed] by taking the hash of the standard uncompressed encoding of the [https://www.secg.org/sec2-v2.pdf secp256k1] base point ''G'' as X coordinate. In order to avoid leaking the information that key path spending is not possible it is recommended to pick a fresh integer ''r'' in the range ''0...n-1'' uniformly at random and use ''H + rG'' as internal key. It is possible to prove that this internal key does not have a known discrete logarithm with respect to ''G'' by revealing ''r'' to a verifier who can then reconstruct how the internal key was created. * If the spending conditions do not require a script path, the output key should commit to an unspendable script path instead of having no script path. This can be achieved by computing the output key point as ''Q = P + int(hashTapTweak(bytes(P)))G''. '''Why should the output key always have a taproot commitment, even if there is no script path?''' If the taproot output key is an aggregate of keys, there is the possibility for a malicious party to add a script path without being noticed by the other parties. This allows to bypass the multiparty policy and to steal the coin. From 6e7e5a252376e0be46617434bf5d7f8bd2ce4ecb Mon Sep 17 00:00:00 2001 From: Tim Ruffing Date: Thu, 12 Jan 2023 13:50:46 +0100 Subject: [PATCH 032/454] BIP341: Use the term "NUMS" --- bip-0341.mediawiki | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/bip-0341.mediawiki b/bip-0341.mediawiki index 3cb19a24f0..c3e35b6a86 100644 --- a/bip-0341.mediawiki +++ b/bip-0341.mediawiki @@ -152,7 +152,7 @@ Satisfying any of these conditions is sufficient to spend the output. '''Initial steps''' The first step is determining what the internal key and the organization of the rest of the scripts should be. The specifics are likely application dependent, but here are some general guidelines: * When deciding between scripts with conditionals (OP_IF etc.) and splitting them up into multiple scripts (each corresponding to one execution path through the original script), it is generally preferable to pick the latter. * When a single condition requires signatures with multiple keys, key aggregation techniques like MuSig can be used to combine them into a single key. The details are out of scope for this document, but note that this may complicate the signing procedure. -* If one or more of the spending conditions consist of just a single key (after aggregation), the most likely one should be made the internal key. If no such condition exists, it may be worthwhile adding one that consists of an aggregation of all keys participating in all scripts combined; effectively adding an "everyone agrees" branch. If that is inacceptable, pick as internal key a point with unknown discrete logarithm. One example of such a point is ''H = lift_x(0x50929b74c1a04954b78b4b6035e97a5e078a5a0f28ec96d547bfee9ace803ac0)'' which is [https://github.com/ElementsProject/secp256k1-zkp/blob/11af7015de624b010424273be3d91f117f172c82/src/modules/rangeproof/main_impl.h#L16 constructed] by taking the hash of the standard uncompressed encoding of the [https://www.secg.org/sec2-v2.pdf secp256k1] base point ''G'' as X coordinate. In order to avoid leaking the information that key path spending is not possible it is recommended to pick a fresh integer ''r'' in the range ''0...n-1'' uniformly at random and use ''H + rG'' as internal key. It is possible to prove that this internal key does not have a known discrete logarithm with respect to ''G'' by revealing ''r'' to a verifier who can then reconstruct how the internal key was created. +* If one or more of the spending conditions consist of just a single key (after aggregation), the most likely one should be made the internal key. If no such condition exists, it may be worthwhile adding one that consists of an aggregation of all keys participating in all scripts combined; effectively adding an "everyone agrees" branch. If that is inacceptable, pick as internal key a "Nothing Up My Sleeve" (NUMS) point, i.e., a point with unknown discrete logarithm. One example of such a point is ''H = lift_x(0x50929b74c1a04954b78b4b6035e97a5e078a5a0f28ec96d547bfee9ace803ac0)'' which is [https://github.com/ElementsProject/secp256k1-zkp/blob/11af7015de624b010424273be3d91f117f172c82/src/modules/rangeproof/main_impl.h#L16 constructed] by taking the hash of the standard uncompressed encoding of the [https://www.secg.org/sec2-v2.pdf secp256k1] base point ''G'' as X coordinate. In order to avoid leaking the information that key path spending is not possible it is recommended to pick a fresh integer ''r'' in the range ''0...n-1'' uniformly at random and use ''H + rG'' as internal key. It is possible to prove that this internal key does not have a known discrete logarithm with respect to ''G'' by revealing ''r'' to a verifier who can then reconstruct how the internal key was created. * If the spending conditions do not require a script path, the output key should commit to an unspendable script path instead of having no script path. This can be achieved by computing the output key point as ''Q = P + int(hashTapTweak(bytes(P)))G''. '''Why should the output key always have a taproot commitment, even if there is no script path?''' If the taproot output key is an aggregate of keys, there is the possibility for a malicious party to add a script path without being noticed by the other parties. This allows to bypass the multiparty policy and to steal the coin. From 41490b74f7a9d52a58d9a1e1fd94f3ee6d8553e7 Mon Sep 17 00:00:00 2001 From: craigraw Date: Tue, 17 Jan 2023 01:40:46 +0200 Subject: [PATCH 033/454] Wallet Labels Export Format (#1383) * initial commit * fix formatting * add importing section * clarify csv preference * tabs to spaces * add rationale and references, require that rfc4180 is followed * fix reference links * show reference links as list * use self describing json lines format instead of csv * add bip number and accommodate 65 byte pubkeys * fix comments uri --- bip-0329.mediawiki | 131 +++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 131 insertions(+) create mode 100644 bip-0329.mediawiki diff --git a/bip-0329.mediawiki b/bip-0329.mediawiki new file mode 100644 index 0000000000..9a8b270937 --- /dev/null +++ b/bip-0329.mediawiki @@ -0,0 +1,131 @@ +

+  BIP: 329
+  Layer: Applications
+  Title: Wallet Labels Export Format
+  Author: Craig Raw 
+  Comments-Summary: No comments yet.
+  Comments-URI: https://github.com/bitcoin/bips/wiki/Comments:BIP-0329
+  Status: Draft
+  Type: Informational
+  Created: 2022-08-23
+  License: BSD-2-Clause
+
+ +==Abstract== + +This document specifies a format for the export of labels that may be attached to various common types of records in a wallet. + +==Copyright== + +This BIP is licensed under the BSD 2-clause license. + +==Motivation== + +The export and import of funds across different Bitcoin wallet applications is well defined through standards such as BIP39, BIP32, BIP44 etc. +These standards are well supported and allow users to move easily between different wallets. +There is, however, no defined standard to transfer any labels the user may have applied to the transactions, addresses, public keys, inputs, outputs or xpubs in their wallet. +The UTXO model that Bitcoin uses makes these labels particularly valuable as they may indicate the source of funds, whether received externally or as a result of change from a prior transaction. +In both cases, care must be taken when spending to avoid undesirable leaks of private information. +Labels provide valuable guidance in this regard, and have even become mandatory when spending in several Bitcoin wallets. +Allowing users to import and export their labels in a standardized way ensures that they do not experience lock-in to a particular wallet application. + +==Rationale== + +While there is currently no widely accepted format for exporting and importing labels, there are existing formats in use. +SLIP-0015[https://github.com/satoshilabs/slips/blob/master/slip-0015.md SLIP-0015] defines a format for exporting address and output labels, but requires encryption using a private key associated with the wallet seed, and thus cannot be used independently by coordinator wallets which cannot access private keys. +The Electrum wallet imports and exports address and transaction labels in a JSON format which could be used with other record types, but the format used is not self describing making record type identification difficult. + +==Specification== + +In order to be lightweight, human readable and well structured, this BIP uses a JSON format. +Further, the JSON Lines format is used (also called newline-delimited JSON)[https://jsonlines.org/ jsonlines.org]. +This allows a document to be split, streamed, or incrementally added to, and limits the potential for formatting errors to invalidate an entire import. +It is also a convenient format for command-line processing, which is often line-oriented. + +Further to the JSON Lines specification, an export of labels from a wallet must be a UTF-8 encoded text file, containing one record per line consisting of a valid JSON object. +Lines are separated by \n. Multiline values are not permitted. +Each JSON object must contain 3 key/value pairs, defined as follows: + +{| class="wikitable" +|- +! Key +! Description +|- +| type +| One of tx, addr, pubkey, input, output or xpub +|- +| ref +| Reference to the transaction, address, public key, input, output or extended public key +|- +| label +| The label applied to the reference +|} + +The reference is defined for each type as follows: + +{| class="wikitable" +|- +! Type +! Description +! Example +|- +| tx +| Transaction id in hexadecimal format +| f91d0a8a78462bc59398f2c5d7a84fcff491c26ba54c4833478b202796c8aafd +|- +| addr +| Address in base58 or bech32 format +| bc1q34aq5drpuwy3wgl9lhup9892qp6svr8ldzyy7c +|- +| pubkey +| 32, 33 or 65 byte public key in hexadecimal format +| 0283409659355b6d1cc3c32decd5d561abaac86c37a353b52895a5e6c196d6f448 +|- +| input +| Transaction id and input index separated by a colon +| f91d0a8a78462bc59398f2c5d7a84fcff491c26ba54c4833478b202796c8aafd:0 +|- +| output +| Transaction id and output index separated by a colon +| f91d0a8a78462bc59398f2c5d7a84fcff491c26ba54c4833478b202796c8aafd:1 +|- +| xpub +| Extended public key as defined by BIP32 +| xpub661MyMwAqRbcFtXgS5sYJABqqG9YLmC4Q1Rdap9gSE8Nq... +|} + +Care should be taken when exporting due to the privacy sensitive nature of the data. +Encryption in transit over untrusted networks is highly recommended, and encryption at rest should also be considered. +Unencrypted exports should be deleted as soon as possible. +For security reasons no private key types are defined. + +==Importing== + +* An importing wallet may ignore records it does not store, and truncate labels if necessary. +* Wallets importing public key records may derive addresses from them to match against known wallet addresses. +* Wallets importing extended public keys may match them against signers, for example in a multisig setup. + +==Backwards Compatibility== + +The nature of this format makes it naturally extensible to handle other record types. +However, importing wallets complying to this specification may ignore types not defined here. + +==Test Vectors== + +The following fragment represents a wallet label export: +
+{ "type": "tx", "ref": "f91d0a8a78462bc59398f2c5d7a84fcff491c26ba54c4833478b202796c8aafd", "label": "Transaction" }
+{ "type": "addr", "ref": "bc1q34aq5drpuwy3wgl9lhup9892qp6svr8ldzyy7c", "label": "Address" }
+{ "type": "pubkey", "ref": "0283409659355b6d1cc3c32decd5d561abaac86c37a353b52895a5e6c196d6f448", "label": "Public Key" }
+{ "type": "input", "ref": "f91d0a8a78462bc59398f2c5d7a84fcff491c26ba54c4833478b202796c8aafd:0", "label": "Input" }
+{ "type": "output", "ref": "f91d0a8a78462bc59398f2c5d7a84fcff491c26ba54c4833478b202796c8aafd:1", "label": "Output" }
+{ "type": "xpub", "ref": "xpub661MyMwAqRbcFtXgS5sYJABqqG9YLmC4Q1Rdap9gSE8NqtwybGhePY2gZ29ESFjqJoCu1Rupje8YtGqsefD265TMg7usUDFdp6W1EGMcet8", "label": "Extended Public Key" }
+
+ +==Reference Implementation== + +TBD + +==References== + + From 7e0c47e1f6fb631d29a87bf4cc13cfda1552d8be Mon Sep 17 00:00:00 2001 From: Gregory Sanders Date: Tue, 17 Jan 2023 14:14:54 -0500 Subject: [PATCH 034/454] uiht --- bip-0174.mediawiki | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/bip-0174.mediawiki b/bip-0174.mediawiki index 0d260ee640..a8f9ac8a2a 100644 --- a/bip-0174.mediawiki +++ b/bip-0174.mediawiki @@ -410,7 +410,7 @@ The currently defined per-input types are defined as follows: | PSBT_IN_REQUIRED_HEIGHT_LOCKTIME = 0x12 | None | No key data -| <32-bit uiht locktime> +| <32-bit uint locktime> | 32 bit unsigned little endian integer less than 500000000 representing the minimum block height that this input requires to be set as the transaction's lock time. | | 0 From fa4eeeef38a1dd4f26aad7220127a61097d3eca2 Mon Sep 17 00:00:00 2001 From: John Moffett <116917595+john-moffett@users.noreply.github.com> Date: Tue, 31 Jan 2023 13:12:53 -0500 Subject: [PATCH 035/454] Fix description of M parameter The M parameter is used as the inverse of the false probability rate, so change its incorrect usage in two places. --- bip-0158.mediawiki | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/bip-0158.mediawiki b/bip-0158.mediawiki index 484e674789..46771131a9 100644 --- a/bip-0158.mediawiki +++ b/bip-0158.mediawiki @@ -85,7 +85,7 @@ one is able to select both Parameters independently, then more optimal values can be selectedhttps://gist.github.com/sipa/576d5f09c3b86c3b1b75598d799fc845. Set membership queries against the hash outputs will have a false positive rate -of M. To avoid integer overflow, the number of items N +of 1 / M. To avoid integer overflow, the number of items N MUST be <2^32 and M MUST be <2^32. The items are first passed through the pseudorandom function ''SipHash'', which @@ -189,7 +189,7 @@ golomb_decode(stream, P: uint) -> uint64: A GCS is constructed from four parameters: * L, a vector of N raw items * P, the bit parameter of the Golomb-Rice coding -* M, the target false positive rate +* M, the inverse of the target false positive rate * k, the 128-bit key used to randomize the SipHash outputs The result is a byte vector with a minimum size of N * (P + 1) From 0a5e3b0101f5f040fd34d83a13ebe59a445c12d8 Mon Sep 17 00:00:00 2001 From: Craig Raw Date: Fri, 3 Feb 2023 10:14:25 +0200 Subject: [PATCH 036/454] add optional key origin property and expand truncation note --- bip-0329.mediawiki | 12 +++++++++--- 1 file changed, 9 insertions(+), 3 deletions(-) diff --git a/bip-0329.mediawiki b/bip-0329.mediawiki index 9a8b270937..9a25c536f4 100644 --- a/bip-0329.mediawiki +++ b/bip-0329.mediawiki @@ -44,7 +44,7 @@ It is also a convenient format for command-line processing, which is often line- Further to the JSON Lines specification, an export of labels from a wallet must be a UTF-8 encoded text file, containing one record per line consisting of a valid JSON object. Lines are separated by \n. Multiline values are not permitted. -Each JSON object must contain 3 key/value pairs, defined as follows: +Each JSON object must contain 3 or 4 key/value pairs, defined as follows: {| class="wikitable" |- @@ -59,6 +59,9 @@ Each JSON object must contain 3 key/value pairs, defined as follows: |- | label | The label applied to the reference +|- +| origin +| Optional key origin information referencing the wallet associated with the label |} The reference is defined for each type as follows: @@ -94,6 +97,9 @@ The reference is defined for each type as follows: | xpub661MyMwAqRbcFtXgS5sYJABqqG9YLmC4Q1Rdap9gSE8Nq... |} +If present, the optional origin property must contain key origin information as defined by BIP380[https://github.com/bitcoin/bips/blob/master/bip-0380.mediawiki BIP-0380], without the opening or closing brackets. +This property should be used to disambiguate labels from different wallets contained in the same export, particularly when exporting multiple accounts derived from the same seed. + Care should be taken when exporting due to the privacy sensitive nature of the data. Encryption in transit over untrusted networks is highly recommended, and encryption at rest should also be considered. Unencrypted exports should be deleted as soon as possible. @@ -101,7 +107,7 @@ For security reasons no private key types are defined. ==Importing== -* An importing wallet may ignore records it does not store, and truncate labels if necessary. +* An importing wallet may ignore records it does not store, and truncate labels if necessary. A suggested default for maximum label length is 255 characters, and an importing wallet should consider warning the user if truncation is applied. * Wallets importing public key records may derive addresses from them to match against known wallet addresses. * Wallets importing extended public keys may match them against signers, for example in a multisig setup. @@ -114,7 +120,7 @@ However, importing wallets complying to this specification may ignore types not The following fragment represents a wallet label export:
-{ "type": "tx", "ref": "f91d0a8a78462bc59398f2c5d7a84fcff491c26ba54c4833478b202796c8aafd", "label": "Transaction" }
+{ "type": "tx", "ref": "f91d0a8a78462bc59398f2c5d7a84fcff491c26ba54c4833478b202796c8aafd", "label": "Transaction", "origin": "d34db33f/84'/0'/0'" }
 { "type": "addr", "ref": "bc1q34aq5drpuwy3wgl9lhup9892qp6svr8ldzyy7c", "label": "Address" }
 { "type": "pubkey", "ref": "0283409659355b6d1cc3c32decd5d561abaac86c37a353b52895a5e6c196d6f448", "label": "Public Key" }
 { "type": "input", "ref": "f91d0a8a78462bc59398f2c5d7a84fcff491c26ba54c4833478b202796c8aafd:0", "label": "Input" }

From 5cafddcccabe3f88a0a2c3cd74944172ab6b9776 Mon Sep 17 00:00:00 2001
From: AJ ONeal 
Date: Fri, 3 Feb 2023 16:11:11 -0700
Subject: [PATCH 037/454] feat: add DashPhrase.js to JS implementations

---
 bip-0039.mediawiki | 1 +
 1 file changed, 1 insertion(+)

diff --git a/bip-0039.mediawiki b/bip-0039.mediawiki
index d8a4d253d6..636e7a57ab 100644
--- a/bip-0039.mediawiki
+++ b/bip-0039.mediawiki
@@ -168,6 +168,7 @@ Haskell:
 JavaScript:
 * https://github.com/bitpay/bitcore/tree/master/packages/bitcore-mnemonic
 * https://github.com/bitcoinjs/bip39 (used by [[https://github.com/blockchain/My-Wallet-V3/blob/v3.8.0/src/hd-wallet.js#L121-L146|blockchain.info]])
+* https://github.com/dashhive/DashPhrase.js
 * https://github.com/hujiulong/web-bip39
 
 Java:

From 96a9adedde84d622e0c135f013c78bac5eae7a03 Mon Sep 17 00:00:00 2001
From: Craig Raw 
Date: Tue, 7 Feb 2023 11:05:53 +0200
Subject: [PATCH 038/454] change origin attribute to reflect an abbreviated
 output descriptor containing key origin information

---
 bip-0329.mediawiki | 7 ++++---
 1 file changed, 4 insertions(+), 3 deletions(-)

diff --git a/bip-0329.mediawiki b/bip-0329.mediawiki
index 9a25c536f4..737a75d77a 100644
--- a/bip-0329.mediawiki
+++ b/bip-0329.mediawiki
@@ -97,8 +97,8 @@ The reference is defined for each type as follows:
 | xpub661MyMwAqRbcFtXgS5sYJABqqG9YLmC4Q1Rdap9gSE8Nq...
 |}
 
-If present, the optional origin property must contain key origin information as defined by BIP380[https://github.com/bitcoin/bips/blob/master/bip-0380.mediawiki BIP-0380], without the opening or closing brackets.
-This property should be used to disambiguate labels from different wallets contained in the same export, particularly when exporting multiple accounts derived from the same seed.
+If present, the optional origin property must contain an abbreviated output descriptor (as defined by BIP380[https://github.com/bitcoin/bips/blob/master/bip-0380.mediawiki BIP-0380]) describing a BIP32 compatible originating wallet, including all key origin information but excluding any actual keys, any child path elements, or a checksum.
+This property should be used to disambiguate transaction labels from different wallets contained in the same export, particularly when exporting multiple accounts derived from the same seed.
 
 Care should be taken when exporting due to the privacy sensitive nature of the data. 
 Encryption in transit over untrusted networks is highly recommended, and encryption at rest should also be considered.
@@ -120,12 +120,13 @@ However, importing wallets complying to this specification may ignore types not
 
 The following fragment represents a wallet label export:
 
-{ "type": "tx", "ref": "f91d0a8a78462bc59398f2c5d7a84fcff491c26ba54c4833478b202796c8aafd", "label": "Transaction", "origin": "d34db33f/84'/0'/0'" }
+{ "type": "tx", "ref": "f91d0a8a78462bc59398f2c5d7a84fcff491c26ba54c4833478b202796c8aafd", "label": "Transaction", "origin": "wpkh([d34db33f/84'/0'/0'])" }
 { "type": "addr", "ref": "bc1q34aq5drpuwy3wgl9lhup9892qp6svr8ldzyy7c", "label": "Address" }
 { "type": "pubkey", "ref": "0283409659355b6d1cc3c32decd5d561abaac86c37a353b52895a5e6c196d6f448", "label": "Public Key" }
 { "type": "input", "ref": "f91d0a8a78462bc59398f2c5d7a84fcff491c26ba54c4833478b202796c8aafd:0", "label": "Input" }
 { "type": "output", "ref": "f91d0a8a78462bc59398f2c5d7a84fcff491c26ba54c4833478b202796c8aafd:1", "label": "Output" }
 { "type": "xpub", "ref": "xpub661MyMwAqRbcFtXgS5sYJABqqG9YLmC4Q1Rdap9gSE8NqtwybGhePY2gZ29ESFjqJoCu1Rupje8YtGqsefD265TMg7usUDFdp6W1EGMcet8", "label": "Extended Public Key" }
+{ "type": "tx", "ref": "f546156d9044844e02b181026a1a407abfca62e7ea1159f87bbeaa77b4286c74", "label": "Account #1 Transaction", "origin": "wpkh([d34db33f/84'/0'/1'])" }
 
==Reference Implementation== From 1c5572b61757344b1fd76cedb7aebaefabffd75f Mon Sep 17 00:00:00 2001 From: Jack Date: Wed, 8 Feb 2023 08:51:28 -0900 Subject: [PATCH 039/454] Fix valuedata type to match description. --- bip-0174.mediawiki | 2 +- bip-0370.mediawiki | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/bip-0174.mediawiki b/bip-0174.mediawiki index a8f9ac8a2a..b7e0d05e1e 100644 --- a/bip-0174.mediawiki +++ b/bip-0174.mediawiki @@ -120,7 +120,7 @@ The currently defined global types are as follows: | PSBT_GLOBAL_TX_VERSION = 0x02 | None | No key data -| <32-bit little endian uint version> +| <32-bit little endian int version> | The 32-bit little endian signed integer representing the version number of the transaction being created. Note that this is not the same as the PSBT version number specified by the PSBT_GLOBAL_VERSION field. | 2 | 0 diff --git a/bip-0370.mediawiki b/bip-0370.mediawiki index 11b3125368..7ba0af4ccd 100644 --- a/bip-0370.mediawiki +++ b/bip-0370.mediawiki @@ -62,7 +62,7 @@ The new global types for PSBT Version 2 are as follows: | PSBT_GLOBAL_TX_VERSION = 0x02 | None | No key data -| <32-bit little endian uint version> +| <32-bit little endian int version> | The 32-bit little endian signed integer representing the version number of the transaction being created. Note that this is not the same as the PSBT version number specified by the PSBT_GLOBAL_VERSION field. | 2 | 0 From a3ad2547bc4643912f67a7aaea951fcc3b24dc82 Mon Sep 17 00:00:00 2001 From: Andrew Chow Date: Tue, 26 Jul 2022 17:16:53 -0400 Subject: [PATCH 040/454] Specify 389: Multipath descriptors --- README.mediawiki | 7 +++++ bip-0389.mediawiki | 77 ++++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 84 insertions(+) create mode 100644 bip-0389.mediawiki diff --git a/README.mediawiki b/README.mediawiki index bbfb63c8a6..9a311d5225 100644 --- a/README.mediawiki +++ b/README.mediawiki @@ -1113,6 +1113,13 @@ Those proposing changes should consider that ultimately consent may rest with th | Pieter Wuille, Andrew Chow | Informational | Draft +|- +| [[bip-0389.mediawiki|389]] +| Applications +| Multipath Descriptor Key Expressions +| Andrew Chow +| Informational +| Draft |} diff --git a/bip-0389.mediawiki b/bip-0389.mediawiki new file mode 100644 index 0000000000..fea7674925 --- /dev/null +++ b/bip-0389.mediawiki @@ -0,0 +1,77 @@ +
+  BIP: 389
+  Layer: Applications
+  Title: Multipath Descriptor Key Expressions
+  Author: Andrew Chow 
+  Comments-Summary: No comments yet.
+  Comments-URI: https://github.com/bitcoin/bips/wiki/Comments:BIP-0389
+  Status: Draft
+  Type: Informational
+  Created: 2022-07-26
+  License: BSD-2-Clause
+
+ +==Abstract== + +This document specifies a modification to Key Expressions of Descriptors that are described in BIP 380. +This modification allows Key Expressions to indicate BIP 32 derivation path steps that can have multiple values. + +==Copyright== + +This BIP is licensed under the BSD 2-clause license. + +==Motivation== + +Descriptors can describe the scripts that are used in a wallet, but wallets often require at least two descriptors for all of the scripts that they watch for. +Wallets typically have one descriptor for producing receiving addresses, and the other for change addresses. +These descriptors are often extremely similar - they produce the same types of scripts, derive keys from the same master key, and use derivation paths that are almost identical. +The only differences are in the derivation path where one of the steps will be different between the descriptors. +Thus it is useful to have a notation to represent both descriptors as a single descriptor where one of the derivation steps is a pair of values. + +==Specification== + +For extended keys and their derivations paths in a Key Expression, BIP 380 states: + +* xpub encoded extended public key or xprv encoded extended private key (as defined in BIP 32) +** Followed by zero or more /NUM or /NUMh path elements indicating BIP 32 derivation steps to be taken after the given extended key. +** Optionally followed by a single /* or /*h final step to denote all direct unhardened or hardened children. + +This is modifed to state: + +* xpub encoded extended public key or xprv encoded extended private key (as defined in BIP 32) +** Followed by zero or more /NUM (may be followed by h, H, or ' to indicate a hardened step) path elements indicating BIP 32 derivation steps to be taken after the given extended key. +** Followed by zero or one / (each NUM may be followed by h, H, or ' to indicate a hardened step) path element indicating a tuple of BIP 32 derivation steps to be taken after the given extended key. +*** Followed by zero or more ;NUM (may be followed by h, H, or ' to indicate a hardened step) additional tuple values of BIP 32 derivation steps +*** Followed by a single >/ +** Followed by zero or more /NUM (may be followed by h, H, or ' to indicate a hardened step) path elements indicating BIP 32 derivation steps to be taken after the given extended key. +** Optionally followed by a single /* (may be followed by h, H, or ' to indicate a hardened step) final step to denote all direct unhardened or hardened children. + +When a / is encountered, parsers should account for a presence of multiple descriptors where the first descriptor uses the first NUM, and a second descriptor uses the second NUM, and so on, until each NUM is accounted for in the production of public keys, scripts, and addresses, as well as descriptor import and export operations. +Descriptors that contain multiple Key Expressions that each have a / must have tuples of exactly the same length so that they are derived in lockstep in the same way that /* paths in multiple Key expressions are handled. + +The common use case for this is to represent descriptors for producing receiving and change addresses. +When interpreting for this use case, wallets should use the first descriptor for producing receiving addresses, and the second descriptor for producing change addresses. +For this use case, the element will commonly be the value /<0;1> + +Note that only one / specifier is allowed in a Key Expression. + +==Test Vectors== + +TBD + +==Backwards Compatibility== + +This is an addition to the Key Expressions defined in BIP 380. +Key Expressions using the format described in BIP 380 are compatible with this modification and parsers that implement this will still be able to parse such descriptors. +However as this is an addition to Key Expressions, older parsers will not be able to understand such descriptors. + +This modification to Key Expressions uses two new characters: < and ;. +These are part of the descriptor character set and so are covered by the checksum algorithm. +As these are previously unused characters, old parsers will not accidentally mistake them for indicating something else. + +This proposal is in contrast to similar proposals such as BIP 88 which allow for multiple derivation indexes in a single element. +This limitation exists in order to reduce the number of descriptors that are expanded, avoid confusion about how to expand the descriptor, and avoid having expanded descriptors that users are not expecting. + +==Reference Implementation== + +https://github.com/bitcoin/bitcoin/pull/22838 From 272e1f5efcbce3ba38b8c4445f5e56b34e856d57 Mon Sep 17 00:00:00 2001 From: Andrew Chow Date: Fri, 10 Feb 2023 13:01:53 -0500 Subject: [PATCH 041/454] 380: Clarify optionality of descriptor checksum Parsers must handle checksum optionality, but applications can choose to reject descriptors that don't have a checksum. --- bip-0380.mediawiki | 1 + 1 file changed, 1 insertion(+) diff --git a/bip-0380.mediawiki b/bip-0380.mediawiki index f870734183..16a2cf4d12 100644 --- a/bip-0380.mediawiki +++ b/bip-0380.mediawiki @@ -49,6 +49,7 @@ Lastly, the use of common terminology and existing standards allow for Output Sc Descriptors consist of several types of expressions. The top level expression is a SCRIPT. This expression may be followed by #CHECKSUM, where CHECKSUM is an 8 character alphanumeric descriptor checksum. +Although the checksum is optional for parsing, applications may choose to reject descriptors that do not contain a checksum. ===Script Expressions=== From ab87f494cd1615ff7bd797dc5f1d57aaa9e0b582 Mon Sep 17 00:00:00 2001 From: "Nutthawut (Jeep) Kiddee" Date: Sat, 11 Feb 2023 12:38:58 +0700 Subject: [PATCH 042/454] Add BIP-329 to the index table --- README.mediawiki | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/README.mediawiki b/README.mediawiki index f4a9ac027b..cf7ae4d5ef 100644 --- a/README.mediawiki +++ b/README.mediawiki @@ -1002,6 +1002,13 @@ Those proposing changes should consider that ultimately consent may rest with th | Informational | Draft |- +| [[bip-0329.mediawiki|329]] +| Applications +| Wallet Labels Export Format +| Craig Raw +| Informational +| Draft +|- | [[bip-0330.mediawiki|330]] | Peer Services | Transaction announcements reconciliation From b30e37c8a26d6b18415406a5664aaef9929a8ac5 Mon Sep 17 00:00:00 2001 From: James O'Beirne Date: Wed, 8 Feb 2023 16:11:18 -0500 Subject: [PATCH 043/454] Add OP_VAULT BIP --- bip-VAULT/batch-sweep.drawio.png | Bin 0 -> 62296 bytes bip-VAULT/opvault-flow.drawio.png | Bin 0 -> 47748 bytes bip-VAULT/vaults-Basic.png | Bin 0 -> 31544 bytes bip-VAULT/withdrawal-comparison.drawio.png | Bin 0 -> 19737 bytes bip-vaults.mediawiki | 750 +++++++++++++++++++++ 5 files changed, 750 insertions(+) create mode 100644 bip-VAULT/batch-sweep.drawio.png create mode 100644 bip-VAULT/opvault-flow.drawio.png create mode 100644 bip-VAULT/vaults-Basic.png create mode 100644 bip-VAULT/withdrawal-comparison.drawio.png create mode 100644 bip-vaults.mediawiki diff --git a/bip-VAULT/batch-sweep.drawio.png b/bip-VAULT/batch-sweep.drawio.png new file mode 100644 index 0000000000000000000000000000000000000000..8f142545793e10484148d50abffc7066a4510c2c GIT binary patch literal 62296 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%0Df84U&UeU(b*=co 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
}q2Cf7sc+g>-iR9ziC6tq28_xtBz|^ttE5Zs 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%0AB4oj> z!3|vC_#HSyd8yqA<=%L~qPQ&!Y9aoID=<=?knNYwU#F_Yt$#4rJ?m*L83;tfoz1@R zW^6~!!@y!k1Q!}rTgCBPeQW1#J%T^M?27a#J9S8vIak`}eN+L7%zKD-#vjig3T&lJ zC^SQ`VDv2y6qy03*naF}Zxlg^PI(q23PY0s?VmJjX}UX^g#?~q9ORqkF`~Pn#pQMr zv(%CG_$)B06wTDKpST$+p!Zk(LfUbndTcF*^@MK{7cQ5%dlIDbB~$E~CfA zZ6S=UQA`&z4`+a8Jrp>p^1RJ+8^RRkV}Ri~1)vHzJ$e_~6_=z0<;c5B`n7h}QMdUk z0oIvHqE+!|cN;gS)*0HIZkjZ5pI#O?PN4Sc+{WDfg_a0jG5-?Ja)7BCYFti7MbU~N z<;8psn2uiXnA1Q#Z^bJ|BC7|Ho@hpT?eXd^U3%7hrA4xDo$MqmMjF&OTt>(b%@YFK zmJo4|Rx;kano<3J`vuEIaqHcsFPpZCqN<_ynx7HmVUdq+8F8!j9YKeTJvbhgk|{Du!X}pnr~Tk+Z*@PwxD`@@$>7 z=|dJl&F z+FBLT+`s3K%+w=mtg8_@%Jk}a2%IT8QoJg+WtIkW+yg;L^YqS1XX1-+0F zb))fDXBUakh@m1b9h=lju6M$-nuQB;jOV`O0RaEhF#O&W{$a7vCObt^orBidF3?uc`R*Ge%VMgOb zt1wA^zg>S~^?>V*_O#v^Bha>!kC1?VH&`<2TwE@;oitKZ+Gl#(dT3@yp!u@G;V3-KMAR{IQfR6<~LO8Q&bfHn^w> zh5>NHFTJ6^!%%Y#SA5IT4~$r26}@olM-YorSje(q+${(m4jwLfD<_u$OEGf6-zDw3so^)us<@KvOIq#zN2AkF1`5 z6n&Kd!UOZauTSFd>(hMh%8WYuJ>W7Z-19X0&gx)x^HRLhSz)5hU4Z}D0hp25DRv}h zXYgZgE8sHWJm)4X*9E-P?s#_@YqguMH19?qPg@pc5+nwI07sa;m>8>h=}KKGM}w^Y z<*d(P=18&5kc!0lE6*M?8errevrh@qe&fwYh~=DwN;(k)w!o#LccUpoN}b95sv)tK z16B0H_;3EsrOI($+V*=+5YqkGr!(9RV`MhCOW!OhhZ?RoGj`d_<^S0ybYaM)$B=T} zMO2i16#r<&pHYJ$;9~4l#r`CUu&#wLym7?Q^XiFTXGr40QGft;)Oek@Z;UtJl1^P} zBo3-n#&`TWJ~umR+*6X61^rGnV!{6U?r+rJWWVHJ_0O>I-zY;Ev@YnV8;@bn9~co0dfI0|I- z`#+R6fH_miu}Zp+!!&pID)z0(A_lTtE1z2y-N#}iSxNBO=J3Dfa15Zi-K2e8lI1{x_|0gU-Mq&|!C*Z9r8H(|;O_IA z3tO*n+m0Ez*T76sXnHTqylTECgq+N;3rv9}*ccCpGn$-NMduiN&yYqgU-?JEB{zT& zN`T!o19z(bIrB`gVwfPeD9j1MWVAK@cz5=8P)WZzdG!ckTK_R~W>;{q5D!Doa({v9e72iqH7nR=K;~2NUFEa-#+VLZkTRgR zY5ca@y1}yb25$Pep_Iu%F>YxBUFEGOMH}^t(JbY)D8v`?k7ZY8QHTY2iD^&tXs#S7 zEw7pU+G7n$?gv+sZU3byKD8zak88p_!q4Mq>0%R6cA-vGe`kGGFwU!J;BJCKTV8-de2>#M3>J@^?dpQ2 zvx~g?{bFy>AnokmwE!zaV?WHgQ{8rM2XZ!e?)?Ih^MH)NpMI5yv6Q3?jUR6Mgm%J3 z>$Q^(Rnu;hrB+|RA3eC;7e3e?9)nM6xtbI5Nq2{Fh%0eLqJ2Km&&JfZ%Zlgxc zSJ$z3d2tNip8Fhzp-af5n(-Zpe-iJe{~&VD{v!&}+EsLTlGlTP!%Nh1pX%q77&i?S zFZ&T4ua~zCuD8MsxkMh|cdzx{QxGX7={T-aUljDU79K4D@jDaN3(e-1tHxFMyeYv2mr>F|AGNt3B z1$`EtY4Wo4=X5JX9($E{9m&WLxx7s*vsPK7SSGF+Ptc!9lZ##ICVv&Mw7mWlm%gb8c*#dfiTce!%>0Tb+3lWXCd-N-Na>Q5NI zgm~I8CLwdyVt6~s-sb!r{*8y(HdfMqZ&3U}l@l2ShV)viKQUPTj$)BIR`F4!_xbfcaKH{rK zhf}4SAoq%KQ8rH=`7v*>P{J`FI_EV5+rC>tu zMOW0#yynzyTG(D4DNb>ky0(fnz(AHqr`eXRUR(nFSeGT{HQ{@CYU0i=xC#{9S^@hB zG}u2plK?AWKz88#8Cu@7`S`F7>vE<$^_*!D%}&ZigwL+cvMIHFS6I#w7D3PE`#Dm%jY|#3y#Q%{U`k@zKW|>D!be>CbwdV(ulik!N zn2SqQ-;;#XzXncZqdMX4ZT~$ca;G~>=kG7idH{?;U=`9*BY6K)jQ%rNZzt=5m+hbtP|M-$G;EHLdcV~!1|;#|%w@6{%|yEGp5fvd{x~HKS)8 z@YIKcpKk;8d86&}VpCl789}D9;Pmi0wp3$+6Ppzvoj zQHNLptYhL+1G!W)h3ObAP8b@MaVE8R?|+x8{VFgC&ANxOh<(vDOYeK;wBn?#pDOw3 zm{mAuCLUN0xi@mKUAx;;4KCBVjCU(N#@kJgBTUXZ2)UEbR7Ex( zvArYbcj|_^cDi|7C1gu($pvc&x!8I^BRZ!0lFLPu1n2Ur;Or~YAnLaT%IS^B9pL9> zqPq(lQOFwUvinIbhCr|0Jl^fS7gN9UbRpj*H%h>HQVbu^MWK7>ITef3eP;! z<%E0ysp94kC6(#w2S#Bn@I_hWHanMob??aHa*Bz-jLpi>djyD1U5o{q@tNuCJ<{Jf z=B$x#P6VMAQ>bJ#>~>|8y!cqa=y|x^l98%b(Frn*O5#`gFU>u$Ju(qFQju8mYOm z{6uLPeD>82os&!HMR{`7k;jxGZPIp64o_4W6}%LJpo{b0>YYpldppZKlAmt3ivn+1 zmU6uH;@Cgr$Lz&{;0mEBp<{7rt^OB^cYz-5dyJ>RomS~9)Shh{BXJ)gW}4HybZ^M! zVS^Ik{>O7~ui13nfY@wb4##-!B*$g>UU;5vAbbs~{3Hy-aFAdAI343sf@Sm2*q%Z* zTw;|vgH0wNf4%*h%4bQba;7q^H)H1fg66(_!&(c7+a3=w<}j%!+QcR{O$qtX)Y75N zFMLlAHl_o^>H@{hC@yw-7&Zp@hF;Znn}u%h#W95vQJOaFf=4`CYCy3}UYP;*;5MwC z2yz&!Ut_b3NlXbUM25Q8ssr6-S1JI1++|2?rTNICkX*-uom}6}b8dN6uKdxi^lgE$Xx(j7aDJ%nXT=3%l&SL{0Ikb?d;B?41`k*jOLY-v-FT#jCW zSKFn|2YJx(SE5=l8-l`#{oJs?RZY2rDm659uG0&ZlYHU4Ovi#E(`Y~`8p5dfspfU> z!-)~lMJG`0H&`4*25+uR;ZBE|0_o>521fJ)SW?Wcq^`L^pBYWP*Wu=1XSdK(&7C`p zJXuJOdU=e?vT%ErsHlZs-JKYkoU9XK8s4r4L8iXrYkuG_4<2X~==5qze`P_z_nBzB zJg@AKS*GrM`k3YHRqHr?4|kgbNqCMnjd5*o5<>)tKHBcs&YrvU{JD6O)+t#jQg(T) z##V<-vi^MtHErbO*@{F{v&VDP15QH$+GKLi=G4mTfy+2E{^UTSYVRjkso5bkNe63k zrGTW_FX3qn{e~z!l#e)(hmAb!S#$Htdrv)o@4m2{CB^I*|B$P`tJ4wysH){CKyT0% z6Qk=vW1}fRW0av>2yc-Abo||Kb8psSZA-dWU)5GM5dG0J`<=ZDSked$Q1srU^!}z6%w;x@JA|tAv zo|I+??;^@lz(DLqd-`Fi(@DSz4ZWFY1hde?o(kNvb(719^I+=u*^8YRU#QC4Iay(X z_Y{ZSSWv>V(PH zJ&#LOh#6UW$+5>{?oJCDMKI<}lC=FGaNqgC@4k5iy0bwWQ!F4QqeY(%T zjIE_O=&5*={(uE0WV_x!(FNU@)-p>tC_NtLHqfsszz!wNq;cT!Y7FqDYhU=7g7s& zWLF2OSjkKY9Gmsf_&oC7u`;tem7UOEJc+p%0{joPoc%p-kM*K7VBBQrrS~t{( z+(9Fw^|Q7kbZ)NqaAx3)?>#K&7xkbCoa-rq>huF;Zf}lZJYt0^|68J&|2rc3R=>jj zlGkLGk>Jde;(SskLXFwDbZX;+1Hgtu+A;&a@Dplf?vOVs*4|1O5Pl~ zuxzPyg@-?jwhIPNGq(`c59FWE4~sEFOY{rG0RKy!W`~xmh@<9d@JkUzw-3Fu2)p$` z#Td*cS*vQ~9tZy2jehskO6VeW42*}x&pqVvH*MqS03My4gB^<3XFEM(9&sJ>8r+S) znGP|gvvy>S1Wr9YW_g9*WXC%=WrM;#KT&*tFVNE|$6K`hp=2V{t=06x(?t)|LZG_z z)GQzXgEL2nT8Z|u+HGa0HOhm?ovSxYd=eb-x4+ZY-uzierrx02?k{|s{8*K6wNZvJ z(K)taxLsU;!s|mv4)J`i0Vv(?y8B#FBueAWMENJ8Hh84T0nVZ|JRL8K?O++{p1`7& zyf=Qmf0U>-Cx*h5KtNP0ul_>>&eenm%@oIhom~|nQ7zsC5YZgWB)pAn(tSI0mqp~R zO2>U~-#ajE1Nj`rEp`|c7~fCs+_fb8At=2>vm+N})j5-n?j2kM&3A=Drn%e))NHdt zWAc&RAM$J|*xDKITf!SyL$C0_v{iOjxr@xg^o z6(OAbYK^;tD%sG*lokVzZrwH0S@zTE?Z-$ic`lKI#$8!!qb}XDZ?dVhmo7nJAO3j1 zLtXHR>fV!!eq~ZyHJik<1IjPXow{`;g*g({!L?Jb&BI~Rx!d#5w(BO2D>ot_g3mOE zbrqe@`uGai3^@oAZDO~n1`K!*4ikLIH#D{z^H6o zE4d{(51Dl2i@KLcGLrZHf~V{G13{> zQOb5)&|V;C%H|HMPvX+4yqd|Q!Pg^CCLTnZe00PnM8fUxJ7-|shDhp3wnekM$A-{a zB#TG~lbXcf@mE&~cw7txuc?2~lB!OGl`U6`%~My$_GUEw85%E6{0v@M?{Z))%E^CC}H6*_DU z#0?{e_GZIEQK0EJGDvWCSl85D6p5deQ;-YFScqIBwBiOvjgg!!)GIWYo-&tZv%x?0 z&s`3$G?0b?y0dtojHX}gBDgVm6_FbF=fy1HRq@ow&bWHeG_V%^tV4VIb_E-Y5D)Lz zY!3X2dBi8pA`dC2W6IOVCL8(c-MaSYE4IGF+K6*88XSd*h%VhMANs5_=WZ=RU+cXY zudN0#f>1$mDGMWd7;21XzKdGSu4}2?fdYYimgqeXp%h^)gGM~oc{uco&CTO&z^GIe>mvG&`)2ZO;QWjl=^ z=$6EA9Z-G`5!FCn%A9enDH1U&?}+sJ`}gh)7w-mZs(J#G3lN?;W47f9S#H z@!RPcF|Fb_MADFkzF_`V^mis$vgP$(o}Tdmd@5R<2T-=B&ws5Pd6))3<>s4(@PB=m zV{q-EkK5kNa-Z>3iCjK0D1%BiTLt!Wnm1<)VHBOBcn&(8?=gi}DR|B}lCWnzH(omu z`#ttkRbu)a)tX_~pV(Ek5Fwy4Hn$vi`Ky7_LnBvZf*o(NacNb_cQ}8u@#EQFXoeI$ z714;4^^t;P?R!AFJKM=6rQn|^RB1>%92b;tmD7+uPv#P~j zl-BT}z7{H#3XIkwdj_>qeDj?OQ5ASjY=($Ke`@>-~iY3FhhukrIcZu#{nYOi?$ zmcg&fv&<*aJTdJTWH|9&0+}hAR4ENtiZ$`d5Q8)!V;@@kbBcEc=|EM) zxqd5~$w{ZXO3~~k#a}qNTiwwZ3KKQOB_|f>aXxzr5dHLgbt-L7K!}xNHlLj1Quz0d z9WpM?ZEOCpp|{5vnjPwy{Sxy&QIV5NZdGST)F-E5>R2_HzcXGD@k;l{-#-hKT_8MR zzI)DZq5XgA3}J71+wT15I>UrTpWwhyeExH(fq0U!^K?WXK}~yqG}lY~^Jun&6a}W? zDkJ}8g_EeW$y$4Z8-cQ4f2Lfp+vFzdeIWq35rwIzn=MEuqNVmg1>55~aYO=_@Phq| zu;AZ=sf23X0ek6)RwpH5yR1RV+#uBqpy|EbTN$bYs&>o{tBfrBcu=zmY4TlfAVUiY#NX5AY}ZG0gl5MtRI&!RMS zbvA>xzskSGthtb!3MYnUh`4#n110n$WE+2~-z5;O<9ox-wKHV2N~S^gK`^%V8pUQAoa|{E;PVa z(^6wtZZIkRxg``fc)DmF!&sOR7TP0z^GnKw{58%IwZA=dH5Bq|AJQ}%YH;rF;9&&Q z#C;l1ZQ@-n&>LVSanRx`*NTE!nfc}8IqGhoR8vf{ zgAwSA{Lc|&!Nw(R2$+u_mJ{WvwjK}u@@^g$KeA~k)j`~x^bUAkyJ)dKeqvj$mV#++ zVzWP=r)%dZevTCew9Qe;qrX_O4-hOp*WCD{645es*++fwdx~eHMm5=Dqq3#e)+}VJ z8d+oAXk66v=)rlMO)sV9F#!26*l3~JJ@+iQK9jIcY)gLGeQd)WKVoJ|NC!Ek;HK}e zu=;>UK_p6PBW|p%I!?72A#r}z=010IvUcY&e_h*NH?KkSSx?&K)^uwa-5An(3e(c0 zvN+bny;CdwSN74x7Vgqm8#TV#sddqWNf10s7x;=#N}tg?-&Lt0VaIs0M*fG&;x^5n zrRxXn89|#r+|tVtA*I{it`i0G9ChM+h`8zV-4%iL&hAabX*Ifia2!!AB!@B&FbSRh!Hq8}{n4T|c&yeR zYowZ9{_1h-Cwkx5uQE}U3W3+KG+U*JU9>ip=rpmqNq^k;?0xjccHR73j4^iqNcmah z*G!SI$FF{8=PO19W#HnB?F^*yl>&Zl{*guGfyk~V)w}Aj>M8I$a5^^W2^EqD{q;%6|mA;p-%KtU#hyLkMAI9wp>J zBX9s0tT_3zj_q`$C@#c2g6)60kG?Jvy?!{XrSE{LIZ?sPsCpDSKNIPoY-n2+9_uqT7;8UfsN3 zdR5MAlbCH+5;85Eb*nLQ>#pa;n=5f44wfSP{THrg@6%1{6nqTKyF%=X3ize%oX$ zM}1&$xHT*BJ^u^)e&tUN-aam6<%mptt@onqF0_XO{uxS%2;bHLmHP9j3^*}JNh%i) zt!(5lQ_M9_vv<-b$~YCfedya}LSgb%&C>$$^L3Wuf=(NqS;3$1+5uZ>q?E^vu9^)Za>3)Nf33&O!WPxkmF@MB}}B( zj9dS^ybS^49@$0GkBskg-6w}n%8uB+Dl7_qZPC%429GrkLv}n|clayn`#tm%F+Le! z6+Kl`8PWwMa(z?PpY{3cAULK?QDd%`zVlDEZtwIAt~MrZRGs7dbKx*OHv?q?viL<9 zY~yr0HO|n$>Fc1_G?Vo#>G~J#C&AJxt8ku>v+rCr1=bqHrv|upL;Lo1^Z8)ZU#)yVIg$zx& zE3J<@ccM#WyYBvyCw-3|9o4n3K_9M3gJOvzP;j$Q^&{!;h!k{Dc{bbj~f$eT$1o^YEIvuv@J6jSbMf{*u+30SC{ItHk zRp6&NqP~GHdRWKHibo1-jpxB`ZetIKxQyyRMaB~731&UT_N)7G+$B4R{ca|$V^_Y~5kzqB3YUp8{-=LzLxGmG+}B%vOW1Ob9%B~ppn>0JW zWH=jX3NMysdhQ1nfTKcVg!$hM?tc4Zpr%IE6EO-ub)oINVyRyUZ-R=PszyGlSmRy?)I)^dpt#g;OqqsfzRAMrCzTmsBg1nu)+*$CG8j0lLjB$2AxPzx@Lu8>6vhwUp5V}YM{Zld;;Aana zoHO{QbfFd)b0>^uxHx%F!?~2qIF(NBq}KplDwQCkRDO%UDj@ z#Y;+4Lth<&)iVSGQHN=IK}bG0V1TwI2`d9f;pJrvFdDip;4`Y1xf;d8k)&xN&NNMP)%2fz7X z^-NG?M=1@QhZ%&dh4Qe_b08VGn5mJ_UQ$wKL@3P^XR4!tv4l&znNZD0c&xe(Ru7JF z!bwwUQf9KozMkqNC%6{OhYB~e_b`VbEXXJ_NncmZ6WEDzM(Jz2c>2l9VWIMVZu0Iv z+Tf@OS;tb_5$Wno(W4^Fv?#`Up56{HEsTzvvAjK60ZK7II>{+$68+pf%uS&_5KT=B z6GtgSUvocC3JyoaK(su}%yhtw$eyM&Gc53qfr-AZp*;JE1Rr-jBSQ@jA8+IA>**oEUq@B#vbxhDiw3NHEsg@c+nhN#M#_H-&;bbsI zb(p+1+|}2Tf(J98u8ZsXD>lScagjCu1pZt_?Rs67osw?=yVD?lQX*mm5imbT?(nAx9bYjPVw1S^6$IHFv%VGcxaH!Y|y&Rl_FA@A;N0M?+k zsfQlQ!-0r^xEZ^;Q>e};A0KabGYbU+XDW(>Kp?SrEJV}GQ^V4mOmYR+)7)T2Ixt_Aa0gWEMCD;lV+@i!OK%o;3*yy0=U-P4@RJw zI2mBDo-URacuya7XRNxmJ5k09{ zlGD<>x?AhnN~#nCWX^e6>*+H#I2>cSmU?%G5yK%S0P4 z1BZKfliX#zUG-%=rLh(uk4ag&s^ie6Fl_^r4${R}TR}|+YHBRwW$pk&I?z15q%>s6 z-VS~=lsT5DP9zZ&yv?0Gjb%J^+%Q;Qlo!m&2W#ep)1_+3`)KL`3;*!u?G2pun5%Brl}BgBi$M z>Li#9(aa0Wo_sB76bWe#esEF4(9~RIeNYBSA2^N%j$pmq+)1Vu`fTqSqb(>3dfM!@ z!83sNuGvxk+PQ~;H4lA zh6Ie7rH3KX%|YH6d}M-=!{f{;3TiYpM@=6CtS%1R2&wC+MF!iBwk6)!z}pz(^(pxR>zpQz)hvKjlc<}PTmeK`aV)#1V2wp3m2?`zNe+Hw>^zLgF0|M_9|DS zQDo%YpzP_@*Oir$G4&$*x{@8#{d}byeEppK+`t`(mOeT}ISUsrH-wvohPnn(%hc0U zUCv(Gl<22tBBKLGA-o-sW>T(bn3}W}QGo_dB`WB6kzF8;9$0%r0!$r&q@k!3f)mjN zq*1nMXmgko#9SSX@N?5qFfy`~vzIdU_0u%RCY%#6)o@@Rci zKMS0Py%7XX!jjEAo%9sEsj^y99xeooql=ugy|I^@pQeMK8&1lDY~+O0A(Gs|nuHj+ z>ay3p0>YcbHrLt2nWzV`bWxYl)pbCV^%V3CJfvh45Y7bl)Eap>LNN+>1rIMX3{211 z(NYSAk)z0Zn)_*>)b(ldNMC(+4#O(2w{}@}`ulUo|GE8x-+yB#SuG2TeE@zP-2~TE zL;BiI_i@wtP*wHcYfcNb%grqKA~H0bECr6<=H(D2a#~hq*w-Pru2@T5IdePCbeA0c zJNojChwl)aqQrZ_-_ab$PV%OrEq72WV|DUAH*o5gt)cNuSVC3v1LZ>2hpA5ke#yx( zQ^hWwmpXe2Hws;HAR>oX>Rmi`9KF1W@UFawZ|m5%-obR=@;CcWYF-{xImY+S{cpFvKr#~ioBc^N$c8i`Yn!X*lN2^EcmnzhB?@+XlCImCd5(}s!WEspsVV0&u!*5pgGa6uUP$#idN zv#6-(l;FUR5SyU21@szg>T8Tq38h)NOJ(I#b5DDQS&nTL&BACd8X=Ltw!*SPp<+Ao z>;|4rwr9kw&BoOf)vPb%dA~X2+AUtna2QzWXJy+|c$fIixx~4&r5SYQJL({8vbwS@ z95FW3*tM>pwYUHdonT@m-r!5*F$UV5ve-xVakl?>KjvsRX7 zYnnueGHw2ObI|%6^SGQ3)4Dg`F|>kY<2M|8Gn&3Uk=57OF!iaBqL_E)s(+1h)A&~S zEfB2-uDl4BtajtKCS6GiSp1Z`eK?SxJ1~_gJWPS^ z4O(tXnR*gqSn&S6p3j#-C>`Tx=lhw{ha%%Q>%{8Kl1cF!d5|`#EXYv?7U$?A)NyyS z+O_U{$LZdI^%5oALRgV|+nYC0!ZS3D_N<3Ta0_y~56Qf?F{bWq9~f9;`gB(MQTzw5 zY@d3$OY(ewf;4U3t!vBoTAsj`(+2TQRsJmRl<_qC_Gc!GlXe?D{lN7-Ee|ye+*!=N z$;ijM`X)NE`ho^7%{6-0@nPs9J7#EI6%4KA*#^l{W&cHb(fd;8hJ&nul;!qxkB^VE za^p0W&$9ac^BOS9XY49{^Vil{H9o^XUW=%F4&=ouMfuH*e1g_28TgMT`B=kd=wBlD z)0hhy}({!7DgIn>Ec?~OHscugjYUk@rGSv4PRbLo5CV&6<)*TU)iV<3yd`R~iRMy}vniswTF z3D4700(;`++#R-T-&3@)+PvXa8!*9|k_=i3ubK&%q0|-?@}-U50Wim<3kED#$ph zeu+=_@?iCa=XI66`n6RYF3N^NP(mX2A5t$k<0tA`99tx8%FSPeaN9J$EAFzLJmNDE zoc{T|>c&#D0e{6pU zm@?WVk<+9BJv{!3?4@xsJxR&OGW?)8gVVA~^L@}*%dyd?I?u0e=kbOf0IRTgyYQtJ z3TflIlDlU^OhH@yTMLzE5T?l(7qG7bhbj5`D17xw$$U9ujj)Xu~ zpHIcwv&0FDrRA=gWC*?M58a3)A&`A0mlnxKmOYJm*Iw^8q6M3{nhex>w<+*5UzK=2&LgOe==1gbPqFVqP8o|@EG@& z)&)$B$#P>`TMx2lUYa$Ly8Iqf9ZmfZkSR3Jh*J+2Uxn>s@b}ZlB5$iaM916~fD)!? zFFXA2a6N(CL|(~}U&wTgM`ngkJ4PvwsI+OGXC~ysm+jhl=1LP zyk_R$N`u{cf#93RNBB4k%RjYTOGiGCbJDJ@lvg$|HmWA<%j9V=IhylOOw^x7vg`F5 zd!q&A&zRHY{Qlr{yJ%|Hb-P!=D&MZ~(2pEhkZ?Z}nY_+}nuLJ5U3y{!GX@?JHG_ z59_nbwy`pf{3z|GHT2IVv*`6txyTSX5x$E!{i=|cPF&2YM4il06~0@pTuf?AYVt`N zhR&@&KA+ZuVB6nvcYS=Ggye~#{eT48)m9M%3StXO233YLDCoX%I?eKt?a2kxU+L>$ zixbAi4&sM)oP@;bDNoRPvPGT*UiE*F(FX6rao2skEu?%MA>(tBU~PbJrxxX; zYHbyIcZ;uA;{--3=O|jaH~wT+KQ^gUEQuEaf*W;`fghWcX3j%%?HmUn@-~~RlQqv6T;0aa*w5MLHdcSE z*Uv3F``)Rx`+n0HenL*=?X&c*uM@d4M-I7) zrPCr!4=#Vtv>oZI@Tm|Hh_}w39Y3voFW$Q0TjHao9uwoOygQDj#(EY>y^?J{|0TDq zyn4X*OGJI#%k1h4ni8QO_nS;(YAbT{d%VO0*A}{_qk>kye7DKavD46|ZutgQXxaDG z_`6v!$K^(Z_|b=hwv?Bd#0x0MZsk?BBY&mDO{T77p=4^2^z*noe#^ z6sD|Axe_>{IRYb4?NWy$^1IUP<;!^|v@g`=pha4qw9JcawGA0QO?8peOdNZEIua(6FxTgf9>9(y4w{THfZVyRsLM1@+TzrBpp=}j+N%(`y$V(^$ldhi2*U-LNqBJZN~{>Bd}qaMN6Z!j ztc%7ke1D~N-%+|`&a&aur`hQA*JyDO_B#4%b0LNRkx=PP>!)!q*lVQz!MTGOp5J+9 zZYLP89M_*1^~J5hWc2@(B)tF6R%^#lUqPDm$-?9%vvE+NPt~N&;$knc*MDHeHbIe^ z88Bg%@*Z)PT{?UkRbj#W*Ox};3Tn!|3;bDx3TFAFx{|HU@Mm^q@H602+d(90U^izB zu7joaxN2i<#z)7dCa}uJf4X=PK-W&r<)v<~w$y}BDf!?Psk>Fej_>cDMO#?712j?s zql|Q?Y^=Hpss>h8d~WleA2U&!%r2Z-UzsVL%&X~N>;3#Hw6A8mucAwWKFBe%eeSkQ z)%hsZb$Y1vNwwc0e-y;9+C2Gf!dW_I@t(L<55Ba|Mfk^y?H+?Ku5@Nw$gaE+UcZ|`6TfT|cx_Rq$3Y5Kxn^W*x$%)mfy z`GhF2GkK+yTTq_vo$h^SM!f307&`kc>sYt&Z(88VPF_Z6`^f@MmhehGSDmV*48d0*7CPzQ+s!uj33<=-_uZ4UV-i%TuUHFt zL4AEB;Mfl4J2jf$y>k|(U1z_+etTl;funSu9b*sxK7zi!-OEPr9$=%+61+zNRR%w) zW_@{5f^JDCJ)A@ZeZ8Z@I5t1SMPFwHZFI?%*s3joNyewFeifN6YBQv`XGWD_nx~or z7iIl_d=Bk%1p_JGx&O2f53{!fKS`q&pB=-bdV`R%jH&>r(yGEc=PB(X;JPpOLCZ0%I0I^%fPo}-+#7txaj686SWHH3@LRinB z=-$p8D;pz1=4iE5DIqrwlMtD-Jkt}IHE3J4I5FN;;#j{2$_TZG9fKSf4mFXi4jFR0 zRTVP+tSNNQ;fdhcBg(YynvIp33VEN!Pp)0v6@>F0bGeK6xJJyN$;-sPGe{Jw?EFN2 z(D>81NS=j{-D}Pb_bkBDxpepbx!>FpFPm4oVY|n#kh=js{fKrsC#bDuC#SjU(mNxp z@_Vto${`Mq96Dt<7ITD$$@c^I_EzvY{BqX2SSly0_%OzZtKBMPqO6Pe*uwHb89HWD zM)KD#TmQy>Py!2=ws42MFDLYs3t^A>w$8&}Pkihz!CQSh%8fAeL{N+_$?aXqvRlinuon{(qtq@3t=0!A49p7}t+8BH<{o_cG7pi| zyi!BhT^um~SeQzsfDs-X%bu;VvKU)=G##`)8Z>oFwuz*1zi9mQ(g)e*4;yM()6&f8 zXQ?91O?%n7a#j>jcbKLrr3O$?D7Y<5iILh#Hw_Zx%Ld`K)f`sSGYGroXr)w|L#%dH zMus$ttF>J=>zFDRa(-rFI8Th8H%*VfkriuRWVG;Oak8r!&@%6$_b?k88lqSiL)-6? z6>q(1$m+5+!ng0yjudj2tp4$+;?PuIMJZ0lr;i%vetz}C1KGZo_~nJk3h8+PN(vXV zEoJ_sI6W^ivm<-nNq@7CxfP?=#C(sCNDxPb_jJKAjS%`VN`wHUfL-oQmJ(i5#T8~M z=NPr~2P~i)mfa6a43cyvbX#W(uq(roLF0sZ5FQ)7HqdsHmU1eNWwj8Scd71_nd{|h zgdzdkMvM)tnHPLiBXC^7z4eJeD8{cH{&adc&d&RlDZ~k-u@jSH8LRqCaq%v(zUMqB zCWj|nX1~76l{K_lS)5LaIIs6EWl!8igTz6V`zfOgfX#dIX>V%2M-YW-HsMTj&|M#; zxNL59RM1-CBA-Bxb`y|^skV%yIbd?F$3q;?v~-0j2-u~p-#xlkQ+OD|`H^?`!h6v_ zmR|B#57Msg%5T-<>O?dL;IlT|j$D<9=5i{2_k~TsRJgyFzk*D0fBEc93NCAXpaWD0 z3@x?%5lJ`0tEaW<@k-uP_XXcPg@2;WMhl3}-HE#Ndd*z)`3xYwR`z!ACU#_DDv~Ev z0+zc$41NxwIAbNB9$@$3O!>l#4qet~Q{3>E5>?l#7!b9`MkTYp)`xZ z|1v*!&{pHF+yPw;ue)d?l-xNTsQ%NDl(Y2oS9QIR8-x7``!kO3GbR?I$tIhS0j7_c zjE;sfkoXis4~^IBYM2(SJ_{Lp22Cs3`D80=FUnhgkCigL+4+$tUJTh$!WH{wFD8iN zuKTI%c5VE5ubR`oz{CmZ27@XsNLnD&1ZeTH}SFZYcwK~UrSks>&L=kNBIb^8#y}U?9-4$ zw?sGmeqG3+GU7lr;gb>G@|dn_puknTfDZxryBls6tcQK??zp;QeOjQaL>-0CGIqx4 zbYNc2?(^k)3~`pYby@Mu0kR5WCNwPP2WRGXR++wB z=L1)(hk7X>7Ezgp-GAJ_cTV4KXLtuWtj6Ygz_xO<`=e|{sGN|_m(O|S6PaHS_UIJj z1jHvmEV|=bpWK}EFiD3`EN9}p7COA;1~S~+(g@Wt$(2}leR1~;!ClzP{=t;tIv>$2jt z0ZbRIl*iq+uaWbEi5K8IPC8%DjDB{`aNp*wVcM7X#4)nM2333tA2r`O!kFVodX(21 zoOofuJG$Qmt8_7=8V@-uhU9x9o!{2I%Z;v!e^sL$AuxRJopYAWrurX6w@sO(WArE^ zr4N?Tra^nn_99J=hmS$&qb|~S8n48t127S$mwH#p8r1Nq8MDXJjz4?y$3YX^60xV~ zUDZSLx$Q-!A*YEG+_3^(Iq#_Ph}+ZGj}~*X1XOLideL8&JNy4Y^J%ef!+YT<5fo2; zkIyk8efOGu_K2x;t-5Kt9|A;{QCs=P7i}ap%4Xk-^_>(C$Sp;?_;10L4E9g;M6g|?VarS5Pm=G$s-5!hh37DEzHU} z!_uaCAe>}d6uK}WbF?eB)~ibRgPnFU*DCQ4mvaZU|CBDTyyoI%@SAk7eVLhk{{R)B ze5UxFQU*DEvaV}GE(5JWQ3RFLWCE>_lVv+l^4`kdv319ppGxfoI4H>CkW@;+)6>u0 zJ|2g9q8+E3m08wpw*{&W+7i<}T2ilcEN<%rxbzdX%f_`?bz^lWab#h(1l8YTh0TeW z(_+uXjjO-~Lf9)Ze^Xpp;l5nVH>h8a(wO`c$s^+;d#qo1E zzs95hbfo%+2hVKzT`jS1>&FX}vMt9e{;uNg0TJN&jPw29d7mRd4xYRGR^o3m^M5w) z%A;LOo+IboCOdNqfei5p5cX3qu54k7C+I{SfmAW80hK5K!8#el%jL`Cd&~i$nEmL{ zaUSINeol!8liT@crVonEpvTYV&k_02h7)J*%LUf1lHWxfoM;*PvloCWVF_t-U>QX{ z+R2=$m{G9;72U2e08p{)!U}9_768QCT(Co=T+UF$Vu zLVx8awoDhwBV2Mw*2NsuOdK<^Q-=qmErj@I#P|M37yWVzro!gjRsV$o9s#+xV2L;a zwQ0_7#e&?Fq|_C{BTU$J@Z6cqhl+HkTx09XAg$;B#YAdvodiAQykCK!RgLd=2V6%c zs?T*$wl4CpQnp=9AmQBlwVnGfF;7)`(49)&)cFg(eqVv2=}oQnUXP7Y(gu>>=&CBVQ5b-cZE!ba+FoB>o2Xmq!{rUHQ2jemV(FZ~IGt0$aA z-1*anHys2(!2Om@FgqmgE>DDMAireSMPP z-jN7ESvLqo%GYeArHu4sEL&BLIHKGG^!_0A+flnDsKv*7jBV6Esn&ymTa)iiKw7g@ z@r*3wH!qPSujpQQf;@iebEvS&vA5|tWbr-y?^maf6%1C}zY1YS6fFyu<`fjPR^_9E z=BnKHHRP1`V}VVP<1eMK?au_%R3zx_9V2cU)Sb>7LLhy4zO%^e(#=~h^2{@>ZL^^? zLP{L!!oDc!@yxnsS%+UOl?n2{agHu2CRPZf$p`Ci@Ji&bH+%vq~>p8ge)$X%0)fd5(_Bqb~CwuP@-2^PBLrQsXhjkAlE0WcOIi4mWt#)?o@C zb1yki9)!JZX&;+4;!T+W4>6}GTVB?!@bCI7-Tq~&ty$)6=(VRUl#RD1qPl^WkBd@Xyl(}U zvJ+HhEk&RARK2snh?_8%iwI?R03;wA?yqbRZ_|A@qW@Y)?AQoWs$6b+BfC|RQ{b$z zo+A^InHsdQF7cvfC`_zUzCL^0E&a+)T%Vd#Z9qoTao1B`@9Os9RKGgQnaLf0O2QV=E$S%=jd3^jh!(z1BrT6vI zrkRQFTh0AS^^9(UOiTZIu47;inC0)^f>+qwUZvlh9yV#EE}XvtwSHjGjyC?(Heq-t zu&H|dyfau>qtlM;J=^+x00jrv6r7d3@mIn|e9XJ;$i!tuJh7at1pPx}9IFV4vXkal zKSV2Kcyrdif8O>scm*^YST@`f&&kXb&893|5;D;4DWjwV?$Wm@Chr>E>E7!)|6Q;C zJ@wgy1)6ZO;3d_7TAyO~Ug!u1v`bX~7`hlCqrp7cJA7Eou(s-bD`2$QT}mJ<#BNa* zylw$`tOpQYcpwNTxAGr1`71SjZndo}mH+9{TUkk`Q}GP?$Bmn(&HxmUE%Rjp^K791 zS@4QNJ#2}d`~jfYB4N%Spf^bEx%Pu&KGwbNDpRwOu_dqG(wL|{%HAeYRe+~bPe~tL z!|hHY$Zy*tGzK%O-aiy=aR6-H+<(Q=Pjuszv7~i~A<{>CbL)`zOckqq(*|g4x%fQf z!9AsMZ@;=QGg4l`7&id`fC50x^Ut1Fp7x&`X(VK%gMKQ1J-fG>bf-?RL1g{YOL~DO z+gML|NA;5wI{;5U^ky&x^d{8`xL7hxvFS_K!iz?2MIJpEnW(ZWbTLqAZs@8mr%sO0 zrrF%CSdfbB=V*)l{4+Vb|6%aiC9T7ZxZs7a?_%(EVSExVR7Vpj!H_0w8KPE#Xx`y{ zzz>-0W{pZw3Ge_^_;m#xqm@J@pIjgqoNLWr9OncZO2_A+40wem2)&_|(E-uS#G;vt zvrmWksU$nmuAyFHOpx z&2w`_c|fo*2Z*ze3np$^^zE+5E#MS103?(Dbc$%8=ME;Kj`s4}&P8_1#-J@)wzkQ-S3RO)VmW5%hVtH1-MS(lU6kysWf}&D z)&zt99Wj<4SRDe$-!xIy<-;HT6B+5&mqEr`yU0CnSB7|)G{PxL0C5>3P*{xZ$Ta4- z#JLC>sfzlm{1ce+U&=p6m$?AU=Q5$f!4n_-~23c^DWoBZ8*X7;1tQ z&L1x`;?s>SC4E+J6N}sh)6~)M1Z=MBmTkLlP%lOyrW=zMht|lKft~uBRk}`X1loUn z60qIOu)r=ccm;Xcj;kvMG^TvoBcyN<^vLKwe`6u;6W#0He;c^Eo0FvoQw}^N=XSgC zfo%HG7!Qb__m6L%OD@(1oA0T6hpq+dv$k&K)aHLgi0RtULADzxpaKG13i9 zaf#SR?3HdKS<(5hncAkfT;A4O;ggr3AQ(!Wq9}*X&(oa_g6z`p@_hy0fa(U?WEglR z#wgm(`s#{l7)5TkKyu2;%p?=<_Z7NE;Xf7B<&^b2f$xWw*h06%dr9xCAJct_)7r($o?NIg zd8{pw%GUa*57TWEOz%OIXvO{upKBrH`1o|{yxzGv?&Y6ggry==6;I4ya9AM zMw(%gKn=%1zng%xsN^`S^83L~{730gu9KjL0}6I9(EpcUYgl(r6;!>e76l@|tKJ(A zKxOTVmxO#PPibDMPuMQ@jAMw)_^?O{{;P`Ay;iX{Jv!>@MwU4#z53YQ3Oh zd2~j7C=yOep^HYWUjzEE3%f5X;app~QOejZ&7Gjey>k4(pk;iD-U)hhl;bg$DNv^| zb^*l;062m?O<6S#`teGbK^{p@B;0Vt&JF5E6irr6(~Xc+ZGRabhNsS(ozn3qDZThoEh~k{NWj?~ zxVfpTbrpS}HXu-WS5>KNvfmrdA5aGAszHiMUq5Y9To53bbcJAO`+A}G4(6^tJ%roF zynL*&GbIyPBegmA>C)3v^yWO*Km6NzaS%BjYWm>%>RfZ_XiAXEFx>Dm&VAiuCv(o#Vodq$(XJLDgVX@f<`X5%1QKo`Xkuh*KIV^i zfE}~&tXY~lJ0p<#LAyg@IGsGK*Vb4IVgf(aoiFb-){@BDTe=%?A6a*{-VNnDvd{Qt zBIxSZlz34rr-}k%op8PSjF$2|oAXy*n{Pws*;Wa}xPewhBD?9A4bS;Bu2j<&1?Ai> z?iVpE0{iuLiT;ts1bpigILMs#3DS-s#efm|rt-LFb8P@}R*3)4l?39{jxDknRMV`y%5l-o(HZim*xMc z`{5uS>>tHvAoF|SoKXRH7|JTtKXnAOVkocw_)>!H5XFK0yw*rhvUB27p{q$XEN-xR zu<`Nyo)-!qTeB!lATP{Hvb~iCLeujWSrX{7e^uyBsLg@thDi*~UI$Bq&_R{=o$)Um z3twt*h{c+zZ@SXLNxwG|1$4ZidnQxx7}o`kED$gJUS|wTC~ZHh@`~^4bu#bn4XT9Q zi*Io(kf*4N-D?9^8ndsAOBhtCNw%NK0rdwVJKz}DL6rFo3OZP1Fy*#|n(>i?DyHjB zhZ9RhPiLvX1OdIK4T2}I4+PKTp^^Tg$g0yVxfX?|KfH1|k1i$jF%*~Up6^kq4fxu4 z3dWgQdKN}~_W&$oFZSBQ8Ie-#nx$B2&<_%pMQ0=@ySIy%cGk`e)YSOD!ZV=2`CZ0$ zVxv4CX`$^8fJt^Z3)~Xap-xIsZIEI;ffr2_+f~u1_d|0Q%zqWyo+;J{l5oQ5n8e`c zFEz*$(Xwiru8eI3L#t07R8ftzpV4xh25i=N@HpM0{L_61?jFFY(h^$l&G!Vam}7XZ z|Jm{NtNrECyDWaR`}M@k%uF{f;|3ET3-`T;@$vEHi&z1s5byY5yNEci|(Ve^}top?=lOIfM}$Q0C_ek+MUkTOd& zEynkDvbTY76uH%=2-|dD+R+1`IM3r*CI^F8y3q!n2XFBm2`lVB1L4^58o^%c6Ia;* zVn3bn|EXiYl<#HK7rTT#x6W>~z80%}XYYlh-aqr?DR!RR?MP&A(V)kHQ`p(M~ZOvk?}H~5gn!+7<21M_C7KQ&bca>wg|F^YQyuz z*Y{U0wr*wBuD(rDyUcgQ?I3$&AOWw`au;t0Tbx2j89%yVXPN;?_(K%q&&BKry!{8p z@ZO{Rrhw;)C+Of2gx|~bMn2dHZ;6Q@KKg3l|9?MYBM5-Li$E-N^RXFNZzjY2zlDN! zObu8^^5n0&lR&4I<9thMXID>vHTM9_YCg!M!GKFHr=1b{y=`v=Z(Q&^;4S*N<>Ctc9dSzs0q<9^u9HE#BN>b3LI;Bcqi^@ zE(h;_IzM+%z<(g!NEiqR=1w9qfVpq;7XkG10gFRq80jM?D_*UN(5DFcdJ@>16oA8n zE@o_$H35=)d>!MN$qBZKR1Ds@DEAuQH+iVB42j0Od%nvC#PPw9f0P0D*T8b>2xu<@ zy~xApCcuGL0K_jkKLqxfSC*xOY4lrn@W#YgJ&W=JFxZfM2hhJRkqWrrKS8C7K-AOA z)xUPeA&!8E(4K#7i<2B{U{ib@$Z;)&>-DKZ0l@6-|9ARo{N#_ljP1BBo^Nx!6#!q| z``rF2#G_lP=r{_EwgfrY0~n&kr}0LG-sLNXaswIiaCXY6J94%NZb!hw<_3q^S0Zi1 z`QtvQ10IOHzCrm1mW0oODC|5q6zvb1F#r|BWmSwto!MN?vGSYB#e)LN)BYPWvU?kg zwp$joHsOHiVUVaGEh+mH(&qQC4N?2!dD{%z7(m%}(S4Vzf7XP*=!oC=cua>RoNe&> zY$?a3h#~Vz@HTSjnA;gcP*^dZMLF!6LfPf-W_C2FxV0QjkaaawJ8kUd@cP^5SNPgs zPOXLeoN*uG{;;mJqy4k4>WCUtF|W8`#e7oIc1f{bfqUAN-A2^35ZLWaJr&CT#@8}|4}4V!*rJ5)RDn9n{m^?f?!T(Ezq zRHOA%`ry9#2E%_RR_fS>E1gYa)UB$70Lzd6q+zlS@LLB5esb4X=ln}L@yhra2qIr4 zRIUJqIU=rAaUMXgo7Q=MrRJ5XBhp~<`T!9?JU}>sYhDjvjvd> z#)1D^V)@^$-NuUF^w4$%WRZI9Tp$7EvTTX3BCxMc6`luyd-5NiGo53*!S?4(@KCHNN@H+}z>IaIBA%cX++Sx)pnQai|LJz^0|0t*1dUa0WniKFDDwo1f15 zKwsvYD2)TY@;~PDeW&I@22Pvun``pM4i68PP(}^2o;}-91=Nev^>zMc|4=Ug&jeC+ z&+f8tqoW0bwo#m2zxKwPNtOfE0Xg7hnmfB2Yfn)qFX~phw*I3AKD*400ok9P4_^7b zP2vH3$~Q{@T*&k<{y2qIz{c3yc#e3uCVFbW3HSo2(TKlMqj8B(X%X`iMuMs)VT1j+ z$zwLATaWKzHz48wArVn03LB5jKv6(Z;s~a+(O)?Qv;zHX;2rz;7{B`CyU5lh`k*Q1 z@ni0eQ+L-WfT*uK<(gr8q6)B%p!uMLuk{oLjE>C2k_O769#`ku*is`!u-|~SW3~u@@oY_k-tep+!Me*D%4hizKZg%T)@+Dv9X^( zGpl~kmy*LU^6RGabNX!q>K^gWSHSCI6*j<;HQKlHnn|@!bG>y0GZAN2MuF}YuF+(= zKK%`hHt%fRbD=!(P%rpiKr2VB#2F0lqOhBkslS>*34puXHP-?=yesa5wS9$?C@20* zdYbhKPw7u}OUr{b+bT!DmcFV$E!?eZf3uckzi4f_9OLXXm-Bvo=p3&F$?koXJ@*&VB0pd7t6%3$?RCJ!LY+)SANw3U0RVwE`n0u7+m}C=@4u-^!r;0J_H`uirjo~R z;!}rE3|bE8Q3CG}HZJt=99ES3 zKe^IYK|uA>pJ)LM)_E~#Th&tRR9XA#`Hmq(`o0dS{WsF6Uh+QM=&TFpf>%JzSr$tH zBoP6qoLqfa5UK3dRH|+WMxw47Sh58W!Q1#}3=aHz#$e0bZzC>Pb2{v0?9$nPiTy?? zfGbi}w&%0iT8$!g!U<%)2(NwklDWE5g}WvCYmWWL=^r}7n=ojr5F=t#!Y79A&O~LY z@BGHs&6@huMq@GY`%mlNa9pFy0KO3mJm~bFJ!o(gT^k^J+Xg7>;nG5_-y6)i%K>&k#A-|J&w)su{m%nA&f5S65#7qBe(3NRLLiJ zw_gFEv9ESN?y_2>zxuJRK*gl-otzKwu6FXWfhZbIt#& z^8h@7>k0seW(wPRjue6T{ZxYQwN4Ehe6gATC;tbK=?upj=p87#Tn$Fi`4qtqHnSTq z<=Y*Hq8|wI&ouJ>#{j#}0jR#vo3HZ!*2;0_G^j8fGR5DA{f6i4vP2v}Z8@Ibbq2dX qJrHo>(FHFMQ32LCVh*k0ZM literal 0 HcmV?d00001 diff --git a/bip-vaults.mediawiki b/bip-vaults.mediawiki new file mode 100644 index 0000000000..f675737a92 --- /dev/null +++ b/bip-vaults.mediawiki @@ -0,0 +1,750 @@ +
+  BIP: xxxx
+  Layer: Consensus (soft fork)
+  Title: OP_VAULT
+  Author: James O'Beirne 
+  Comments-URI: https://github.com/bitcoin/bips/wiki/Comments:BIP-xxxx
+  Status: Draft
+  Type: Standards Track
+  Created: 2020-02-03
+  License: BSD-3-Clause
+  Post-History: 2023-01-09: https://lists.linuxfoundation.org/pipermail/bitcoin-dev/2023-January/021318.html [bitcoin-dev] OP_VAULT announcment
+
+ + +== Introduction == + +This BIP proposes new tapscript opcodes, OP_VAULT and +OP_UNVAULT, that add consensus support for a specialized covenant. +These opcodes allow users to enforce a delay period before designated coins may +be spent to an arbitrary destination, with the exception of a prespecified +"recovery" path. At any time prior to final withdrawal, the coins can be spent to +the prespecified path. + + +=== Motivation === + +The hazard of custodying Bitcoin is well known. Users of Bitcoin must go to +significant effort to secure their private keys, and hope that once provisioned +their custody system does not yield to any number of evolving and +persistent threats. Users have little means to intervene once compromise is +detected. This proposal introduces a mechanism that significantly +mitigates the worst-case outcome of key compromise: coin loss. + +Introducing a way to intervene during unexpected spends allows users to +incorporate highly secure key storage methods or unusual fallback strategies +that are only exercised in the worst case, and which may otherwise be +operationally prohibitive. The goal of this proposal is to make this strategy +usable for custodians of any size with minimal complication. + +==== Example uses ==== + +An individual custodying Bitcoin uses the common "single signature and +passphrase" configuration with a hardware wallet. They are concerned about the +risk associated with relying on a single manufacturer for key management as +well as physical access to the hardware, so they generate a new key that is +highly secure, but would be impractical for daily use. For example the key +could be generated in some analog fashion, or on an old computer (with added +entropy) that is then destroyed, with the private key replicated only in paper +form. Or the key could be a 2-of-3 multisig using devices from different +manufacturers. Perhaps the key is geographically distributed. + +This individual can use OP_VAULT to make use of the highly secure +key as the unlikely recovery path, while using their existing signing procedure +as the withdrawal trigger key, with a configured spend delay of 1 day. They can +run software on their mobile device that monitors the blockchain for spends of +the vault outpoints. + +If the vaulted coins move in an unexpected way, the user can immediately sweep +them to the highly secure recovery path, but spending the coins on a daily +basis works in the same way it did prior to vaulting - aside from the spend +delay. + +The recovery key could be any number of things: a 2-of-3 multisig with keys +that live on different devices, a 3-of-5 with socially distributed keys, a +Taproot construction that incorporates one of these methods along with a +time-delayed fallback to an "easier" recovery method, in case the highly secure +key winds up being ''too'' highly secure. + +Institutional custodians of Bitcoin would likely use vaults in similar fashion. + +===== Avoiding the hostage situation ===== + +This proposal uniquely provides a solution to the "hostage situation;" by +setting the spend delay to, say, a week, and using as the recovery path a +script that enforces a longer relative timelock, the owner of the vault can +prove that he is unable to access its value immediately. To the author's +knowledge, this is the only way to configure this defense without rolling +timelocked coins for perpetuity or relying on a trusted third party. + +== Goals == + +[[File:bip-VAULT/vaults-Basic.png|frame|center]] + +Vaults in Bitcoin have been discussed formally since 2016 +([http://fc16.ifca.ai/bitcoin/papers/MES16.pdf MES16]) or earlier. The value of +having a configurable delay period with recovery capability in light of an +unexpected spend has been widely recognized. + +The only way to implement vaults given the existing consensus rules, aside from +[https://github.com/revault emulating vaults with large multisig +configurations], is to use presigned transactions created with a one-time-use +key. This approach was first demonstrated +[https://lists.linuxfoundation.org/pipermail/bitcoin-dev/2020-April/017755.html +in 2020]. + +Unfortunately, this approach has a number of practical shortcomings: +* generating and securely delete ephemeral keys, which are used to emulate the vault covenant, is required, +* amounts and withdrawal patterns must be precommitted to, +* there is a necessity to precommit to an address that the funds must pass through on their way to the final withdrawal target, which is likely only known at unvault time, +* the particular fee management technique or wallet must be decided upon vault creation, +* coin loss follows if a vault address is reused, +* the transaction data that represents the "bearer asset" of the vault must be stored for perpetuity else value is lost, and +* the vault creation ceremony must be performed each time a new balance is to be deposited. + +The deployment of a "precomputed" covenant mechanism like +[https://github.com/bitcoin/bips/blob/master/bip-0119.mediawiki OP_CHECKTEMPLATEVERIFY] or +[https://github.com/bitcoin/bips/blob/master/bip-0118.mediawiki SIGHASH_ANYPREVOUT] +would both remove the necessity to use an ephemeral key, since the +covenant is enforced on-chain, and lessen the burden of sensitive data storage, +since the necessary transactions can be generated from a set of compact +parameters. This approach was demonstrated [https://github.com/jamesob/simple-ctv-vault in +2022]. + +However, the limitations of precomputation still apply: amounts, +destinations, and fee management are all fixed. Funds must flow through a fixed +intermediary to their final destination. Batch operations, which may be vital +for successful recovery during fee spikes or short spend delay, are not possible. + +[[File:bip-VAULT/withdrawal-comparison.drawio.png|frame|center]] + +Having a "general" covenant mechanism that can encode arbitrary transactional +state machines would allow us to solve these issues, but at the cost of complex +and large scripts that would probably be duplicated many times over in the +blockchain. The particular design and deployment timeline of such a general +framework is also uncertain. There are no sample vault implementations using +these means known to the author. + +This proposal intends to address the problems outlined above by +providing a delay period/recovery path use with minimal transactional and +operational overhead using a specialized covenant. + +The design goals of the proposal are: + +* '''efficient reuse of an existing vault configuration.''''''Why does this support address reuse?''' The proposal doesn't rely on or encourage address reuse, but certain uses are unsafe if address reuse cannot be handled - for example, if a custodian gives its users a vault address to deposit to, it cannot enforce that those users make a single deposit for each address. A single vault configuration, whether the same literal scriptPubKey or not, should be able to “receive” multiple deposits. + +* '''batched operations''' for recovery and withdrawal to allow managing multiple vault coins efficiently. + +* '''unbounded partial withdrawals''', which allows users to withdrawal partial vault balances without having to perform the setup ceremony for a new vault. + +* '''dynamic unvault targets''', which allow the proposed withdrawal target for a vault to be specified at withdrawal time rather than when the vault is first created. This would remove the need for a prespecified, intermediate wallet that only exists to route unvaulted funds to their desired destination. + +* '''dynamic fee management''' that, like dynamic targets, defers the specification of fee rates and source to unvault time rather than vault creation time. + +These goals are accompanied by basic safety considerations (e.g. not being +vulnerable to pinning) and a desire for concision, both in terms of the number +of outputs created as well as script sizes. + +This proposal is designed to be compatible with any future sighash modes (e.g. SIGHASH_GROUP) or fee management strategies (e.g. [https://lists.linuxfoundation.org/pipermail/bitcoin-dev/2020-September/018168.html transaction sponsors]) that may be introduced. Use of these opcodes will benefit from, but do not strictly rely on, future transaction versions (e.g. [https://lists.linuxfoundation.org/pipermail/bitcoin-dev/2022-September/020937.html v3]) and [https://github.com/instagibbs/bips/blob/ephemeral_anchor/bip-ephemeralanchors.mediawik ephemeral anchors]. + +== Design == + +=== State machine === + +[[File:bip-VAULT/opvault-flow.drawio.png|frame|center]] + +The vault has a number of stages, some of them optional: + +* '''vault transaction''': encumbers some coins with an OP_VAULT script invocation. + +* '''trigger transaction''': spends one or more OP_VAULT outputs into one compatible OP_UNVAULT output, which broadcasts the intent to withdrawal to some specific set of outputs. This transaction may have an additional output which allocates some of the vault balance into a partial revault, which simply encumbers the revaulted portion of the value into the same scriptPubKey of the originating OP_VAULT output(s). + +* '''withdrawal transaction''': spends OP_UNVAULT inputs into a compatible set of final withdrawal outputs per the target hash. The only authorization for this spend is the content hash of the withdrawal outputs. + +* '''recovery transaction''': spends one or more OP_VAULT or OP_UNVAULT inputs, which can be done at any time prior to withdrawal confirmation, to the prespecified recovery path. This transaction can optionally require a witness satisfying a specified ''recovery authorization'' script, an optional scriptPubKey gating the initiation of recovery. The use of recovery authorization has certain trade-offs discussed later. + + +=== Parameters === + + + +The recovery parameters dictate both where funds can be swept to during a +recovery, and what kind of authorization (if any) is needed to initiate a +recovery. It is specified in the form + + +[] + + +The first component commits to the destination that vault funds can be swept to +at any point prior to the finalization of a withdrawal. + +The recovery scriptPubKey would usually correspond to a spending script that is +inconvenient to exercise but highly secure. + +The second component, the recovery authorization scriptPubKey, is optional. It +is a raw scriptPubKey that, if specified, must be satisfied to allow the input +to be recovered. The benefit of using this parameter will be discussed later. +If this component is not given, the de facto "authorization" is the reveal of +the preimage. + +Vaults which share the same recovery path can always be swept in batch operations, +which is an important practical aspect of managing large numbers of vaults. + + + +The spend delay dictates the duration of blocks or time which must +elapse for the trigger OP_UNVAULT output to be claimable into the +withdrawal target outputs. Encoded as the least significant 23 bits of a +[https://github.com/bitcoin/bips/blob/master/bip-0068.mediawiki BIP-0068] style +relative locktime. + +'''Trigger key''' + +The trigger key, committed to with , is used to +authorize the ''trigger transaction'' - an on-chain declaration to attempt a +withdrawal to a certain set of target outputs. + +This functions as the "normal" spending key, but if an attacker obtains access +to this key, the outcome is not catastrophic: any withdrawal attempt can be +interrupted (within the spend delay) and swept to the recovery path. + +The trigger key can be an arbitrary scriptPubKey so long as it represents a +valid witness program. OP_VAULT outputs which have the same +recovery params and spend delay can be spent into the same +OP_UNVAULT output for a batched withdrawal process. + + + +An arbitrary set of target withdrawal outputs that is specified as a parameter to OP_UNVAULT as a 32 byte tagged hash. The preimage is a list of destination output scriptPubKeys and amounts. If the trigger remains uncontested -- if it isn't swept to recovery before the spend delay elapses -- the vaulted funds may be spent into a compatible set of target outputs. + + +=== Fee management === + +A primary consideration of this proposal is how fee management is handled. +Providing dynamic fee management is critical to the operation of a vault, since + +* precalculated fees are prone to making transactions unconfirmable by high fee environments, and +* a fee wallet that is prespecified might be compromised or lost before use. + +But dynamic fee management can introduce +[https://bitcoinops.org/en/topics/transaction-pinning/ pinning vectors]. Care +has been taken to avoid unnecessarily introducing these vectors when using the new +content-based spending policies that this proposal introduces. + +Originally, this proposal had a hard dependency on reformed transaction +nVersion=3 policies, including ephemeral anchors, but it has since been revised +to simply benefit from these changes in policy as well as other potential fee +management mechanisms. + + +== Specification == + +The tapscript opcodes OP_SUCCESS187 (0xbb) and +OP_SUCCESS188 (0xbc) are claimed to implement the +OP_VAULT and OP_UNVAULT rules, respectively. + +=== OP_VAULT evaluation === + +==== Witness program ==== + +When evaluating OP_VAULT (OP_SUCCESS187, +0xbb), the witness program is pushed onto the stack for the +following result (stack shown top to bottom): + + +OP_VAULT (*) being evaluated + + + + + +where + +* is a 32 byte tagged hash of the scriptPubKey used to authorize the spend of this output into an OP_UNVAULT trigger output +** tagged_hash("VaultTriggerSPK", spk), per BIP-0340. +** If this value is not 32 bytes, script execution when spending this output MUST fail and terminate immediately. +** Because this parameter's scriptPubKey is committed to using a hash, witness version upgradeability for the trigger key is preserved. + +* is a CScriptNum-encoded number (up to 4 bytes) +** It is interpreted as the least significant 23 bits of a [https://github.com/bitcoin/bips/blob/master/bip-0068.mediawiki BIP-0068] relative timelock. +** If this value does not decode to a valid CScriptNum, script execution when spending this output MUST fail and terminate immediately. + +* is a variable length data push, consisting of two components: +*# a 32 byte tagged hash, the ''recovery sPK hash'', committing to the scriptPubKey which coins may be recovered to +*#* tagged_hash("VaultRecoverySPK", spk) from the [https://github.com/bitcoin/bips/blob/master/bip-0340/reference.py BIP-0340 reference code]. +*# 0 or more bytes that optionally specify a scriptPubKey that needs to be satisfied to authorize the recovery transaction. +*#* This optional parameter changes the allowable structure of recovery transactions. +** If is less than 32 bytes, script execution when spending this output MUST fail and terminate immediately. +** Because the recovery scriptPubKey is committed to with a hash, witness version upgradeability is preserved. + +==== Check for recovery ==== + +After the witness program is parsed, it must be determined whether this input +is being spent towards a recovery. If an output in the spending transaction is +found whose scriptPubKey hashes to the recovery sPK hash (the +first component of ), the interpreter will +evaluate for recovery. Otherwise, the interpreter will evaluate assuming a withdrawal +is being triggered. + +In pseudocode: + + +is_recovery = False +recovery_out: Optional[CTxOut] = None + +for out in spending_tx.vout: + if tagged_hash("VaultRecoverySPK", out.scriptPubKey) == recovery_sPK_hash: + is_recovery = True + recovery_out = out + +if is_recovery: + eval_for_recovery() +else: + eval_for_withdrawal_trigger() + + +==== OP_VAULT evaluation for recovery spend ==== + +* If the recovery output does not have an nValue greater than this input's amount, the script MUST fail and terminate immediately. +* (Deferred) if the recovery output does not have an nValue equal to the sum of all OP_VAULT/OP_UNVAULT inputs with a corresponding recovery sPK hash, the transaction validation MUST fail. +** Note that in the draft implementation, this is facilitated by a "deferred check" which is queued by the script interpreter, but executed after the script interpreter has finished, in other validation code.'''Why does this proposal require a "deferred checks" framework for correct script evaluation?''' The deferred checks framework is an augmentation to execution of the Bitcoin script interpreter. Currently, the validity of each input is checked in an order-indepdendent manner across all inputs in a transaction. Because this proposal allows batching the spend of multiple vault inputs into a single recovery or withdrawal output, we need a mechanism to ensure that all expected values per output can be summed and then checked. This necessitates the introduction of an "aggregating" set of checks which can only be executed after each input's script is evaluated. Note that similar functionality would be required for batch input validation or cross-input signature aggregation. +* The script must FAIL (by policy, not consensus) and terminate immediately if neither'''Why are recovery transactions required to be replaceable?''' In the case of unauthorized recoveries, an attacker may attempt to pin recovery transactions by broadcasting a "rebundled" version with a low fee rate. Vault owners must be able to overcome this with replacement. In the case of authorized recovery, if an attacker steals the recovery authorization key, the attacker may try to pin the recovery transaction during theft. Requiring replaceability ensures that the owner can always raise the fee rate of the recovery transaction, even if they are RBF rule #3 griefed in the process. +*# the input is marked as opt-in replaceable by having an nSequence number less than 0xffffffff - 1, per [https://github.com/bitcoin/bips/blob/master/bip-0125.mediawiki BIP-0125], nor +*# the version of the recovery transaction has an nVersion equal to 3. + +The stack may now have 0 or more elements. Any items on the stack will be used to verify the recovery authorization witness program, if any. + +* If the ''recovery authorization sPK'' is not null: +** If VerifyWitnessProgram(, , ...) fails, the script MUST fail and terminate immediately. +** (This validates that the recovery has been authorized.) +* else (if the recovery is allowed to be unauthorized): +** If the spending transaction has more than two outputs, the script MUST fail and terminate immediately. +** If the spending transaction has two outputs, and the output not the recovery output is not an ephemeral anchor, the script MUST fail and terminate immediately.'''Why can unauthorized recoveries only process a single recovery path?''' Because there is no signature required for unauthorized recoveries, if additional outputs were allowed, someone observing a recovery in the mempool would be able to rebundle and broadcast the recovery with a lower fee rate. + + +(Note: the above rules imply that if all inputs have a recovery authorization sPK specified, the structure of the recovery transaction is "free form," and the only requirement is that for each OP_VAULT/OP_UNVAULT input, there exists a compatible ''recovery output'' which preserves its full nValue.) + +If none of the conditions fail, a single true value (0x01) is left on the stack. + +==== OP_VAULT evaluation for withdrawal trigger ==== + +Else, if it has been determined that the spend is not within a recovery +transaction, it must be evaluated for eligibility as a withdrawal trigger +spend. + +===== Witness stack ===== + +There must be at least 4 items on the stack (shown top to bottom): + + + + + + [...] + + +If the witness stack consists of fewer than four items the script MUST fail and +terminate immediately. + +(Note: in practice, the witness stack will have included the other items necessary to reveal +a witness v1 (or greater) script-path spend, per [https://github.com/bitcoin/bips/blob/master/bip-0341.mediawiki#user-content-Constructing_and_spending_Taproot_outputs BIP-0341]. This is demonstrated in detail in [[#Transaction examples|the transaction examples section]].) + +The items on the stack must be validated as follows: + +* is a CScriptNum of up to 4 bytes. +** It indicates the vout index of this input's corresponding OP_UNVAULT output. +*** Validation rules for this output are described below. +** If this value does not decode as a valid CScriptNum value, the script MUST fail and terminate immediately. +** If this value does not correspond to a valid output in the spending transaction, the script MUST fail and terminate immediately. + +* is a 32 byte data push. +** It is the hash of the proposed withdrawal target output set, defined by target_outputs_hash(outputs) below. Note that this value is duplicated here.'''Why, when spending an OP_VAULT output into a trigger, does the target hash need to be duplicated on the witness stack?''' The target hash exists in the OP_UNVAULT output script, likely behind a taproot pubkey. Its presence is required on the witness stack also so that the expected taproot pubkey for the OP_UNVAULT output can be constructed for comparison. +** If this value is not 32 bytes, the script MUST fail and terminate immediately. + +* is a variable length data push. +** It must be the scriptPubKey that is the preimage to the specified in the spent OP_VAULT input. +** If this value does not tagged-hash to supplied by the OP_VAULT parameter, the script MUST fail and terminate immediately. +*** Verify tagged_hash("VaultTriggerSPK", ) == +** If this value does not correspond to a valid witness program, the script MUST fail and terminate immediately. + +* the remaining elements serve as the witness stack to satisfy the witness program. +** If VerifyWitnessProgram(, , ...) fails, the script MUST fail and terminate immediately. +** (This validates that the withdrawal trigger has been authorized.) + +===== Transaction outputs validation ===== + +Once the contents of the witness stack have been parsed and validated, the transaction outputs must be checked. + +First, we must check for a ''revault output'': an output in the trigger transaction whose +scriptPubKey exactly matches that of the OP_VAULT input being +spent. Its presence is optional. + +For each vault input citing a particular , the output +located at vout[] (the "trigger output") must: + +* have as its scriptPubKey a witness program version 1 with a single OP_UNVAULT tapscript, having the internal key lift_x(0x0250929b74c1a04954b78b4b6035e97a5e078a5a0f28ec96d547bfee9ace803ac0), per the NUMS point mentioned in [https://github.com/bitcoin/bips/blob/master/bip-0341.mediawiki#user-content-Design BIP-0341].'''Why must the OP_UNVAULT taproot use a NUMS point as its internal key?''' This ensures that an OP_UNVAULT trigger output is verifiable as expected. It also ensures that it is spendable only by the conditions of the vault. +** If the witness program has a version less than 1, the script MUST fail and terminate immediately. +** If the scriptPubKey of the output does not match the expected scriptPubKey, as computed by creating a taproot output using the cited NUMS point and a single tapscript spend condition of the form
OP_UNVAULT,
the script MUST fail and terminate immediately. +** Witness versions greater than 1 are allowed for upgradeability. + +* If there does not exist a revault output in the transaction for this input: +** (deferred) the nValue of the trigger output must equal the sum of all vault inputs which cite it as their corresponding trigger output. +*** If these values are not equal, the script MUST fail and terminate immediately. +* else (if there does exist a revault output for this input): +** (deferred) the nValues of the trigger output and the revault output must sum to the sum of all vault inputs which both +*** cite this trigger output as the trigger-vout-idx and +*** have a scriptPubKey identical to the revault output's. +** If these values are not equal, the script MUST fail and terminate immediately. + +If none of the conditions above results in a failure of the script interpreter, the +stack will consist of a single true value (0x01). + +The above amount check can be expressed in Python as: + + + +spending_tx: CTransaction +vault_inputs: [CTxIn] = [inp for inp in spending_tx.vin if inp.is_OP_VAULT] + +"Where we'll accumulate the expected totals for each vault input." +vault_totals_for_outputs: dict[(int, int), int] = defaultdict(0) + +"Build the expected totals." +for vault_in in vault_inputs: + maybe_revault_idx = find_revault_for_vault(vault_in) + vault_total_for_outputs[(vault_in.trigger_vout_idx, maybe_revault_idx)] += vault_in.nValue + + +"Check the expected totals against outputs." +for (out_idx, maybe_revault_idx), expected_amount in vault_totals_for_outputs.items(): + total = spending_tx.vout[out_idx].nValue + + if maybe_revault_idx: + total += spending_tx.vout[maybe_revault_idx] + + if total != expected_amount: + FAIL_AND_TERMINATE_SCRIPT() + + +def find_revault_for_vault(vault_in) -> int: + """Find the index of a revault output for a particular vault input, if one exists.""" + for i, out in enumerate(spending_tx.vout): + if out.scriptPubKey == vault_in.scriptPubKey: + return i + return None + + +=== OP_UNVAULT evaulation === + +==== Witness program ==== + +When evaluating OP_UNVAULT (OP_SUCCESS188, +0xbc), the witness program is pushed onto the stack for the +following result (stack shown top to bottom): + + +OP_UNVAULT (*) being evaluated + + + + + +where + +* is validated exactly as described in [[#witness-program|the above OP_VAULT section]]. +* is validated exactly as described in [[#witness-program|the above OP_VAULT section]]. +* is a 32 byte data push. +** If it is not equal to 32 bytes, the script MUST fail and terminate immediately. + + +==== Check for recovery ==== + +A check is performed to determine if this input is being spent within the context of +a recovery transaction, exactly as in [[#check-for-recovery|the OP_VAULT evaluation described above]]. + + +==== OP_UNVAULT evaluation for recovery spend ==== + +This is identical to the [[#op_vault-evaluation-for-recovery-spend|OP_VAULT case described above]]. + + +==== OP_UNVAULT evaluation for withdrawal ==== + +When spending an OP_UNVAULT input into a withdrawal target, no witness stack is required. + +* is used to check whether the withdrawal of the input has matured. +** If the input's relative timelock check, as described in [https://github.com/bitcoin/bips/blob/master/bip-0112.mediawiki BIP-0112] (using this value as "the top item on the stack") fails, the script MUST fail and terminate immediately. +*** The same CheckSequence() code path is used as for [https://github.com/bitcoin/bips/blob/master/bip-0112.mediawiki BIP-0112]. + +* The transaction outputs are then checked to verify that the withdrawal outputs are as expected. +** If target_outputs_hash(spending_tx.vout) != per the algorithm defined below, the script MUST fail and terminate immediately. + + +def target_outputs_hash(vout: [CTxOut]) -> bytes: + return hash256(b"".join(serialize_txout(out) for out in vout)) + +def serialize_txout(txo: CTxOut) -> bytes: + spk: bytes = txo.scriptPubKey + return struct.pack(" + +If the above conditions do not fail, a single true value (0x01) is pushed to the stack. + + +== Implementation == + +A sample implementation is available [https://github.com/jamesob/bitcoin/tree/2023-01-opvault here], with an associated [https://github.com/bitcoin/bitcoin/pull/26857 pull request]. + + +== End use == + +=== Creating an OP_VAULT output === + +In order to vault coins, they must be spent into a witness v1'''Can OP_VAULT be used with a future witness version (greater than 1)?''' Yes, however use of yet to be defined witness versions is discouraged, since such a usage makes the coins spendable by anyone. scriptPubKey +that contains a Tapscript spending condition of the form + + + OP_VAULT + + +Typically, the internal key for the vault taproot output will be specified so +that it is controlled by the same descriptor as the recovery path, which +facilitates another (though probably unused) means of recovering the vault +output to the recovery path. This has the potential advantage of recovering the +coin without ever revealing it was a vault. + +Otherwise, the internal key can be chosen to be an unspendable NUMS point to +force tapscript execution of the OP_VAULT specification. + + +=== Recovery authorization === + +When configuring a vault, the user must decide if they want to have the recovery process gated by the optional recovery authorization scriptPubKey. The choice is left to the user because it entails trade-offs. + +==== Unauthorized recovery ==== + +Unauthorized recovery simplifies vault use in that recovery never requires additional information aside from the location of the vault outpoints and the recovery path - the "authorization" is simply the reveal of the recovery path. + +But because this reveal is the only authorization necessary to spend the vault coins to recovery, the user must expect to recover all such vaults at once, since an observer can replay this recovery (provided they know the outpoints). + +Additionally, unauthorized recovery across multiple distinct recovery paths cannot be batched, and fee control is more constrained: because the output structure is limited for unauthorized recovery, fee management relies either on inputs which are completely spent to fees or the use of the optional ephemeral anchor and package relay. + +==== Authorized recovery ==== + +With authorized recovery, the user must keep track of an additional piece of information: how to solve the recovery authorization scriptPubKey when recovery is required. If this key is lost, the user will be unable to initiate the recovery process for their coins. If an attacker obtains the recovery key, they may grief the user during the recovery process by constructing a low fee rate recovery transaction and broadcasting it (though they will not be able to pin because of the replaceability requirement on recovery transactions). + +However, authorized recovery configurations have significant benefits. Batched recoveries are possible for vaults with otherwise incompatible recovery parameters. Fee management is much more flexible, since authorized recovery transactions are "free form" and unrelated inputs and outputs can be added, potentially to handle fees. + +==== Recommendation: use a simple, offline recovery authorization key seed ==== + +The benefits of batching and fee management that authorized recovery provides are significant. If the recovery authorization key falls into the hands of an attacker, the outcome is not catastrophic, whereas if the user loses their recovery authorization key as well as their trigger key, the result is likely coin loss. Consequently, the author's recommendation is to use a simple seed for the recovery authorization key that can be written down offline and replicated. + +Note that the recovery authorization key '''is not''' the recovery path key, and +this is '''much different''' than any recommendation on how to generate the +recovery path key itself. + +=== Address reuse and recovery === + +When creating a vault, four factors affect the resulting P2TR address: +# The internal key (likely belonging to the recovery wallet) +# The recovery parameters +# The spend delay +# The trigger scriptPubKey + +Aside from the spend delay, the end user has the option of varying the other three parameters along descriptors in order to avoid reusing vault addresses without affecting key management. + +Worth noting is that when using unauthorized recovery, the reveal of the recovery scriptPubKey will allow any observer to initiate the recovery process for any vault with matching recovery params, provided they are able to locate the vault outpoints. As a result, it is recommended to expect that '''all outputs sharing an identical unauthorized should be recovered together'''. + +This situation can be avoided with a comparable key management model by varying the generation of each vault's recovery scriptPubKey along a single descriptor, but note that (when configured for unauthorized recovery), this will prevent batched recovery. + +==== Recommendation: vary the internal key ==== + +The recommended mode of use is to keep recovery parameters identical across vaults which should be recovered in batch, but vary the internal key for each vault output along a single descriptor so that no address reuse is necessary. + +==== Recommendation: generate new recovery addresses for new trigger keys ==== + +If using unauthorized recovery, it is recommended that you do not share literal recovery paths +across separate trigger keys. If one trigger key is compromised, that will necessitate the (unauthorized) +recovery of all vaults with that trigger key, which will reveal the recovery path preimage. This +means that an observer might be able to initiate recovery for vaults controlled by an uncompromised +trigger key. + +==== Fee management ==== + +Fees can be managed in a variety of ways, but it's worth noting that both trigger and recovery transactions must preserve the total value of vault inputs, so vaulted values cannot be repurposed to pay for fees. This does not apply to the withdrawal transaction, which can allocate value arbitrarily. + +In the case of vaults that use recovery authorization, all transactions can "bring their own fees" in the form of unrelated inputs and outputs. These transactions are also free to specify ephemeral anchors, once the related relay policies are deployed. This means that vaults using recovery authorization have no dependence on the deploy of v3 relay policy. + +In the case of vaults that do not use recovery authorization, the recovery transaction relies on the use of either fully-spent fee inputs or an ephemeral anchor output. This means that vaults which do not use recovery authorization are essentially dependent on v3 transaction relay policy being deployed. + +==== Mixing input types ==== + +OP_VAULT/OP_UNVAULT outputs can be spent +into a recovery transaction together. Script execution works identically for +both types of outputs. + +[[File:bip-VAULT/batch-sweep.drawio.png|frame|center]] + + +=== Batching === + +==== During trigger ==== + +OP_VAULT outputs with the same recovery-params and spend-delay can +be triggered into the same OP_UNVAULT output, creating a batched +withdrawal trigger. This is allowed regardless of the + values of each input, allowing the trigger keys +to differ. + +Trigger transactions can act on multiple incompatible OP_VAULT +input sets, provided each set has a suitable associated OP_UNVAULT +output. + +Since SIGHASH_DEFAULT can be used to sign the trigger +authorization, unrelated inputs and outputs can be included, possibly to +facilitate fee management or the batch withdrawal of incompatible vaults. + +==== During withdrawal ==== + +During final withdrawal, multiple unrelated OP_UNVAULT outputs can +be used towards the same withdrawal transaction provided that they share +identical parameters. This facilitates +batched withdrawals. + +==== During recovery ==== + +OP_VAULT/OP_UNVAULT outputs with the same recovery +scriptPubKey hash can be recovered into the same output. + +Recovery-incompatible vaults which have authorized recovery can be recovered in +the same transaction, so long as each set (grouped by recovery scriptPubKey +hash) has a suitable associated recovery output. This means that unrelated +recoveries controlled by the same owner can benefit from sharing common fee +management. + +=== Watchtowers === + +The value of vaults is contingent upon having monitoring in place that will alert the owner when unexpected spends are taking place. This can be done in a variety of ways, with varying degrees of automation and trust in the watchtower. + +In the maximum-trust case, the watchtower can be fully aware of all vaulted coins and has the means to initiate the recovery process if spends are not pre-reported to the watchtower. + +In the minimum-trust case, the user can supply a probabilistic filter of which coins they wish to monitor; the watchtower would then alert the user if any coins matching the filter move, and the user would be responsible for ignoring false positives and handling recovery initiation. + +=== Script descriptors === + +Script descriptors for vault-related outputs will be covered in a subsequent BIP. + + +== Deployment == + +It is anticipated that deployment would happen in the same way [https://github.com/bitcoin/bips/blob/master/bip-0341.mediawiki#user-content-Deployment that BIP-0341 was deployed]. Parameters to be determined. + + +== Rationale == + + + +== Transaction examples == + + +=== Basic creation and withdrawal === + + + +Recovery Taproot: tr( + sPK = 5120cafd90c7026f0b6ab98df89490d02732881f2f4b5900856358dddff4679c2ffb, + internal_pubkey = c6047f9441ed7d6d3045406e95c07cd85c778e4b8cef3ca7abac09b95c709ee5) + +Trigger Taproot: tr( + sPK = 5120418c46636d9e1a683f58e35b42336e776fdcc3b2d4e39e7a0bf1ab0716e3c5fa, + internal_pubkey = f9308a019258c31049344f85f89d5229b531c845836f99b08601f113bce036f9) + +Spend delay: 10 + +Vault Taproot: tr( + sPK = 5120062eb40e358106ea4f39bcac8ce046e44b84e5c0cf8799bd3d08f9ffb4afeb7a, + internal_pubkey = c6047f9441ed7d6d3045406e95c07cd85c778e4b8cef3ca7abac09b95c709ee5, + merkle_root = 11765541441f95f7af87fc19fcc1c09a1f5b05514d130320e4dfe6d729690230, + leaves = + - opvault: [ + push(5eb59117ddf962d44e11da5ce76c699cd9e6af53764795600543f02960b66023) + 10 + push(523882cb06ae65b1c2ba6e2009c0bf94e3d93ffe74470b354f854d335d9936e2) + OP_VAULT + ] (version=192), +) + + +"Initial vaulting" + +CTransaction 83b4308ccaa83eeb95316050fe2bfd1b027e285ddf31b0bd69762ec113140126: (nVersion=2) + vin: + - [0] CTxIn(prevout=COutPoint(hash=b4ba2b24be456aacaf743be5fe5de25eb3ebebb52f3faf75aecf45921a810101 n=0) scriptSig= nSequence=0) + vout: + - [0] Coin(4999990000, sPK=[1 push(062eb40e358106ea4f39bcac8ce046e44b84e5c0cf8799bd3d08f9ffb4afeb7a)]) + witnesses: + nLockTime: 0 + + +"Trigger" + +CTransaction e0844e873c4319222ebc407b0aa8f385c8a036e3145289d87750d5b895a88b33: (nVersion=2) + vin: + - [0] CTxIn(prevout=COutPoint(hash=83b4308ccaa83eeb95316050fe2bfd1b027e285ddf31b0bd69762ec113140126 n=0) scriptSig= nSequence=0) + vout: + - [0] Coin(4999990000, sPK=[1 push(9a15dca153a8651b610a02f3a92df3ada3cd45fd7f6183c7b2c1bc333bed1e63)]) + witnesses: + - [0] + - [0.0] [push(bdb4b3f6af17c93308af5ea689b33425497e388a0075f4311540e50d4d3d76f068ab645603333929e5ac62ecc125fc98a053aff53f65b0cffaaeef31efd415ff)] + - [0.1] [1 push(418c46636d9e1a683f58e35b42336e776fdcc3b2d4e39e7a0bf1ab0716e3c5fa)] + - [0.2] [push(c707f3e01b67c9dac06ad15cf0800cc07278a0a1c4f54cb92457ee5c0d84519a)] + - [0.3] [push()] + - [0.4] [ + push(5eb59117ddf962d44e11da5ce76c699cd9e6af53764795600543f02960b66023) + 10 + push(523882cb06ae65b1c2ba6e2009c0bf94e3d93ffe74470b354f854d335d9936e2) + OP_VAULT + ] + - [0.5] [push(c0c6047f9441ed7d6d3045406e95c07cd85c778e4b8cef3ca7abac09b95c709ee5)] + nLockTime: 0 + + +"Withdrawal" + +CTransaction 9595af9728de3ae9ca6110c040ad34f02f9db8b610296f99618354b99d5ec395: (nVersion=2) + vin: + - [0] CTxIn(prevout=COutPoint(hash=e0844e873c4319222ebc407b0aa8f385c8a036e3145289d87750d5b895a88b33 n=0) scriptSig= nSequence=10) + vout: + - [0] Coin(1666663333, sPK=[push() push(c42e7ef92fdb603af844d064faad95db9bcdfd3d)]) + - [1] Coin(1666663333, sPK=[push() push(4747e8746cddb33b0f7f95a90f89f89fb387cbb6)]) + - [2] Coin(1666663334, sPK=[push() push(7fda9cf020c16cacf529c87d8de89bfc70b8c9cb)]) + witnesses: + - [0] + - [0.0] [ + push(5eb59117ddf962d44e11da5ce76c699cd9e6af53764795600543f02960b66023) + 10 + push(c707f3e01b67c9dac06ad15cf0800cc07278a0a1c4f54cb92457ee5c0d84519a) + OP_UNVAULT + ] + - [0.1] [push(c150929b74c1a04954b78b4b6035e97a5e078a5a0f28ec96d547bfee9ace803ac0)] + nLockTime: 0 + + +== References == + +* [https://lists.linuxfoundation.org/pipermail/bitcoin-dev/2016-February/012470.html Bitcoin Vaults (2016)] +* [https://lists.linuxfoundation.org/pipermail/bitcoin-dev/2020-April/017755.html On-chain vaults prototype (2020)] +* [https://arxiv.org/abs/2005.11776 Custody Protocols Using Bitcoin Vaults (2020)] +* [https://jameso.be/vaults.pdf Vaults and Covenants (2023)] + +== Acknowledgements == + +The author would like to thank + +* AJ Towns and Greg Sanders for discussion, numerous suggestions that improved the proposal, and advice. +* Jeremy Rubin for inspiration, advice, and mentorship. +* BL for discussion and insight. +* John Moffett for early feedback and a test case demonstrating a recursive script evaluation attack. +* Johan Halseth for providing conceptual review and pointing out a pinning attack. +* Pieter Wuille for implementation advice. From 476aea3107b6459ad4e9cf5d0643b1e956f3c5cb Mon Sep 17 00:00:00 2001 From: James O'Beirne Date: Tue, 14 Feb 2023 12:50:05 -0500 Subject: [PATCH 044/454] fixup! typos and clarification from feedback by Gleb and Joost. --- bip-vaults.mediawiki | 19 ++++++++++--------- 1 file changed, 10 insertions(+), 9 deletions(-) diff --git a/bip-vaults.mediawiki b/bip-vaults.mediawiki index f675737a92..66bf7cb6ad 100644 --- a/bip-vaults.mediawiki +++ b/bip-vaults.mediawiki @@ -68,9 +68,10 @@ key winds up being ''too'' highly secure. Institutional custodians of Bitcoin would likely use vaults in similar fashion. -===== Avoiding the hostage situation ===== +===== Avoiding the $5 wrench attack ===== -This proposal uniquely provides a solution to the "hostage situation;" by +This proposal uniquely provides a solution to the +[https://web.archive.org/web/20230210123933/https://xkcd.com/538/ "$5 wrench attack."] By setting the spend delay to, say, a week, and using as the recovery path a script that enforces a longer relative timelock, the owner of the vault can prove that he is unable to access its value immediately. To the author's @@ -90,8 +91,7 @@ The only way to implement vaults given the existing consensus rules, aside from [https://github.com/revault emulating vaults with large multisig configurations], is to use presigned transactions created with a one-time-use key. This approach was first demonstrated -[https://lists.linuxfoundation.org/pipermail/bitcoin-dev/2020-April/017755.html -in 2020]. +[https://lists.linuxfoundation.org/pipermail/bitcoin-dev/2020-April/017755.html in 2020]. Unfortunately, this approach has a number of practical shortcomings: * generating and securely delete ephemeral keys, which are used to emulate the vault covenant, is required, @@ -157,9 +157,9 @@ The vault has a number of stages, some of them optional: * '''vault transaction''': encumbers some coins with an OP_VAULT script invocation. -* '''trigger transaction''': spends one or more OP_VAULT outputs into one compatible OP_UNVAULT output, which broadcasts the intent to withdrawal to some specific set of outputs. This transaction may have an additional output which allocates some of the vault balance into a partial revault, which simply encumbers the revaulted portion of the value into the same scriptPubKey of the originating OP_VAULT output(s). +* '''trigger transaction''': spends one or more OP_VAULT inputs into an OP_UNVAULT output which carries forward the same recovery and delay parameters, along with a commitment to the proposed withdrawal target outputs. This publicly broadcasts the intent to withdrawal to some specific set of outputs. This transaction may have an additional output which allocates some of the vault balance into a partial revault, which simply encumbers the revaulted portion of the value into the same scriptPubKey of the originating OP_VAULT output(s). -* '''withdrawal transaction''': spends OP_UNVAULT inputs into a compatible set of final withdrawal outputs per the target hash. The only authorization for this spend is the content hash of the withdrawal outputs. +* '''withdrawal transaction''': spends OP_UNVAULT trigger inputs into a compatible set of final withdrawal outputs per the target hash, after the trigger inputs have matured per the spend delay. The only authorization for this spend (aside from the relative timelock) is the content hash of the withdrawal outputs. * '''recovery transaction''': spends one or more OP_VAULT or OP_UNVAULT inputs, which can be done at any time prior to withdrawal confirmation, to the prespecified recovery path. This transaction can optionally require a witness satisfying a specified ''recovery authorization'' script, an optional scriptPubKey gating the initiation of recovery. The use of recovery authorization has certain trade-offs discussed later. @@ -186,7 +186,7 @@ The second component, the recovery authorization scriptPubKey, is optional. It is a raw scriptPubKey that, if specified, must be satisfied to allow the input to be recovered. The benefit of using this parameter will be discussed later. If this component is not given, the de facto "authorization" is the reveal of -the preimage. +the preimage, i.e. the recovery path. Vaults which share the same recovery path can always be swept in batch operations, which is an important practical aspect of managing large numbers of vaults. @@ -269,6 +269,7 @@ where * is a CScriptNum-encoded number (up to 4 bytes) ** It is interpreted as the least significant 23 bits of a [https://github.com/bitcoin/bips/blob/master/bip-0068.mediawiki BIP-0068] relative timelock. ** If this value does not decode to a valid CScriptNum, script execution when spending this output MUST fail and terminate immediately. +** If this value is less than 0, script execution when spending this output MUST fail and terminate immediately. * is a variable length data push, consisting of two components: *# a 32 byte tagged hash, the ''recovery sPK hash'', committing to the scriptPubKey which coins may be recovered to @@ -299,7 +300,7 @@ for out in spending_tx.vout: recovery_out = out if is_recovery: - eval_for_recovery() + eval_for_recovery(recovery_out) else: eval_for_withdrawal_trigger() @@ -307,7 +308,7 @@ else: ==== OP_VAULT evaluation for recovery spend ==== * If the recovery output does not have an nValue greater than this input's amount, the script MUST fail and terminate immediately. -* (Deferred) if the recovery output does not have an nValue equal to the sum of all OP_VAULT/OP_UNVAULT inputs with a corresponding recovery sPK hash, the transaction validation MUST fail. +* (Deferred) if the recovery output does not have an nValue equal to the sum of all OP_VAULT/OP_UNVAULT inputs with a corresponding recovery sPK hash, the transaction validation MUST fail.'''How do recovery transactions pay for fees?''' If the recovery is unauthorized, fees are attached either via CPFP with an ephemeral anchor or as inputs which are solely spent to fees (i.e. no change output). If the recovery is authorized, fees can be attached in any manner, e.g. unrelated inputs and outputs or CPFP via anchor. ** Note that in the draft implementation, this is facilitated by a "deferred check" which is queued by the script interpreter, but executed after the script interpreter has finished, in other validation code.'''Why does this proposal require a "deferred checks" framework for correct script evaluation?''' The deferred checks framework is an augmentation to execution of the Bitcoin script interpreter. Currently, the validity of each input is checked in an order-indepdendent manner across all inputs in a transaction. Because this proposal allows batching the spend of multiple vault inputs into a single recovery or withdrawal output, we need a mechanism to ensure that all expected values per output can be summed and then checked. This necessitates the introduction of an "aggregating" set of checks which can only be executed after each input's script is evaluated. Note that similar functionality would be required for batch input validation or cross-input signature aggregation. * The script must FAIL (by policy, not consensus) and terminate immediately if neither'''Why are recovery transactions required to be replaceable?''' In the case of unauthorized recoveries, an attacker may attempt to pin recovery transactions by broadcasting a "rebundled" version with a low fee rate. Vault owners must be able to overcome this with replacement. In the case of authorized recovery, if an attacker steals the recovery authorization key, the attacker may try to pin the recovery transaction during theft. Requiring replaceability ensures that the owner can always raise the fee rate of the recovery transaction, even if they are RBF rule #3 griefed in the process. *# the input is marked as opt-in replaceable by having an nSequence number less than 0xffffffff - 1, per [https://github.com/bitcoin/bips/blob/master/bip-0125.mediawiki BIP-0125], nor From 9124f2940e6315deaaee4aca92a8250aeaa3aca7 Mon Sep 17 00:00:00 2001 From: James O'Beirne Date: Tue, 14 Feb 2023 13:07:22 -0500 Subject: [PATCH 045/454] fixup! image clarifications --- bip-VAULT/opvault-flow.drawio.png | Bin 47748 -> 51069 bytes bip-VAULT/vaults-Basic.png | Bin 31544 -> 18595 bytes bip-VAULT/withdrawal-comparison.drawio.png | Bin 19737 -> 20724 bytes 3 files changed, 0 insertions(+), 0 deletions(-) diff --git a/bip-VAULT/opvault-flow.drawio.png b/bip-VAULT/opvault-flow.drawio.png index 092a683b0e14f3d86e6791b60ce9ae085f67c0fd..b1a0b18bb21610920f07e056b513bb3e0b9355b3 100644 GIT binary patch literal 51069 zcmeFYi9giq8$Vo9M6x8ZW-UUDF@~hfY8Z@l%nV}2I)-7GF=I+uvx~B{P?Acv2-zwr zYm}%+NGOq_PD-JA?m6dtpWpZUJg?XD7d+>@&N1`(+@JftKi7RN@9TYClj`VTEg_~T zwqe5t2^$>RdBX-F%!Umczlm-ESAKY=>4HBSBb}|08>*iu&x0?*kw_a?QSi?(QNI-M zkP;h1Vu$hq=pp_aw4tbfK4}{p1%*YjwV`NjV`FM~_HaZoyp;WzdSQjZ&MRp@Cgwf9^&urPs7u}YFHQ)z8`8Tcm$7gwYSqYMuE>EbcR3p zW9{$D2opSl3W^8|1y`^TBlG=6f`7q97is`Cg8pAq2zDOj9}!6pWBzC3`_1+ngRz1; z{%mUCKbHv@7c`#f6k@`~`%<{x&ff4~)<0v|(c%98jPdi2qWgjsjkTc|Ah~}<1g2q9 z!AAZTog;W_1IRxQ(*G3|C&0-$9BE>25XKB)kfAJcI5zU1N#H~_%@-DFf^{^3Fhdyu zZ~~4MZA|bDw~OTS-A(w$=26Bh7Xq4Q9f_tRNR-Hcs0bq0#@5yr$wsh)Y&mQwfo31g zBiMzT!N5!7{SZ7j87z;)aoAi}j42;{2i&2Xe`jKzs;chr*S1>O((i|TUYH9>yL$L@f9|tv}0PRPT?5rJe z<``C3n7u#7$=%N`7=mQ+i1wyN z!NClSL(yDd1Y)pxlnajUM{+*~5S3cbsD-bQz)FeDYU@hQ| zFQ1KOpvfF37@p}EWMu1%w|9r3%&eVYA>b}Ck{vFXg%bq@-+=ienS7`zh3?42!Z@~0 z(Gk>u5MHoTu$i@ueI%R@bwM%Q9Qc9OcECSieNCJxp%K(DJ0p@i5rLsb(}KWNceE3Y zjSLTRgYpqvh=WZO-2{$_biqX9qRlDM_Aa(8h6|kHPqN`gAt_O>%$vYiMNvUOxo zB--7@6&Hk}u~{fSHX6@Gg<#Bi)|7B3I|x0*HInEYOh zsLmv`YcMW=%CIv=xWIS_5+}eEMG9ir0%7p|TpdHAgMwHA{OBlK7Mnrj!2JCLrXC9Z zLr0qWS(}h;qQioyfmoWGInj)bbh9xrff2ZlL@dJ?77eG`qa)pIZ3WtlG-9x$nSxVw zbMQ3^<@tsKCrfvOhllfB-R+&p1hb$JqC-fq6I?L4sd<1O2N}qAGIj%xx<+DnSPlu{ zfMnR374#EKAC=qUCHyAJ4A8HDrK<%(NN*Ip}v2_j) z3MJSF^K2YYjL>MJF)ReZfH_lGCQcz}KPC~vqS~-A&URd6I6XKT%W!tZ!;P&`rZ$Xd zL^R*s4dxC(W0}GBU|Sdxhi>NX5*CJpB8>>fA)z4{90&w_YJ{7a1KY?nh)i}B#2zY) z6De>hWbm1X=SN3lSvYeSBs$mxT!3Ir$aWYTlnsvQ$96*Cq5e)$Og7ow&jb#Ek&T_G z_Ix77kKp9%&vQov&n5S**IFPRFVMLL2&33o(CQ$viS zN#@4p0@a6dC=_5a*k}yXjb#ky1_Z$Qp+vSBFc72z3;Ykp?_9k2s8g3pQA((*VWY0y12Gau^5Vlcd zM}Gta&Tw&ahtX_oi5P*Wp!r1^1^eRgc6e*15zC0Kgi*8`$%Gc_ zXy)e#<)ByyRseAQYkNurxEcbvT(&VjipGVwM>+>N*x1qF_CX;g{0JilYZoNS7Z((W zHphiJ`vET*jO5zkNya2IDwV%)V7<1pqK)X;f@C$t3U?ZFx z){z*7v137v9U^Hw35m|o*dl>a_y#~t2=*Z)vbh7zh2g+q zJJ5NiTsO869!o))^6hyjrEdOLb+jYy{t^uKv!p z1b@CG+?N!L=OFP8rf_gMB$C9&2O_D?=Amx52s{c(30`333bI5}+WR!2Sol{|)8A_kZ&s zDCVNVZ^VWTY8!0O2v^>bk3}L)vM+vi5jsd$URs#S;^XhCr3uk8#csd6zdc1leAT_O zeLEI&fBP=I6b(67t$q9CYSL+&Lr9L5FH_!Knv{R?*r@;G#8GZkV8F_+i^5SV|37w-y=M16Zy9k3yk%Ua z=I6iq3|mEZAA4%~Yxx=TueZI6X9$N_hkyUL;=!9rnn=^Do*VW)5i`=lVKnybZ*9sn zeWkNdp!w@>d7QJhf?&>hYv_^~qT|QcJ~5vbBe3z`U;0Wme!4x@l5gPAlIMP8R8+bn zXmxp>IaF%1n7a33_{!^}H*-pTv&_3x!tZZv*iumKE;z#MUEr`%5jWxzt>~gY3Ljon z6s-Mxe`&&IZ_(TDyhHVq$b1o%0)T?#V*5u$AVce zIFHXE-vC)~vlYezJVI(Qy)E{IW`pBF*%dno2W#JcG5K5a#YCXg<#~C-oB)}P`snwU zPTW(124r|Jsv2aTeVO1+ax6a8pRxGb5A}!GZgZ2+0>;#!spjnZNw0FDPhY4*D)i2m zF6M*8t*NAx2l8p1L45{|Y{R?Dr)e3+t>UF;fyR=NR;4=l3U#kwvAFFj2bvs;4&=$A zTzC64y~AcIzWe>{=7|^FvU~CZOMHG1$PCuDS=dTZRO&GMg`0cx-b=@BeSFqPf7YcE zvpi@!VrVgR9_V-69k7kum7Tf2o6$ZOLT|IcxQK+IMWv&cOBepk?EVuz(|s!JqtpR{ zK$?y_L{ns6bQmva)Fp1HMIT+d+jzm)-?sC4@asFxtqawyvL3FG4p=LXh&~~duAiYNur){S0Xx4zU^tjx0 z(zSB`xAUyaPEWtwTU*rQ=oA_LeJm7kEag#j4wa1A;7%Okq<&~6dN-Dx-ru^)9$FDN zk+@2A@Innca}K$ky04M0KOOL-kp9?9PunENi$8yLLh|ss;|*QdDX>MP8W+6IJ7#Zb z_-pAO4|o55bNtV*l{9ZGHucoajY$H{e{m8>p`og*dat|aHkAXI=(QzmYugBVp~=%H)pS?wiEo%!Ex}`fM6$<%Tu>`Mox# zUKcnJh1ai5)ZET&`}MtU;P~qN-nDId?{%*iPWK!~QyPNbU5xooUU|j1*<8eZJqk?T z`kT<>zWayPKDxlMclT(AhDuXo?)4k@H5uOfQ4(O|g>~zKwV*^}eDet9)D+H@x%o*Vjvb z*nNg=cgE<~i~7YncL{b-l-v;f;rR{b`j0P*CzY5r`t~XE!#6I3-5Z_$bRNc-?aEYo ze;yvTcv5mV^XrMPkKwb-JzFT}$yDIM42#iH$gA+1bS9MkS z*yna;w+feCWWl|COEz0s>W81e$Zq*~#HWoMG~{F!h+U zyT?D(hX|Zy)wgU@WU(4JrdMioHLFX9^mlhiQB&1T=gO{RMSObIP`9o3YCh$WvBq`# z3v&20H3t$i+ub|n#V6pK7lDq#<(1`jJ+f5;zO@EsbW#>^O--vV;Bk3m@8+AkPbayh ze*I}kR0-w`zCH;#^!tY|cXj@{lKIhJ-$uNiU9*25Z^%2Y?ks!`$vuAJ&+nDCs^!iM z1!%wJuIq%evYlQh6c=uo&j5Eev?wKHE{KBG>2B(7tiYn9i_NKzyGZW~BcFKAct!MT z=Wn#>JNx_Bno?XdKpOh@MD@0H%mA>^c;a=8+@8(tRtr9FVAasd{qWbkE02Ey^gyO> zC8UL4M>I)I=cTZwcct`#;Jujd!8B*^GLCNZN(p<#8SyfhQ)-+9mOi!p;Ag7^2x)E| zS(dm-58hPA8?6Iiu~?G6KUh{*js^u$B)A7kQ`1P8n-$7yFX0fs@pR zPA^OAK6-x>SE_SqVNVr97WiI8uOGRF7mTHZ5xxp>9U%a4TpK*FQ0d$LM5^Tbr?CM{ zS~%R`?()!L^6ukCc*nx4a{#5W#=_d}O3ROjcL-Boq-tO~womQ5;-mZJ;EA=d$?=uR z6JZT^q^7g3*`1rtI{cegr}#zEvc?Z$efg_+PKiBy;`zjhKfm%>@QAlK?)TBa3yhmj zd7Vd2Ji=GZqXYpBFB+#T(7`L6<;HF-I#uB(5X!`{ua5)Wxo>l<&nrp9$6M&l9hy0+ zZzCME@@Z@&z9gooBz!_csGv7M6D#5_zyH8Eb!w*OUiN0}=at}!s@ZTAnP-U?KGr{T zfL2Hk>sOLw&91(a@VzpL6gTjDw{iMOay{mSb-ezk)}?#ZzTH`~`xD=K9sSfG=XvDP zA+Wi;&^%A?ESyty0pZbzA~1`F+tV$t>!o$9ox1C9+I;N>kg0S+T{t2UIQlF(d^vG5 z801!)f$>hnISo3_Td6xn3yaEKHG17C?;X;9{i5vDk^5dC_{cY%aX4_}uQWRL?-;#P z11LyRdO5yaRT!9(g*fqQ{O5l$3t9e-ZI|SUGZI?=WMFYazykKEpfUmUNZW7@TCZCi zaZ`RMr&cQGo94em`~Z%!-C~`oA^hm%hG7kg;yUoLoX8&!IJac-B%%b7-bzBSWg431S6*s{nO(xU2x-&0EBfPu<28@RtqvXombWcN7)wq0q0N73u<|A0@!R8QU3Y* zWoLGi2q`zsBq|0R==&S~xy$czH9h(lRI4xK)-Ng=#sC8t^4>&O6HY^JU`R`9zmn6* zFVpE^JI0GXjsD%c_fq|^V*NmIxVl1i{qtf8(N1actsSY6Qv7TfeMk%O={MZf9G5fV zRa&Nx&%c4dq!~9TJ7YyVG-Dg)o}wfhy3VC(4>{b>654(2bDRe_xQSAmGnH*;y)azma2;UZC!cB_ZqM`F{@4u*B=AVI`sDt@LgO3gmR3ueExZ$d_3j-O zvN}x=mOH|uG6rgXuP%&j%01$8kgYwhvEg!DlU3S-h$rUnn}Bb6_-%1wEJa%Qn#*+u z=8w-)!?c8Zf$g(p?L@U~gVi!bERpQLQ*%9AgMW#dM?LuJ#M6fvOVw?^`HU_2v8;w+ zO5fd|vlsFct;D5oLFX~VvSf1M@uV(sc+^Bl-Q)2Z>cfwUVJ-7}M06DoA3xS2UOKu1 z1^g;R2j-|PEr6Gwwuo*mSsA=N#$2G>4xxvo9VBW0L~lS^#H_N9{ul~O>$;S!#rGII zia)(wXnlB&w$wT(($ECLTZZV=t9M+SrfXWpD)TRBK!43cbxYEz_|l-yZ`zs9%bXU0 zrq}uQ)O1KByUjh6JZwT+|I|47ihJ|kYWY~q%EZLlQrlrk(d^vIsO0lW{K?iOPh=Cf(>7HIiPoyjK=`b=PJxOj*)(Ia-_oDur=EGdfNqCpZsvXW8qM=NZ)s7DqtXns@!_eKJ5_1bBvbR&Kuen>W4|{_=i@b+`b8`)`*x z?f|<7vPu*wYG)Plam{z1dG+E|!xKO86FYzZURz>5vxhfK&g{7mLi>Uu zMN5V0#=A-#l?~L5Uw#cdYt;69h%~y;z+)XKk;bHZe{(=0kiYp)S5b1swv~NftVqrG{`@|gZlLc6P837|#6)dMud{2j zWkHvn28Lc-ZLXBKL9XQMz~M<|ys*1%u+m1=Ykq29tnxd{B93mXkRnoy1@ILb>B0H< za`1y}&acf1?ccfrvq6sAEt8P&v1ul25rAFR`y%ee=AXyDkAg3B?LEij6d<-ubz(Uh zm2kgiDwz`6@S@)h7ouJpn4Mqtu@1SqQ&G}*j!2_1Bc&g}0 z@1MHgT?wwL@8$K4=$64g{UoFchEA+B;E4#oM%HjMfr|ocU$E3)*wQCR;wExM{ z$veGLrBaZ^_7_ZvW{&f#uXckRMJo=385y16j9Y3ok4?u&_;jsji;ZJU3kKdOa<;#v z{Aq`_e#3L;*(?P((=*{_QttG(VUGctc1q+8V(&EPbTc|edFMdIu-Ekk8KFFZ;oRae zZfi*2e{R2XOxNX_EGUK~I~mCLJ@DdAy!-x&VQ7&WqLB6=C+-1PBF~8YQhZAqL8@dx6=|Om5_~=m@PEtMF8%W@<)+o0s^HH7WSoNKU zZK(ZuL`v_i{2+x`t3;g_1Z{tc*z(fkBnaqHXMWyZ{ZMgX^9`@osHi77)~fW)?`yU@ zHDxW+!gNb^#_f$DU7QnJOzLlb!|iXLI;r$(SE>0k!hEia1EkM7cYCRE@ z|FP2ii?`2$M@YUB-G|c}rC&}oM+S~GFx(@r=d9YpCTTWp3N*I~`)@lFpinXMsy~(21;=;wFi?#JZX>*7@&DA=V>JB#I z`%T0StP-VdPTl+>$m&(VX#@vWMRKkl%;<9~ND*RXtLiHQ8*5tw$t?-oxe{0ybPWy_eRx8LZ(Xp(J z)i$`tbQ-E2F8%hL2Nc_HH?XmfH=XQ*Q!GUL(B|h`kNV~m&S;jYV&4;x z>jX@x2NnF(o!c`1=CaZrjFh&gD|LnJi*u^+-Z`Rt9c32Pdq%EDWLSe8mwjwyf=eVV zJ$E5AF!W8XEuBizt9Gj(V$NuYDuE&iucGSqt*=Bcj+-X7>1#amcJamR=F-jS`8V?m zmtQIZmMiWRNHNN84_m<9@dcs#=JN5PYS(V)m!{ma16Z-)Y;L;Yy{2kMzjQf+j}|!T z(zvV%6D@7#$+N1S44do{pJ9r+3h*@q(>XXsKEjhKoGpM(*xc!A@fD>~u@(89aY_u` z^Oi?%OKb4)gLfKEmx>nk-SvLdAPK7mDmN;~a6A^&Lub_-7n7B14LdrYQeusdd} z8|m&V-LzN^(o<5l#=e8ksD)?sJ$;vB%a>YePUn2Aone%Q@C)d)a(DhkJb$0xiQY6mLT0qnQ5D#u26 zIlJ%eEkB~}r-J_dnX)^CngvpJ?{l+w^g-R-f>G3w7u=>5SJEZmp8)f(c1Cngy`a~> zx6=8Q;W;lw-95q)0$Qg!zalF41*$q~_&}=Oi{myzm`nlh2TC4Rd!(PD_MhoHO}<+1 zZQN?&Y$y6w4CuF~f%_+&ie%4El^hxO@?WQg(-cvFN(IDyoSnvfl!Jz_V!V~PUNIak zsRDR1tK$ORZt0a8;vk^Feh|#(egZv)<6PdS4FMr496HzUq zaqA!v$enDc2!8x6yW;;}X!ziK@;Kq}ueYlFIdwt0+St42LemZhv-V$~!cIg2d|xdf zY8EEj+Qz~kN_d@8wH)u>ec~f)kQ+YpV-4Ck77x`RHK&PId%D4tUf@(%K&oh(@0P`gt;Rz3tDhrKlt0 z2N6YCX49hFwNH&BneAqCPntxO!|!`8w2d)aN4bEeEIkUwPpBUKI91&=EoQN$NYdh? z(aLDxrRLqof3z1xy`nD)(xs&by9CL8ZTDj1dxco?WFHYXt`@?_eW~>SL1pCaUKQ08z7oYBYeR6XCk>1V1x!?BuHm&l) zEjs{(4hLEMyMP-(*d*9H(uSk7_9XHWFU2{5m0Ip z)OA`w%|qeb^pb%7dVJAxtm`+JDWn=KGbYHc1@)8KullteGLiGkK->z^KLCQZZvzR% zq#&Wf$(#_m8vS*)8nAhb;1n8X+(8<((hnUtduZ=PUWrHWjjQA2z@m4rkFSL`4q}y> z$#nsvyAa!c|L8s}cQF6!?Uyuh?x%*476F}D(*oegxc8q`cTMW=$xDCM16SHbb~h!- zA9?8&^Xn0+oV_5wb*!Uks;=7$%U$P&Tv?s{- zVP4+)3(&%fqtRbFrEUWL`<4Br zLlXvV>wkS$>F|4VKdu^}udm8|5EApju0*)Z%&PC8(nO6Ej4|9l!Rl671eDCphklo0 zzC*;NS`Y^YES3(|on<-X+MP4*yw}Z-dJG%My_0!<|^5 z6bFCQJ{<=T61$7%gUaFs5iTAa6{O1F%_F)L0-MxPC!gnto!U37fP2w@4*D1=lM9MN z6Fr;X-tW8Bw|@cXH>6G<5m8eL*si_Uix>GHZp42*2CO1-zT+(ETKJej{Zr)ZlZ4nz z1!$MPzUZIM)fa#$soTyTUVJ%n zpzAz6`6%)9ju|62W4*ET{9RH@rQjphT2asuRe3#u{8PTV1zy`wNqWyzl% z+9|41!@ySCo0nn;#v zl*SK$5X*m}XP-9{KmQJE9T z?=_$7TO^GqDW6&sA7$LU`*HX1#oZ^?2d7pa-V%=f8lM!pP}OJ(*W^iwH#~E&7>%x| zZV4_qYC8YxbXkO=9l%24Ab#dvxLR(2>HC$PurB3-DwK@B@DYfXbH)0U>0eep#*1px zektiwktthijSjw47wr&{P&DZo_sHNpMTng9zZN!m&vcL07IAUEDS+>9a4*(46mC#x zo-0Yu*aacvDo6CF%e~Eb7uc&^VA3}P*e@EyG27VFwPOdheKc~wQl;DX?$!bKIZ}^8 z+_R<)(&N#jsgw&3-o3nvm)G>@kQea20lJ#k7zq-lMi06s-{nRu6-0cft_20Ep6x&p zN6F%J8LQ%PNpscLprjpMq?GnUQ6EY2IB!Cy5mh`bdx;p~9c| z<hE6$;{?NL|rdV2!VnUgZf*8$lvew7ywqo3PpMG7&!-*}2P|4dl zl81g2KVGU^OwnFlY5NoEx7D-H;N5G(cf)OkGc(3}&gA^k1sq?o5qOgUi_lIDSE z@oAxE(QfEZ%tOUZQ|c3{dQMeo-|_2@c2u59I@6EPPt>q(Sk)Wk$R_~c0@0a2o2Kcw zAZb4CDomew@K7abVV`ZdmvoSQd5i(RYN-IpAlS+0Yv>;Z$!CKPFXsy7cf;H(aY1?P z*Z%;h=z=bh*Iy;}yFNnkzPuG(F=R!`0AvXIJa9Qt$o~U_UK$?J5qSgMd}C|pB(5sP zp-P|D-?RR(1efpQ_@gj3dU`lm`jW}_O$`Gn(#nU9@d8fZ8>-LZoT`>$Gmf<3oUrnH zt_0KDIt;gQZl&mHKsJ!sgBXKdmz-rle86Mf>kqtG1^ng&Amn^LF{O;%dbev|aXT#` zK!dg0hcpsnRU=->NFc1%v{kEsCw%?L)<;1`A-Jb{-=ErCVRihsw`T~qn+$DMK?u9r zwq;07XrtxZ*)5ypMZyZ&o3fiST|U;<8>r`9T17_7e=3;US-LJ%MIH8xw6C+}iDO=m zw4PtS-lUf|&HCxAMLfM99M1go%~4;erzj@VXAVsWRTskz@9k7g{}#JyT|d#&8q|iq zsn+yVE&x<(`qyOeC)6DU<$`@eb$hmIT0Px+w`p4IQ?fG0D~OIb01egMZn^BZ5Qjaw zZD=NSpb11weaF0uKJ_bVWAB0YX$(=NgsIiH%ne>i{#DR|S~k>tta@2O6j9(>ehnk~ zMdhCP2f&O9YHC&3K}AL-6_x@j8_g~G8i;W*6_23fUET3kjcWk)JTK?DETz2h+((Lh zyv))>r5>RlX&NS0QO>=11dp?C#X7%Q)2?U>pE~^_FXspua0ogTdM=%OC+Tzdk*eR> zm##1HNkdKNP>D5NpHIDU-DmeqE@AtMfc|^(RY23`m{;nD-TQe>fS(wkSwQpIdqD&a z9;jcv55t^seUij>bldd+op}}@0m@Ay#je{ygAXVfR_HRB#|NdhJ@F4wd@yuL;x9y> zB%$o!5fg5v#chyRZ+?IMFy+#rm=FWCL-jJ3RYYN@o`w!rl8MWw)V!+GiF@YaEw-HQ zI82H8JPN{CSj*r(Es6NtuH(HA39_{GcaEoHgv;!)5aJ{rvZm;M{iFuwMRWDJwtcVs zeCX{m$ea6D!#DRjDN34Gnk*|k)DTt|6D##^ctNaFlB==^@{M~sl99Fi>^cEXi?zBa zVDw7kbHj%&-_1TPzExu;QD2RJrRwhYSIqApN3pjBB>xI1b5a=F_~+E6cBFIx?7|S% z*I}2OvdI5BGn-uKv{fm7_S^TF2>WB$qdSD16Jg>NyU=3J&ue|Vo0p3pi^$a;xyyGe zt+JNGv1d>CIUBi)KHbI#P0`Qso(hL0!+Z&8mu_iB%nbjyIt&Rw^jf|$8rx3u|mqF!dD3_m-`MkIe{%JxO$ z-DVQz@hMdM2mCJ2!c#su@fqRUGrd`@>g)0)a$NoDmZqQT-k-)A;pw~bveco%o~Zt& zsNv4m{u*MfsklLXcJrS-4uwHqpNTWy_T2u9}%ju-XFhi1=9LZJa0@bir)0t|Am1inMP+4k5g_4767ZNRHFIRC+m-{9qF*pg!)k{E zFU8y*19fNRu!f8&-?Sk$BtjpZR&qkSk{Z5r?Tg1yVW)cRLI}XsOn^%a7ll>a1pO2= zpBRAD3|aQ}h*^GkdZQXkX-oZ$pdXr8mFcwOeQy zG=S7;fT))2MXlaQdRwDKooOsT+||li}|Kw(X8-@?$mH zUe_0NAo*}oAXDmlZB*m*TL#3u-o32#od8_~v|4lrf-^tVNefi7e!ki~lVzb#IzP>8 zs#L=Y%Kj>wE}z`cz!-Uglhsl>9r?LkWTg4Qj|;zDO}JM-7$AncW4`5q68^XTyd?2- zv&tIT1Gk^9Kd*=@or(ul+xH<%S_S|{N+Y-Y@tQu_#?wV=w%G`MH>rC4G}Yf481i_* zknRaVY7zFh9O*k9ZuBWo_i4-J`!q;A?hVaebEf?As_886k?5NvzD3o*z`C|M3aai z_rFVC$X>N0@60Kwtj<^t78QEcErF;w*qtW(xINEjQb1r@{?((&8O6Sf^SlyoHJlC) z&I64es(XG?4CzXlvENy%7N}C4U$E>g(xP*-#i4^z!u8%IgU;W{s3@n^?%=ziB$iXM zJYuCN=<3T&0l`vVQk$t>v|o6epzklyP9ys}Dyw|RTA7vTf5hKLXA#$CEav@6^2cHN zI&f|I(mUIKUd(_@-|mS(m0A4)som(|)$5y+`l0a_XIh?=cI(Nl)vw@d`NUPTDQ9{I z%=ERWP4aHF-!R^aoqTufc^ ziC2z$)gSrh>$<3kPMcM;vxRY}TBBBK^U0n~3zpwb1kG&RdX21?S9Swp67tfB(P3Mq zu6R{7`fU!@4D{LczB%|^Z1_CrF9aNK(t+pCwriU0cDs{+`~#a7@A(m5h@i|_Vr#LL zi1uY3U)$+n%IlzG1a%v}j?+=mq8kV88$Rop&z|+o_%UdksDEI&_>equ$~joUDI!+U zPPXvvwakurdAMql){S>>^?devJx~MiHq$$T@f9jbxE2qSqQT+Jq?|^N=*&Te@ z5Bvd7(E3wEChKJ22GrB!kbA-{5F|D2rfYM^!$D8gtlLrg5ZBnQotVoHo0fDUdYUsN z=i_^fL?lQBBwA|ptoRX&Bm?@sHINRH3~yE3y!Q$x?w47sBV<#wH&Hb}%5=42Ffo5= zaO=W=ASl00eUQUKw#tk%v-f*41*p*X_^YTw-gGLl^Sted)HTpt*>iq;NXfvV4LRea z{TpP4rrQSPcslPmiD#T zG7|p)d(KDh5^{17u3wF^?AT{Ec^2aP;Z@Ajs7(vo;|4mmTdvMs$?B@k5TVCaUWUHa z)<4z;(vI^x#YaKuEL3^7r^-bUE`ylfy8afJO5Bn{Zgojm^SKlZE-YRd0SLQ^J@acQ! zl3QQjta%_7ka}4U#zM1WR#X<$t(u}i-<|({t#NwH+V=)V^J2?F2K#fk;j-7|?cb(; zip2>>Kh)*`3W;(|+H&w<>efriogyQOBWY5SiLH!|6zLq7&*mfcQl=3=K}QdV7dME^ z#BOG=fNd)w{(AdVa@TXol3j4sOTL-kAQ&5|%Wp8+cfA$wvY=5V;k_^8aYg;W<(mYi zhC@GFW&3T4iXJ~L_*D<%EvwTkK&{v(kWMdVqqalR-3pIqUu^pF=x)U$zq13n&4NZ+a$2nz`=HEBNMbBR}3@V$JTj z5y_o0I#Sb<0#q_`)BEt6L4k*$_qJKDx~b%eqSxY2ljDMBB^lk|^+ny8bL3+^f*xw@ zu9TuLNz#_WN%!Uo^^&g z)7SIENA2Hxj!Wt3$_-WBe)XuUy&N55{2>~nLI~I+N7V0Zx~Kav&L5s8n}cruCG6bQ zM;y3lsoAada2bHp+X3%LX{qkZ=Y|d`Box%YaQB{g#Fa{TDOGd{P%q8PYO~TSzkui% zBX+$qA5Kwisy9pPmM6JAnSy;#FL;Q-JNbVq2>P6aH_?svlv+vFD?DqSvhnTa6(gZ9 z#iV`RF+Zk~qs9SM#cXKlc~UCj`1}jtMVCFr5!Z#w@3`#I{CMbL(y6|4l?2bD>ngB4 zu=bQsn#AmWm*3YM_4YG8XGu4r=?OXwVUw>vWWvya4}{|RQUy3&ndN{(_x7fij1Sk# zhV72DH*n6)%ga`c4D0`Mr)p}YKs1gf_4J{4Y1z|5Um%#Kr&1~Q6~wAaz6Gqkr#eyC z@n&Bi;F_pkqDV({2HI;~?t82CTVQhD55;nP!_0pWk-hWdDf7DG6^;Q7nPVl^3gK5X>dV1Edbza|s0>ZO><)owlXBzF6EVO9icIez}!ak^jLAfYNd`}-e2g}xly zGwLl$_V+tQ&05i20j$yObAym7(Cc!YiTj{)SsWhzNSrqc+DJa~?52+#ek~O}vmDq`RQH^{~YSV|~Uz7ru4ugJQ zLF@k(kMS?r`f2xvB9i|A7Wz|F*DlE6Z#gAR5MBBBtft=Z_fvB@9;%#ji5Z|CN2x&LtjRI*#AWb{8=m38h= zGJzv$qM}+Wt5DN(2W*yg^}0{?tsd9yhB5l5rBgI8KxK1&omA7jypv~lf8YVWxs^FoHlvP~C0$KBXt=9TM0fh&zVS7o+HErams6j`Sutb|@f2oO zmb@#E6~hd@>UA{kw_HAe;y)-A{WW*F$5S|VPvM+{$-_KF% z*0Uc{P!LQxUPP&SI{(4x_})VJJtN)e%v@P-(Z_)6CWXUNw%%WTIHr%>pz{YegW-vX zg3e}X?bo*SzA3LD4UGA#Ie#LoukDJlcgx8zEuryNLF+BV&SL3Kq^5Q668+!O)xkb^ zWaYuYi_zCMu8l ztkokR>aktIM~CXRt;lt3*{uVhus+>$u-!l;RpaQkanaA; z?Xy^)sz8q#ky@}}U=>G*nS?J>9z`Ei;BLXh5m2VUy!)@!9~F({eN}ycHy&-1B?&q>QFh?pQsj*&i*h zI2zhvqyn0!wind|Pu;$f_y?G+JKVvjHKX>dczoVoXEq=hJOTzlGgm=pl}1tUhK)nt zbT8rxsWCE42mG_Za_mgRslLUGg(A5pM8q z-DDC=Wvb7d3-LXpIMx{EeRP+LihQG-Z~{-$Gsq@ej2Z5C9wHAv?1}cPgBX^k*HaB$ zYqhJsgP7HTWcYN~3ObVA?k4RTtV{i|N6XW?_Y~@Y@fU*4ocFdY8)a12?)F*IBdtiy z;*WJ9A4T==)xQCd$G~g1hJ$W>6neeA?dN-(vGl%yZte z9DM0)Bl7NsHx8xOcEsEe%v2LQ9VKiioxOGZImxs35$!6b$ z4fVsNbuJUDKW0vGNhY9RxBDoo8;dQQ*pN;gAvUE8I-S>-MoR^@+(!u&y*%mRf6N%fdZibAC~eJ6U##j9%X zOHDqMFtOG7PW0|v=z8Lj`Tk4slsdXF*Y5}rblTX?=j#tPKUq3mJ_wkoe!!5bj%MVA z4EXGD3+rva`nYerp8l+#X2+pV|EPKMvF*=qBE%v@H(ptV)ge8c_d4(#Hb-MI;f@w< zr*?b7HrK91*)J-?zU3ZAQyE5h!tMWT>wH4?t$`0?`||#%7VL2=)-^Yj7IG4G^vQaV zFPw*;#aN97c777u_w<=!vOHv3_=eUgy>sU+ogS0amD~4}Bb?C^#@>VsGxhS9UnAtT zFn88}&?*ERbu+#9p&2V*BkjSe+~MP%mDaNScNVs6pQ*nL-B=O3^r44U zT_?n0%~kJC-u(7SI!7a?Wc53)eA1WMwVu)3crQNr#=i1iy|nussXMC7_cOP3%DBm{ zmKSE6Rh3cbd8JjmQ3mK@HNQhy-We4c;K^zKQQEC~wEsgfs|}spw5PFQ{By%S34P%F z)cr5LXmlG|ySM?}|Bzhek*jLlU|x3Wv&W$0CFBa!+_DclBSd-4y=}q}p z&ezJ_l9k5U7uA4Y=M8v<=e8FQ?|LiRsPGQ*Aa3{wUg&OZ#tv@Bt~u0;W49dFzAXe+ z-vU3Ac_}E#nJ!k6>t+?wXK)Aaf54b}xSsKtt#~02jVKU|)X>T~tJvM}MVX!oee5~X zY1iC0_UC`7kKbt0(n^wcBw6`$ah@NJ`8SlE_*<2BAJD*jQ!ibDCTx(?>~9D3onwYm z0P$)>npK)j^fl95eRSv4erH!@2OE_<5ogy0aQGe!;B7^9*DCK-oz7fJg=pXtXhHSQ z%WkuOg%lSW7~op3m%yu2@P>C?A!rGbs{bX}27Q%%!oNYuWUw%_7+!wtmumPGK|$;P zqU$XKqKx`>Ux5LJo`E5xJBMzhVMv3aOOTROKtM_9?oNpzL>Q1%P(W!!k&qUVP(q|6 zq{Oqv=Y99y@7d>k@{7!@d(FDn`p0$sRzZcKZUG~k@q?;13%bIgHL@>r%M#gyd4X-^PQURF>i;Z()WG#+Gx*?eDU!-^TtY&fUH89qv}7chXk8#2 zu6vx=^!`_S&V(iO8yp-BiuDD)^%fAvaqL{B=VY|dITqb8^~4tl)Y?HYUVb4>jYA&` zWJuGVyC64x2IRiejG}iDp4P$p{rZK9zAsYEIECtG*P6RIR#u+;NQ}hnap${zdF7{n z7}%r$nk%MeT7e|tQ1Je@2s1_ip^U~@!S7i)L(Q?jpf`4BB)@ZPyLg(__^n9nq_)kE z!sf;b=!CX>IIf3Y_v%N@(T&XWU7s5Xz*T2q#`xs1h!`+WYuHo8S-FsJrC6OB%HH33 zlqFJ%1^O8?Q~%ogdzN2CamB!E8>Nw0cCL3<5fPOg#L~eV`7c42U%@i?&S}6#SuBz@ zo!pF+O$M}_LqO?Z+C|z!z!J34zci03yQ66TD3vg(I}T0oegla|Z8MP9s(xv$UTYi$ zF0*gzS>>g&On;_MM7eotEbc7?Z(N-+&XM7M+)+)`#4TswRCso0!)iOj-B9xgeZ3HI zTs}lg*am%7=}$MMvKqyveSWgT<{ z$HG}SXgDig^9)%+tP9V6F{-eI+=?A2+937D^|RIsl;v!VjVx4lfQRYs%*|!(sGl~Z zIullD-txJSIJew|3{IqCp3ElshsYkXIl;rovg?7&G*8dPUAsE)_B8g8I2Vhwtr#Rx z7H_uEd3#xw^m--QlO6OiE;Dt1pMly+zisn68D5RiLDAdVFxhbWWzYla7gR6t9=Li} zT)m+S3v&3Bl%tlJrGCaTCnC`?HA5+&NvX{qXs%)aqGp11E$P%Ro^Srxt59Wd7R+c# z*9uGF2EFEBJrF5Y-#EbNmzb0uzRm*yb;KihSMYX<%RL|cgpJ}9`F-H-D%u*Joy-%r z(42jYSX~6_kgdEfKJm$}vMq6o>o*Fd#GCq3!`bvEnfgJ4gz5c&(z}`%3XJ;@9j<$8 zN#&Y(58~fg$;NQQFnvV!>jGn~dV)X6@kkU0$~R^GRPDHi57lup@e+AGAx;1z6e3>1 zf0OuQvK#CBW}ck`c7b^yr{F4_qPte&Dfm7(=`$#oyNgD&@*}~gFRoYJ{(Jdngi(_% zzw}Nc;rseWHx$(m;hekeBgX6`ZhgP3wp2+Q2nqBCzPPrcxQ9h`I2Mys5YA`zJ zoAe?)t?o+aN$2u@&)LQMu8eDw%gz9s51np8LyQ+vbnV1G z0joDmo3kbWnQ!A=68ps&J>nMd5Ov$fU-_$X&M8Cg^;c~~O>Lta@3b^Ng9TujAQptH zmQwx|$zc%%p;bv^@Z&46V*Y^}qZMKTq|G}xU!IC8B=x_w0G&Yiy2hCpSbhS!gj`=$ zH52sC-+6KM@aUCtMF`N_2F%{FnMa-~Syk}AanFreYwfZfg00%!T!8HZCPXv>ZXb@~ z_7GUfp8)ct*MGf`qjZX7Y0;%#wmn8_=BN;Hl()hm5Y#MqEw42yzQz;`{|YcJmG+y5 za`PP%|5;t@rNOr&mCZg{rEa@HmImHJ^Af1e)2857{rkG`IsCkHXiL|(41Fw_xCfmX zedsEgQ?r)%{SRf3>F&TkF)`km?Q370^AL}K1#hM!-~edwqe7XPax1HsRhWigDtZbk z+9cdLN7a50jJK%TV|KCg${OdDid(7Do8_s>64c}7t{w@&4(ske11i2{whsOY03AE` zpJMIuqAx3;Q6y&(L$H%IqhEGkyV&RoMH0LSLExfWGOHg;p+Pn$0QLf?B=o}0X zL`(moh&pvOe@B#oh`kaOha~l6Nw}8y5>TYv^BFcd%od6#(0_43%=bBx?v-R?8_%R~ zU?vII?y&6lZMyuqO$SP z2U4tfXPd#7r|W(M25f?P)TH7)83@IgQeAwa|M~-_(2>^SkZJ#KzIW?z2B2D@lJG6w zn7Eo}YI9(Tg!vuSAc;v%OAiDwAi6-^sV~rNvCXg;wx3taZocXvVOEAt z04#-ShAiLf7O>J_e6>wA607hAgj!Lx3T>99Um2K@oI3N?NVhjqk6oE2C~Fo*?l6VY zDm0ftjR^&6Qv3O6zdvWFjJf~3XOKozD)?kCfD&UyRk;rDDiO2mQ5@V;^44zU4IG-9 zPuL2~R1c#Ua)YJI9|LX6E1*+)1uDsHZA3MWJJFxj_NnQmiR`X)T}2*P18+CZu`50G z&R7|A18~BunOFK8IT_gXQRVXwEdER3_0FTkrbekhK3@!MmOTW{R{4TPE$I-a(&`t+ zlb^ZV199Sxc2HGb;y3L8R0GYFTc0yaSr;+|T#a;oS4?x&u71lwNJsT2BAk5AQG^!s zwa<{Ke$L8Opn1B2M+%#`LPsqYbnKxWZgUnG-7jlU`9Z&JNVJdFjr=V6^lpRff>&hc z(71L|lQ@${LwKQrU(M9SfyCnr|Jv7Db&7hudykAIO-aE98&cUEVr(Ud+yY9zGQVa% zN}uv%nFqUX{&vwyrZBR7i3miL2es~2P3oYnn@t6Mw4^O5B;EC}u@)D&9kP_SE{$j6 zwV6$T(`TJTWK-PH(DDt8LGw&oKy}l|U2@sfKc7l25$}&z7b$B(R=qfCXA0;1yr4S3Y$F;thSH+1N>)C62~VNxjO86 z32FYc=Sh~=TrVexW}Q>*YZ_bk!1-fR-k}xxl4&Nz!Jg`%-53&g8xi!>I;c)Z?i`!9 z72|7fnS(3-g(1{RU5_`v;|!t1Tsw(NOu^!-CM$V*ebrKZ^EUDB^?l6dasB};z!!G( z(UDD+6;m((a-3puv_n`WAIh3Iq~ELX%Y*mADIX7kGrTAkL70fY+LYinFsv^*s{A$c z6BYI4!pq7YMy)}juBT$+eI?G83nyvKrL6rMHt~LXJ}Cg!XWVS+HmxabSy}6yHV!^M za30|{p(ptkn9r{+9wv5UhhkV{?-zv(MA9`o7Ev-2v?ml2vy95ElAn)rqzMT+tTv}O zoTEL7(Y#-zWOe1&Q%GObdv+P#cE%Ajq)Cf`&SC+C-XHotbcI!9{0Idiuj!}ioH&Xj+o(mm8EAK07YZZx`Oy2^#$Wkz zqI1PqkIgk*-UA^gRh~)s@L$lPy8eZ^JMSuTwR@I&LFVEH-w9WWT+f+}9r|g3;&!%6 z9LtfsQV*tqe6Sw!ypY|;Y zamh|4R*m)Jjcf!;+Wk8oZT~z-8~YPEQ71v=ACDY)J#(l{0Jx3qFa%V2ohx|r%q8><`EGrj-nT1T{#Tv6NcbnZo*6K z+Fd@ss7t>p+8yNLPx?>>~jlZv!Le zl`iw6#;QJPgYVx-e!DfWAaZi6#Ur-9uUDKan*Qa-XE-WMbsx|x^=sP{^6|H4_RvQW zSWS~Wxpi$@O8c{bD0(&avpH>f5Tm=6nezcVvK*fYt}w-1eE}kt=j?Sid~a2 zQmzzWUIrTH?iS8f2}<2uP_$!F5?HxQ+kbqTuGPu1xAdGxAcp}x3x97T&^ZbX{+3K{ zdrdZ_^aK>7K8t&%c#AtcW_IJV^R~2)=fPeT-*IW@za^n4F52n8>Hfk7QOiBmOTZMgW(dv!2!d*&|v!M@55^MozH< zFQXZtd#q8rVM%fvbLt>|0_rj>Ijn}%tG;_9HmhqSTN}FYwOzRvY`-6-^{uSAlE;lN zbw`e<)AKm$+^N5%e)fCUGdZGtSwl5mXm#2A>u2$EalyMDUqgP^8Ep-5rM4)=Ndp<} zBW$8dY0DMv2=*H~@cWctf~;0?;%$GO#@&Esm8CEOYp(@t$5c>K8_^+?v|E-PeXf#* zs!vG1oG#Y2OdM1LaZ-?grSSejznm5M3%@8~lv)!F{jCVHq+BAXG(Koc65+)n_P^fg zaP+@LxW2bV9#EmL@RcL0=ML2;4&@&{*1_mT@qTlS_nlON(#pSmAMav6eZ017{mhjn zpKtUPAO71=B3gbOm|;^|nmyc6Xsvki^b5NDXKu zV_N&jWHqcCCMCM5#eLSUbE&p5v+MUkHPbm+EtOx43}OfeM~1DGsPwUx5aG-&{a_+$ z=X>3xrnbB{GqxC|O^vU^`!f9oA_^=0Q|xu%;)!h`#gETix%|?MY#19HWug#-b=!6m zE4pwxJ>-)@ zvfWe1UX=|*hQM;#UIM?+-aQ2ul0yfz2q1=b@tiadVW-L)b=B|b&5gZ<5UBCQP5(hd zUk|EVe&uc4YgN+z!KvJMqZcDm&P)7;QI!PxlI}f`iu(J^)whQX`+kEhvM*NZ-w@54 z%8@7tpF=A|!@Ae8-%hwcneIqll%T(_eu?w=P4a{1ZwBb`Db(1d4JTndejeNG2KNmi zc)v`q?ryECsVBkJs&Ru{1#=)2O=$nDGDkw6RQ3`lN>=OhazByv(#aV0AbC@%on8k< zN$il&5S%`)D|4r)mGHM?opbZI(;59>9>0fisT=~~dV_sac7GDjiWZ~$p*M;_g6pm} zO3jhR0}}tH7RHJGm7pF&w*d=(Mf*=WRy>Q*lh*jl-X(B$3W0>6YrI z*rr)nxy_S?AY}_(e6)Se=`>tbz6_#4P|j zH4*pz`u8k$0nVf1d30sPlI$9%UI^L!4@J5~M)fbx41JAc^aVCH7h2$P?sSPlMVh2d zqVT4h0xI3jWgL|<5i|5N4LJ^&f}R*F+tY}`wq|c{YFS+*gB^YgQyFXFO!9SGT^zt9 zdG=~C0)&jW>p|<@?~gm9c-Bo44%iDswq>W~6*4>^fXz^U`_dN^rH>H6e7vopcMo!u z;BKz}!p^#|`i`X8U+bPftW)ZVzpmK4tk|m_@UDqKL|>I89LA8oLmwBiR&^-E*>=NYGX1s9BEbP_O@F8f$u1`d@4kvM5? zb*d1zcEDdyA|Jb+*e5^sG4jWY<(RaiP6~fR1oEw!%A^8@0kYCGy215Lh?-vVW-BX~ zp>c8cy^Y8YY6>f|+pZ4wX29;+^{8P{vo)AgEpivM=suVTPR9zP`nm5yS`*x4$OIDH zXlTu>NcGXiWWo}cnh8I?5}0Tt^f>L6>x~#$MbfbtRb3a)xy2}>)nM{57`9uB=9WzG4X3uOcKDz1imgiya4rX`Nch>G!}Q{tEb9-X(+@+T$fk z3#@Sy@4Y>geio5zy~;RxmZ;Zs<3kUbs7EvckW20gJGxLbfn=Z!u#^1i*Pi3V;1!h} z%C{RVQ5LgIdSdUJN=Yb&15vHPnBPoFV>bTFghDSHfj-P~lVZn&LZB6HELjiU>^tT2 znm39S<(pn0D)?)n=_*FHa$t%k^4F)*Fzj5S#yTm<-C9pMk;2L{Uwn;Thf9CE2Xdz1 zH_^atYxY1}=HLEym?(VLjRhwEgH$&!(z(6c<7Cn<6a&G177eb9 zKX~5Bh^KM-KFt@(;lcOzUN`U*sy1UldkXMPmKwZgMDD2VufxTxg};!l6!cG&X1~yY zNJR2E<`vvdOSjj%w|8xThwi5*!%PER5*RgY69Uyb*2A^pS8iLz%@|(8jfw{AuVf9V zGJHC|j|s52ZhQ{oLv`Z^&)<26dodprjwILWpe4?cil7M8bE;_mX!KwWlgnP zy}a*N0sXCI9XV}}oOL7&&~3Uw9<9-6zZa(208MA;(NL^5E2=C~FpjpIHW-5EG7q8; z63=&lh1%Z7giJti^uEw;^_1f?AyGqV&4jkeHuVQ5cU>j)#g!O4IKg@-4M(b+-N929 z-*tT9nTN3JiDfWR5LU^r)qRXe$9xla(q!fCmLu0wQ-uOy_Q(*?({35&XvP*g_wHk} zY{x&tqCn47bfuzozS2j-E>Mu7_ppdO7aQ&Y)#73$%b(SpAc-^Suc(%S`aaBo z{pWT2N*a&Ic7FMbon*jn>^a5E)prbS!#0mkono(%x|4lP@BZ<{8GH|sE}Dbv;a*LK z8%;A%8NLoDATBun396+phqr-=H9r>7Z!!F6&M7xS*nQ<=Z#K6+I^g)3maq!G$+EJL z%JqUWL*QP2``Ot5YHeaY9twwpIl0LU;Boy7_JmbLBY;`*4QHklXG5DhH;pO^sF$}9 z)u|cwc}H88oe1gI+#uiAm2%-3W8Cu3So#EB5oFTzo?S=`cOl%y9Lc7R=N}5 zvXMI@*NakJ#9=-@CrpKPK_a_=tN&por>2i+n+}@d;)-uPC@WL|q}Mp}22NnBUzc5x zdZp@d9GsIZT?c)3&5#jCwNbUZkrB>~lj=$l2X%%&eMwS&H->?Ow1G}wc=}@&U^O@T1VET&(Ti#S@$lhF3JDoo&*6lnNT?qqb2aE z=yB|ghF*Rem(a{$#mVsPp65raqM>QYnq>xOoB?I#taO|c7@pSfFi%zeFCq!ti=Zah z>b?9*kHbI>oQZ#$uvI`7<_{J{r1Yyiz~B9|Wp5Ut~UeteRTgll~1dEpw&}p!lBm zpA=bnWBd5Datn04rDd`m3GkdsD&J6oK}@US-QV=oa)qU;j#+XGp&vgaovQy=UVe5A z>eW_8(~rJ}%$(JXhyL7rTJi#u0OL8!K>IPu&H-Vr)3=!VwctVLF7pb{Rn^jvwq@j? zq;imBzEh5OU-jNqleW(^>9eOeVrS^1`(69p!DSKZYB zfp4DJz*z*WSqVIXq>YDEobE97t@G4?WK!vLrPU-!W=B%_L=e*L;AZn0*Kiuf(!_t$`C)P0-3?H^}h7d5$g>aMA|?+_PS-RI`Klw*?-&vXB4O zXw@@f-#OhclOBzzd%g4O#SXfHe^v`(sM%<=a1UAmm1U&k(t-bVQbcN|)x&|wo8HF1 zJ7w7psmu0n=7_++pNC8F4e?u?HB*p zXz)5;H*JF|`=~n=r?ys{ra* z53ID4RNdpQaevz=PkkumhDvbdER+)HaniaY-Tg)7&tYc2pxQ@n@cv%V<0J;x)aIN| zPjvso%dC8w8PdF79JHq4?K$m~j6u$;^x96_>OvZa2C`6(6H-HgrxZJ3i^laj4(IPyM1ez2UalnmuOE0->aDt_ z=?GA7E?BzPW#2|sTA*O1lvIs?W&h6JnBjqwq=}3kT^e+Qko9ByzEnawrUu| ze}f9u=rDR$iZkUK82))}fydD>2^}t-`JIE0$T@loq&P-N|1%xN7}bK4^!i&{G&S=2U~`6#`SAatMF91nUMRhmiz;#) z6pUH)J$@Jgh06G}Pl6j@f@0p5zvP8gyapBYX$m#?wKex?Y(8!1b&U<(RzTpfjJeIq zUF|u4f+jozCR#%eG^L%(^@z^dbt zzaa;jbtW%C%<~GDdf=R>_27^<;~ z`Sk^{R6aLQki->bu697`EFo03AW}Hk7}_`21S#?^4#cUp?)ZKD>#*%79JFI>Ip4Y1 z8%TM4fS4rK$}t^f{k1D3*&_t(h11Hbz-sIZcB*2rO&+i3xJsttiYoC0$kTls|J;fKUWVuekw@PvwU~W6Ut}8bCUe-uI&Qk_oDxi z-)pj8K?9P9gSB(_a!%a{L$~lg-ARwZB9#qZdJEnF#_EZ)TwTx~4_`v)LJK9$; z^}ODFrv5&Vv&n4HapR1z-Z+GY^kPzhq`5nZJKZ$p3W*&31c5HukG3&&viy2L;(Pdk zFra4zWpqpBQm__l9~CLjVG5vmt?eWn(J&6N$}TF$%%8$T#tV7i^YS;N$PPfH+Op;R zkM$Aw9<`Zxo=!)7N0Y{Ar5iXVSbqa!;1?+8%m+WzCW*Hjc1gXwbQMT!W@b5RjukCf zn>t$-9K7ZZdZqy!Qo$+UR37Z83xxF6ce2lUvH{+y`hmH76%qSe4cYitn%))F`ne)I zRfYE@k|V^$&1D)`)2D#PNSg~E$2v3&a~IyZ#^|mN1)V4OOjk${7Y`_2Jp%60#&cl0 zP9le_ldFrnPb1xjbVEgv3N|HetBrTm!~m+37zcEmWEl-MZ^HS@eFy=>aGx@RI2<#_ zuk?~V2yiR=6oufd2RH+md$fxe5I3kNY#0qFwl(A6Grs}SaW*)u76@v4yy7M@V^tmc zXM__HIoyA?O?egTpkJ85=~XBK1HyZ1^r^H1FZVyMz3e5U{!OI&9RxQ8k*!Umf-g4{ z^5dBxvQdVGuLsgO3%u2Rdn&5I&b=nlOE^_yBJ>-SJ@Uws95y>?f3r}r4Um%^Wq0rh z$~lX3bNMTp-_hkPW$@@aSs~+6hDCUlHuG7eQDIRVlpM=MAEd{wAb#H|6K~uRdox(Z z5W;~<6Z%*#bOFw8r>EojEcQ{?L^rC)e~{$6WAC)DboWGRO32~^#rtK-+iiW%H*?L- zGXk&Q;*;e?$BE(VI^k>@kuMjk1z+#~C=`Bn6vu_?zTV9Kj9rFMBK&jglE;c$+-SHt zwq-)^=&`n}FH+y8tsU-Q%>P>Wqak84or#b4p=}>E280-Irt}jO=T5*{*?x;}HVgWH zyEqg9m!7vnpnmRPnYkh21;V>L78Xt-d-(t)7W!^)CSQskb;5KQ@oY@JvOj&BCleLz zyE3eoB{hGP%4f)JX#7`1cR8+t^#KJB3dCh4R?biSlA!Psf~$c`;lw}Rv|(1ddYv?p z6c!fdcI@Kj`B0f+nR}LMh7dcByU_QOpjbw+Ef&wY7}i$Gbib`T1W;b8sMeR1&jDJ~ z{vDBH6mJbTb?LR+Yw<_RG4C0?9qjj)11(?P-#!C^l12(x7m!AcH+@?<1giFpQN`X^ zD%q9j>}sd?Ih-hgiySGZV>r|@(UC{*5wH@hEj|C)>?>>Uf83%2S4(y5utP7e^=TB} zaUX(QHIDA;#n_02@-!Xb(5_ZOV{6t;ofiSB?P zp!YVdbGRK66s8P;I<<~aXO)o))-jgX8$;oP!@+ncq^v5gaomIoREW+wLmD-pjrH)) znqiMPWNig@BrOtFLSKU)emX?>W?^Zojw!}>=6VJH?F;E3a(vx%ObmXKeu6*CigBAf zjzH+wC=HPv42jLw24Sr0cJ5()TU&m#zPFsyGCvmOSib+O(j0SWs#(FW^i$dg4>Iv8 zUn8dBt>WRB#$5{z9R_!j656wyiTNV9KlXk8>T)hx{||%HcPJL6EN0WFxmlM0V*8)j zAvue@Nd*?N2Of3W)2-u=<88{^hLpMVGt_Glyp_Kcb@BT;bbm!($?wb(DQnnHxwhjX zUf`H~_XbYO9CyEFZoa@W^}qi1-5II$O%=g+nR}`uA_=L6Nm+q*ig$QU)vs{kXmRf& zDlg~2ndk9@NM~gTC`;oJPOd7`o0wQ@-dvt$J=Zsm4_z56XTQD6`~nO!9#<2&iIxU( zjOqW;{hZ!TT*h+KSi+pta9gOh`%!`gUti$Q89sAVdVU@p(^qdUi;K`NV zb(O*ZK=wRrEme~}Rn|w?DG=)N#+X=uGbZkFIEWW+cuKmi8N=j$HuPfaE#}3wK=7So zJLmlDg3_LEN<+kIE8XuNFngKt-4gJ$amC^{gguu>pC zNUSY%yZSJIM5Bq7nqv$G!4aopnCl%RW3C80+XQa%Sj0=b5Xm+sb{_}3sE5hkCu&@5 z)pBgp9e^^FY)9ss=$-R4>l?M$gDA7`8aREoEZ-qQFqBwEh!*Iv#E@ULzZn9V`fn}3 zjau*t82KTgb7Y+`gVOW=F>}MpR!-R_3xKz9uU_)&ki5T%Z^l>Pb6fzdQ@h*WdFE70 z^A=P3-4e)>c_)G38Qu7l`*G2K;#h8Aa~2^%xI2??=U%+A{-E;rVh4!&U-TpuBXIoW zoiGAQuQn}PP(<0H&~o?&^uEnCGQV+Hk9{deyYFfdXO{rZXzJPlC>y5c&4{wMTuOYQ zU~e#t5!kd&$7C#hdiPyjm8$&#ht-o+w>RHP5QH;hnVf>GM!f@M`@9f)9KQD$-ghF611#c?faUOM2=K9uwgYPWI8Gixw-AD(el<#k z3|OiO!4Csg;`tT;@^>9-yeGM2fWjh5p%m&V&bRL95x6c6KfTDwUGOP#CXs_W8ui@BG5&}tZ6Nw@4+H8jZnAq6}Ug&;_9a?{otXA>tC@4L}nwkwcxcN`~~!U zH2JdRvfm}!UFN&UHO&nH()i&VQ-{SN#x-`$T%D3BLF>Sv{*jCVaA}ORL3AE zo4Jh(d~txWnmL%@Fy0=sKhDd#l)H{kwGZr4?JAf1sf`B#^wjs2ptoWvSr(W)JM4~f z22xnuLyhh)0j})>(7ax@rlZwief0o2gSQ#(2pP0=DU0?<`uOD9YtYPR444P1r-e8; zSJI)k;*PfOcZL7NNUf+j5RN88$9bdYZ{cE88orxS611{+IWAn1SSm#;saArTX?Y z#vrH)aC72Hxmu7{k9P0(#i-uKN*~U0hF#;2B&K?(%^FaFBljSynaoD0^^tav1n)*E zH5+zKT;CoC1HZSUeqh(W5`HUH#?q7>z>Xz^5P^4CB8pV+;IHp8Mtk5$+Kl5Q(9p$PH!s#1!p*u0iJ4)fu@y;hPm1&7U`#5Rs9=&D- z6olL1qebSG9WW{s5}_d6{6S*vlGN-+3fI-{#s*e9UBC+MXz%lSSN0jW)~&P?I?jhv ziBI2JMk&KGKqCCn>)O$z(QS|-eBh*&t$H)fe*rjXL$ra~c8MS!x=RM)AsT_ zC&R=C2&feAd?U_f^43%eI`#$f%VH}4b|n3%ecfm;e0QBmDX_)DRpj+giA3F=?=O2u zg+5f?;>b`-qKwc_ofRCSHRZ%w0Cu`nXT?xvG7d;i*YVNM4#jns6oZhh8k8Y@6Jwqb zF&h!CgD&2wkuDYTB=vZ>7}z8NKw2TuO_e3bKvVgRB=^id0h*<}g>7CaRf}90*JitS zpVK~aD5~cdp0__p^N{|GLeQ`2ixll;evohR<{U_w;6Z|dJj`-$ER+1(j7BhZuW%fi z9{#v-j=~>+-z4otHlqCjjS%RO*4`que=-elG{0vZQb(E%U~~&^<}K_VI{wI^tKMp9 zoxlk&fmJDrJWo2Qk!!*m$ED}YJkEJ+U_o6UlXd`JrG7q274;kcq9^oh#4`{;?-Zh3 zHP-N|Cf%rqV4hG%#S*`|>m}%p7=zVv3nZz|zj3Pkri~p1%fo)n zY=Z89-%cXRmVTL7H_V2Wdz(#*RV*XruLgLz{=P1opWXwa(`MDXid22aX_q3;*uqJJLNg7oUKI7C_Cn7`#q9zGj(t=pFD+Fl z`v&z-d?p0mVcv=|^W|BKSK9X+uH1NSZMLuuWP%}I_8}61A&h78n-w-<1n1rt>q$=> zBX8BzD}(qhWl3`vnYAJk0s4WMh^u1$pC zMnERQlSZxP%qVOa1PS(*^=j7YVK6A<*_j2^%TavAcVT!`!28r(>d&NBf=B^R`~Bx{ z^)OMu32P&KTOzxLyJ|p8xb@dPf7_=aT*-gRHWM-MF-AHH6BD+)V`TuawhvNEVxbom zMTFcR{^Bs49wy<>c6*BPsdV_Fl8&yZ=x}f0jjPWX@@zA?K0C`@4L(+R^Bxpfx|nzrRdLl%CE>`tA`zFLbCiOc5Qr3>V=XHYjpT>>k`{r@gsp?gfjc%+o__B>x%9tuL z3k1wR$nohxlfDOGox2%%`nP`ur0Sh(&6{_=4`8KJ*VzTP%NTxirDn2n&tu4HXXW1x z0j0pLZKI-Jtpz~v#70JuqYNdW@)&|s-NU;0F0A=PQC|Q;@-r@4Rtv0TnxOrM4%GWl zZBj8GRmu*7f|3@iAvia&J}DK?5RGZO`oWSV#gG3`!R)^GJ|V`#UBhEx4!cY|BBSRf z!M9=8HUHAkv$VsrMDw0P+{s+AQ6^ga&Sjf}uF(KWdxS2^*9NIlagEDy>ki%u#|0=+ zSZRF#no_s?Yu1uI`)RkVBR25tcoGM!b`n01jB8hha0#P+KX{TzNH64K%;?{~hIF#7 zvlG}b8Etpn1;mFRbNWX%y23L8E8#yK5;ll6@uXQ9(^#WoWuu5NG<1f3ry}OhavX+M z$}@yb;SeEGZzaXOXUt@F-4PK%6oye#Rbz^238goabT6oKc!&DH@o=v~0NF>WcG0l~ ze-LF7AISS*Ff@LD`EDd&p}@s2OaC^xsrz-ow&v}j z3~6lkZgB@{UYX-x3P@W%+-MO0zrkN{`j{X<=cI{rim6J0{$qZHUtT{Np_z_f<>1Of zhyCBcFX~3mK2^10FEspC6k)8$GIQz?ucB?41BWx@=0PdSYuzrI>pp2NS4aUnV112e zQR`o&arCM+g)nlYG)7dX9JgF_}%AUac_Xy z-771m`QMn2B1!SAnHvX3lYR3>AZYw^MjGd=XWL4gi&=zD(-rgOky_9D@3=`Bn+ zj_eyJ^XRwOp8rMo(knQRzT=OKb6m3v*DqvVuID)>dn9`QYllvOdmep~o7(8VpH28@ z6SIxOyh>6FNAC?(nv96z0=lgp1DT->pRSmnX{uOF`ax5OHy>k zWz0qvpRNzZL6lMJRsn9qt~qAO`Lv~f9-D47>t?zwb*$eoO(&u^Ecy@q<<_Pjl#!_E zaLX+NjiBKuPG*o;S^UN8inUu5t04^ev`7ptPiT1mz&{z6nm{dX)G{Y&mobNpA}V+h zpPKZ+)AQ8r(2jDI&o*;z|q$mvL(N1uWSAN_bd`y)o5xhc5o{9e9?`5nu@8AgG^ZWu1HOyftVV%tr*9fOfysb`@2ZmX_9B0 zX={(=0lB!&gP=7}GluaE1^E91?sbxx;Q!#Zp~D2woq*|pM;$_O%R!%=_9a7BO;=(> zkIgN8(}r(_ly&G^o)Zd`Bl`J=x40px$;yRfSIQ1Hv0_3MMn+9q)G zHJ_BP2_BZn&ly0#UP=E?2pAjgniy=8q*Axbu9^(B+Dk{K@j!yIDHOnw{(LjZf(gCq zdJMg%3eBiAlonQRkT_YZ23_F?pmzI`5#^3;jG1D$1jja~mCQdPPf}`h?%0Iv@1XqS`{(@kqme?{N1(dw z2a=pllc1_8;(CFCiU%SUku`%bUbornPZXvCqsPTw07mJwJ%m#|+hr~Mj+cnTCs@v< zM;evoV}JGUAx{)~f8nZxF17@KAM7-dv}_6G0|A%*mGVB#|#FO z!<4F8ZmiwZg8%;^z9wBsk%1i1jMSRKSDUgnlC`c6}r!y6gLsV3QVxrHcS|JtEzBBNs zM#qXu$w2b7Sy=a()Z+sl0c_^`h<_ukM!v66(?_uRQ4Z2r;TWcHt1@s#3IbP4tOqu@k_^GS1k#>N>nJK4Yv6=`x&7qbIT+Z}S65_Z_86My{e!eO-Z!K8Eb# zlCKJ;HeTeHp&ExSKLeKK_2!5v#$|WR(=przlML}(X~$Fq5#Y)jNPHpTh(RapX)^%Y zTXn#{#X1E0ISj!eF$Wxshs7AC5Oc5SeX58k$lsm0=BLs={ch1-nXyS~#UfXN}_i5Nyx7e0eTw<#_xESR0JJRtv_*5>XH7*IbMPrf`Lr*mY~qG4j_Ai};{aBeeO=4Au- zh5XEm)`9;PMSfclZ5xDNn*$o(*N`2R4n;c(=f{E_&2*JI0_UY!0e{+oqNB80oLU>V zd7nh!N<*@`_VI1q-Ul2xu}qY$k3q6ZNtUxVu;uCYk17^P8(-)HiepKdfA&*DrT!1F zm<0ffmC*iAuvjhV${j3OZ_KJ67#%<}V#q+Bthl*7UVQ#;A-LP@3SMLud>4X_Ah&-O zQR;;LKPD}*BF+(Nzs63*tz>|~SC_QwiHe9KB7+ZVgt3$SyDAI%II#u2uM3UVL3@!S z-z|`_`Y+){UQXzXN*lHU(e#us;f{Ngye%l%a?xE-a%gei?Ym7-|IjzmcR!>5NX-~< zY6Y4foVv3MO}(aR*QV{^NkOD%4|}rZ%IDYgS*d57#7YMM$4YA-`4BZlT!1Sui=K(z zIQvc=Zg@W}`_-MrpX}5XjZf3PP2#sIlCJDX$FX~sTVyN#%*ER0(st@u^s);uD*877 zsj%_w8={Y&_Vt2RhZ?K10BI&C>j^hYDgAj#!gt452{Unrv~W__@U-Oz17|dJSfqKv zm@I#EeYl(^)}jxev+o%GS4Yu)k5Mszb2&1%N!8sFP+A;}k1f>6V4NzT*o({XBFS^wSBc!s@Xe z>zg*dPq3-P+NB|ufAlM@IjpoPTbr7vuv7HI7?FH!=^SJ>43VSGz)?EMP!!wh0>lw( zl!ISTrfzA>cJeVD5Wnvo>N86Ar_y&651A z_d@uU3+xAhBNMOpL4!ex^)yo;pLU z`m5GL4zLJ6Mo*O2!1%utS(vD9*e9r~o>%hcNrV^(xHEiI?!6aHmSE0ke~15r9^lam zaCjAjIWBzVrX9OW+?~<;_it#BGrp%$`{h2LlMV+7Dq1Jw*G#geD|_WqE2(xM9Vxrgsb$J=* zFn0HRr}Oc7K*{fbSqXIryaFK}ZP4>H#en(QbU076Q8jbS9S_atgO)TwXGsJUMasR5 zDBnP=wzS)%mzC%KK-zW0>7ba`k}CbP#m{$FTQ&W1{LaYf5R~yt9?3p(gzG+7-6)PQ z9`s2wMPk~B0@OZy>(By*FwtIu{Q5Hh4OZpA!r1UGMCC&0G)Z15hnBS1MC6rSOs9`9 z6VW~$;({5o_gqj@IB(5iBiXf(Xaoc`1(ypiU1SKZHU+!Mu3L^`$mh}lRn9A-(>S{(FoNvV9l|z^z#7!eAFCu zZ34!xYvYk`R6WA!@jmape5(?!+(@Cu@tEY2;e@%NRW(iS>{fRN>+?&^Be)~AvyrI6 zL*8Wy2@BD1QA?9NTD%cE(-Te~pRSp3O|)ZLZN<$fx}K<@c!tE?h&M`qlhXFG<6g)K zP?J;I_3uJc?!Ejn9p8Wxc>PI^ctbE~O4j-i%I92qy;j_rM-jllQ zvcHO!f2*>=A{q(*k}#XVZ?r^zz2a@@WpJY}+k6Wf}DOHQEOcApjX?KciRQ3Ei zHMee4*NwYSmP?o9r|^E=QpNCp%KsE1&y)6_2T>RzVBXU6D541E_2*Qfc~(FyXrJvgHPgAa#A8(HshPm@{OZ%|Lz=g+Fsy7#q`}G~ zW~NSsO@hCCJ8`*=ba?7NGmW=YXVWz4gy>8K2UwopQNt+R%)3*kKFNX6;bvlr`Z!8m zi|#o4^ei>lqo}8wBPVX@S(fpPzM$V`!3AuLc`Y`mthHd*j~#97BBcJu8)6vZ!2RB1 z*TSKJm*+iXbl-~eW1!kc&@5cR^abKgHQ=XvWR!f<)XNHBO{Ae?n(rN69lbl6ZW2+C zlK@ppei;9ZgW*}&!mh+gkUqVAcD%g>i4P@@8e6Xx(Z16ep`%{i_#|78Wg&K!D|Z}p z6&$&fovt_jsT8@n;@`csr^`u8lGEsjq?sCxFV;K)G$MG4=Er`8sLD9u5o4N>s#i9L z$AZ@QY9nPu6@QCXe=UsxAT52%K2QqEJg6f?M_3Z)AEPk*Mh{+zK85_}y%?O2Kt*ZB zy_4u()$VIF6m?Lt(lB?Co6x%o>@%MgR?D6s4-|WP+(qdq)kgO2{klkkk(>}Ue(B3$ z>50J}Adu*en1E7$t=Z`W6{ryMT^dFC#&CRzykot#H6+3P1dyfSaUh#tFa`3riL zuT^M#qC>^>1|-mbpu?I+`;P{8P7#%YQ5W}|nrt4t3Ns0qheQQi)K>X3-OO zsV*z9qqAalO*8v7*yE^lm>)Ox?S{G_6|GPZ@)D#RU8YpNJ) zuYs{@^j$I4vM1kniaAj^`MBTZ_Ngk_>bJ0`;Ozce>M#))1$=RGNyQb2gy#!qSfuqmzpg+z+!zzO4qr8BQ#k4EJ_3>Z!*Q!{A2#6+d(-Sq? zL~O+V7%EaV@Y!%`3k77lFK0*2ZF~k?bKg#xqPJZ*t()(5QWxG9a0UPr|+W&rf z1GY2)*}SEmtCDxysDzMm(7a$;tOC#@`Dia0DW!u>?OOR4bqmo`h9Kj4ayLpi0jN4Z zKL}Y(Br?qwG^vsMs-*4#vtT3>BPQF<-z*AiK>1>C}vOP#&b7WacDlXtGy2N&qhsxU}uo3k7fqo$}UZausd_H+&7;j|GOT4f=pQ_^7@L0`a{!=>f(Q( z%$M=Q!W_t+7(I{UipKF{#u3hA1 zv}WpcGXG@PVtNX|9n`4h&|Oyu2Rm$%*by32BSNIAy2W!PE})*XT3(aDMG z`y*b(18&hJT&9A%hxa-H2UA$Kf-`^+;k&`|(|4Uv&UlRC8}G?r?|+Xg=i-`WDY|S+ zaPqq0N#Da;GSS;CMY-`>qpqW~UWh(I&{KM?PYG=$>c$sE|a>#&M&TzKSHN2eX z7&+7_=kte|)I;kUDYCp(ce_};3rGj={(9_V}#%9vG=)k0P_Uu*5WD-%IWE%EZjJ+g`~h~sYe zy;LDpMp)mH3&-8I)6(gCrlv=eLLL{0J=r``}j|n8*;3ZxxNHOwjem>=Ud&Kaaz{JDsX6cZcKSe;GYH$?F-Y`;-$P> z^&NUg#Y{eT?i^a2=@Q3TL_cT6XDGcN1%rTVH}zqdI0Y#E5~}++k+VqZ|7q_%o1*Hv zu2DhI22{FkW}0*PJ0&M-UZ~Kg!?xpDTL)qj z&V$CcR9yLdU=idRb2M@0#LJjIw?AfL_xX;i_!pfFN?9Acd#>!Z5ml3(kLz75tKakg zZC>=vtNv!u2fn60f1b0$IKFm0*^cJpkV^Eo8!ePmQ>#+>cS)n9RUXvLN?_wA1I3}P z(h2H_9K7|xVns?R1TdVwYYsTP?sysJJnmH zMRq;#;@iF$Bds_o(QZQG{H8dcOe57snFT3}a?f>KBumg9P_Dz%aK)tGenmd@nN9nA zJ&wPV(WfjqL9w3A-N-of?A32l(T%>rE+WDl&&P)~!|8F-;xx?UoXu`SSYFoiftwUf zP?So|=e0)&{d<0&`{gCQ3nYU(A;0*8T|}?+jD2EYG30Zl5=niePPg#IgpG_y`CVO_ z;iH-B>%?~Ne%1SAMA;7~NkV>I(cRA&GMUch4G-jccb}9uRtz7M7{a0;R=XBRt9YRN z8PVbx2s?qr4;7e?Q_z%m7x5IAwS}Eho;%JNt{xRIuXJPmY0*KN4rUX;&=JIc{+TpG z!&&Ww*rQRik-vj!rDsKLeW?Q4EAF^bT_x~;oy+MY=D3-}BoWiQiZYGwLJmy@)%UMQn-uW8=pP_D%p>`ArA zKbO0vi(5yPwX)cQZwoXxrMM=gi0e{ZCSloJU;1E^tII-$BI{^kP?+2>=Lz4CKk9f{ zlqBVGSWzd#H6MnQoDKoi4fW{|t75{p<(<2^f{L>a#+VJ*qfTneJGi)e@lS}Nh$G7At+Z_Ak5g*1^errdyfA_W9_{En!!x>Y z7E!kLyd2X@FcCXuLF;>1|w1yLIzc+YVB?lSOVaRKNCR9=yFg znnP!rcKGl%BDlS%r!pC&q4c=1n7e`x?RTSGcoyFthDseCKS|BVwM#RQ6mm6ZKh#d= zj>KMe$sD>r#a$4s=ALII*u&)?oZw~GRR~&;C%FwYJ{$|>IVlpKHEQI->6Ph z5qI)BE2#0p@?nHKd0B)d-czkN>;{w6d#*klIjYJ}Qy7LmCfLL6@5-5_^oOSD2kCVB z@jT5+6vvJAfZ2zgTl|)!zkE7{G064#xr9X#wXxz?v$j+sdS7>rPu-&{L>E`&g$}(a zH_h8F_LRKw5&a_~lZ%v#gLIe%Vw0p-tKDZvv@J2YKcM?Q88hcdkC6eN?lR+hns!fm z44MSwkb)uv{_}N8=vaQrK*Hk3Gb9gC z(mC2pQ8$z@cLzxf%woyFO>&NAk|tKS9!oBRTTDO&#lv^DL^8uO6CD}GL;V^-8HMv38~T1uEp=*OVIS+S>9deLVJydvplImj`L|bCMeX4>S}*M~)u2KZ3n*aDzARc~3^)R>$WeL*VgB&; z36d}_5ef_n1I5?ooYAT-~5LS#zOC*Nv zf8{M*C-;M2>eYnti4GXU#Afo}bLO`EwL7`zsQ06w=uG_bD`xbj)Ik|u)8M`Ha4#a;@Xv>D6C40*#zEVB3ykreO-#PO zrMHXtP5J%#WGR_*7l@=@pf5HG-hC;$zH@FpU=QHRm+BGE3i4wb$wEuj=WW}FNcA94 zQXN#sA3*|%WfYDaUXOQa_v`Xh#p}8)e}Y8I{9pZI8yw=72s6fw`J(CIlHDf0Famk_ z!Z674!^9~r?XJ5sZ!HdG4nf)2*USJHQyX5*iap)w*oPf`R8m9}xe}bn(&+0)FAVl) z*bj@YN{#m;6213UkV>EQM}Obdfn%3pmNx4y82hB2HmUV4mdi}c&a!XB4Ey#k5HVKA^+wD_=rI6V`A=VS*B%`3g=V+R_JPb!UytOC}*j)N$-^ZeJ> zt9B!@)1lnUkEs=kz)*6`I0ezJVk3rL#1cWR&z@T~vgrGleh}Y2-WJ^2;6A%-6pi%!=G_CQTv#<#r<>ZGG5rN*oZ!EydpP0?#HfC}$TmpBgOtlr0lIVd5Xgy)YN-DZ+>z6m8@ z&kS<(I|}OmIwCbzF5oKc)q`WKs#=Q>{=S6h&4XCfX^dh~WYhiDaC+^QRA6f}M;&fY z`rV5}80~GI;4U+I`S4G7?^5S|b62N-J5mtL!L$7!F_?Syk+tii^&bKkg1$cHlhEQ1 zt^EEt-u5qJjHQ*H@6Wgdn&#{uDtDvO6I9D`h}o-GpH6&Gsqk7E*#g@=;@+QMsa7%w zd(-Rm^ji=J8wAO_?LJEc395mT$&{UMBr*I8J#X5NB^@tlr|GG==bC)p_DM}0By3k- z1LyOoLzy=i6Q+KBT?e$`7K%6U)COP=u!6fTMkplv?3}u9R8Jy=)Z!HhFc9I(D5zc( zbONM>)(|`vJp!$I2smxwolh`3nYU%JmbF_ua>_Bgg4YYoOz4}BTdT`C%XB46b%)XX z^}pjhTE23OFprdh2BLGBPZU>|fm7Cbq#E#q7OQj7Am@Xk@?!IjN(-Mk`rWAz_7v|u z=;ajY8HEG*eGnUK$8h2<@5ue4n1pPN-y5HHQiSTpmvX!QkNr|#R*XURwb#F^ODx0) z71>XaJ%9riza!SF`8nGS2dyriKAD#7ta-mgJ06DWf(o*X-Nd%!e5;t&QUl>vw3p)3 z{CFE|LJHWA-X3*E*z92KGQ1`+t%M{RMuFG4Le?SkBgOX9GqHO~C(1hz!`17q;`sND z1A-25ir#p!(Yu#I-<5)AW7o9G6iEz+@zhEm^*j`Hk8s!G=^zl2={gWWO2!zspiU|oxYqw?_NzX-nzH_IK53-PbhU$i? zAaK#zOfh-^#`mR$h*1dhowkz4p~_>|=D7{I7K6_`+=FS7s`&cc0aCurB;j}iDjZ6g z-!xofx4AW3VyDdl^XXvKuEqJ8sJYq0qQ$}d(PPTdPUu*q+Mu+&hrKOeZWSqFOsXoe z(5d$SO+X?V9!?H?##~%%qd9NaKnl~F_jwI=y&~re<2|sLZH{WRWx_*E?KkH4j6P&s za0k&K>EiRCJzZf?_Nz;-#zmlfK(t}cefw1#Q$Tujg?T?D`Flfr#PPEdk)h3$1{Jr> ze^f>)Hf{u5xIk`Qi97}vL8T^ zkXj?LO?C#)(dc4_Div?>q0fHCg?#3U_wmRk84m$u?}obiw|U>oqT>^qt(sWeLO54L zS?HTT-Khgy3z&!H_q>TV)`)zR`D9_us_b^GUGj-THnvquzx^`WtBA*3>3mUH@Mh5Q zOM%C!S`o|LCL%__NP?)K?7?}%+lrf~NE@+Lz5OY~B@+$}-TTqJL9#ynePS&X3^a>t zEjnQRnA&RlF_v@nXPUR|Zn#1b`JC7o<4;+vMeP<+%G!cf4suI{q`EemOP$zjvlJtV z;cyP=i6J)EId7iV7Irb3DeC9QI}MIr`^%6s78zGi5oU#Qh^~szp`!1NPgX9BD5c!5 zR|n@+&%6E&41p&i&P<gOZBG|=R4b2;k9ZhB1`{S(%xuH(lsjb))H^5jsAKM&0!X2eVljBXIwnh%dr zF_>!qCg}lNY_al=;VR9rxxI4K3E+DFo$Pp}3r z=ZQNpJ3Nyl8lFWA@KV-nt{IqU0Ra@98f6)`!G(ve{ z?nz*t`A?>Ya_?}*Ov>=;QYW==axwJ87DTzk+&9he=$483A|_9m{P~KeA@iaQduG2P z1LOL&wy-n!505WJlE(!+Z|>8LI>|r`hT0|*MLpxw6+UI09OwRb0SBoaayJpz;_B;f*9}{$J-q33$p1%2 zLqkFvUtMXR;GAr(SMpGGxYmX|`Hp>rM=t-!Qir*!qH1&lqYXulpVEL{Xk-!e6Va^4j3?eK-|UptG<;pLqe*@N_dk&eiT2d#$Z(Mb<+R3Y(5$T>qknmgM$# zLcV^Bvd?cBJoCHXV)UX)15Y(gt5qQYuS8BT+k1Sh`%b)p^VKxgvxy!y)R}<;5sy~P zeP=A0jgyZZMmVQvvYOF~`N|ECY2cL7#3@P0Dc*(}1akx;p%_($x`%^!vmb=X zKHB`NQ8McNVje?>3rWuv$PDWobJT3^?GI{aG5>}-W-zfBeu>kCLMDbtK<1P^EKW- zW`TiV)c$EA`dTQTb12VM*=PucyD2hkqh;DM%Q>oq7tW)3A&L|FHKAWp_v;+r%CRt` z4htQ$`o`;Zsot9$y*K+T)eV%*IBACO?_?CCRUY1RcYAca=I&Z1SoGE7J(<5|S`YT` zjoRx=u6<0+8`wH5y^}H02z)OZDPOr4i+UK`rRCy;Yqg)(P?;sGS9wQ$m&>VTs??JM zf`cP}&Tck$Dr=t7wdM#yAETE49ZSoX_SGtKUA#x{@}~ET6%Bdizb6+X`NGw6F@++! z_c?^?L~y#PR%KjSEaVYPJw?TDIf)QC=$l+7WPyho1rA?(z)3cShDzG>$)^xzCHTI7(P4&!R0D-;3H**aO_=|oTi z9;)M3TPR1JP~3UAgZPh3iP?TjLxnM;F<`~sY8P(wYg=qW`hv-&YK?zS0cpNQ2G*)^ zHvUKi)!~UEb!(yg?fOmKF4s1Bs-%7Udsh$JKIVQ;e0VR%dWdC&BU7QJCNw|Odw8_? zd8{{GT&eqciO#vaf`A>pdh@LFL(T2CGHZr4MhHD_jv(7*_o2M zx+g|L6Y$x*wzvMTby>bq)!<;BxkIucvBlB3{>4BczT@R!fun&|`G9^2pMN2psfpl! z;FTu0o-*y7BV9lW>|>p0ObmpPZ+3q_2-wy+c#E>n`CTErW6jN>g(uoy*%xtyEfOcc z&r}Orc{H?l?sQQOV*m%dBG=IKM4+|CCrF&Yh2_A)|CKKqFXq5U=V7)4-|p<6vH>_v z|8r?!F#sg9FJW^ppvZlMLB+x=|8oY3$Rgf?M8@&x05sBoo*VCSp#iU9VW+DW&}c*mucD z8+f1-__MC2iW*r98*{7Mi9*+rbl><-MA$=FoT&t9G8v$u{N8VK@MNUCUmN`Vm}Nb(^Nma2 zzMs%c6qKRr0a7~4P1Bq!$hsB&za7X%33^tJLj^8Cwh~=&o$E|=S?J9yp$WD*HlP9H zxd^%SPgmZhoXFm%(CI-E(0(UPHl$(R&;3s|L6qkop!W+mV9bd$W;9V#T zih?8$m!et&Ld0`gbn!BJQh*CKBk;D_ugnRC^YE`(Y4>xYSmg}svAEh(7d_zT0M+F0 zWHlW~;U)$3q#z{v1?t&UY~ z0iZT&8zXNY!6;Ua6bKuC*8le;Zo*wE(HcCI;k*Nt+rtPO^YO8hB}Y$5bMU!j_crsb z!Fg92-w#G=6;av$4`iM)

EC!W_-DY^aZ7k`P?`YhW!+k@9eB7_n;_hN@-8E|Tma z=reMFzOy;9aH$)pqN~lA-$=FbHLTT9QqUbq+J}W&5{S%k|JD~pxI6MdeBx~2kx_0$ zMW_y#;#Jueo~r(ezlhopt0c)0yB1fx!o*qr&2CO--lh!gWCG`XRvAF1FgYpt%ovBMBSv}Xmdh3hPY z62%2i?&uy62X;V&-fzON4OKLR;a<|5m3&vp3P3-@y8E8HAb#(TuUm}d2!PNGq7ST8g09n!V!WhCCgUXACGW>h_eO5aT)25Rr0j^d}M6l+TXnU2wSO zlB6bIb^3bkrY@T;o*8bw2btCReyi2eI@Hh1Xj7+Ph3J!?Hz$A(SH9OpJ(U40?m zIss*@$k@$;RYG<7<>>92{C*~EEq8Y{)&~EmUAG@RJAI)ndl_KrJ3jp%^9{-z4VY!z zGvNL`+a%dK>@T4!R>>w$dJq3BB+ z>Tf3duhvT*AokD&-61UQp@>Hla@MQd=A&_iDLZU+3Hw(&%MvQm0%{J@5BIW`Al2C+ z7UFGI?eR`4%MCPjOc4v35siz67Bd+f8fFVpGYufYWp;6ccyNDDUWm;tTeNmfSt{h* zW0_43$ETZp4bOSQm46Kys^MO}f_;Ym_isAaAJg))3V&v4w__2J%N0;yKp@#FTD27Y z88R9}F7cdSMRVTe6*#YE3O*wMIm~JBY&)Th7O>c*jXL^n4qP{<#4IXiuc3cJS#}Kr z$wljCvh7mPT3D@z^>q}%jE2|@1s|n(^lID|qVB=5N{4Zy>i0IZ?ujoVLK^}C>ZZ+; zP+-JR!MY8=vYe1%?JjK?A()D>ja4USe`9eR6v$K0ZN#M0`h{u+eZ{D;Ohs3V8JDye zPonk0+B6AnP_X1si8H;{7*NID}@PNh+#C1|cgQUV90#c>z3vRWksJg?0-PFdQ zd$o_aQh36{w|^;dGX|I;D<-}1Kr(#*c5=^WZAK+1_$`1ePZSj&tR0buLh6<0w$W}3 zRKlmy_>~(uUO@#>Y17u3Kcz*KaVilml0jM#3?eDyD9#}M#`r!Em_3QbgE{I-z;QO> z%?Ch(4_RslRt!)U4Ccax3htb049x^|d;(D#FnxbBZtCbS0NWG)D&vip_rtK5%~s}r z_Z=m5fM}0wZX&gWfISYwI_3(B1qLr{H}kx~$0)L9$dYE05&s^5&MGeuk^M5E3VUhTEw2n9d|v^XO=;&hYp2g%a})FLpx8JdWanf{$yV$a85K_=Odm>%i0C zGesU^m*EnDZwG6u)FKLAms`Qhl`;WwQd0^xk&Ti`>k!s3&} zm8ZSK{HLOOk8cFQ;>w%Ribi4RYdc&(12OFUka}7c?jVo$PFDJ(>bo56z1YcN8%++z)@ge&mkY4ti9A|Ly z+BX6ko9;a`_j0Sh(EnkJahf-dUpaEhPsQ7xUdXU=>1M>rh4MADzBJ9un;@%ivVTL< zzd*Lb6;z20nsyPHz1Tpihp)DX2GgjQ#PyH?wv_}v*nc)M^2>G4 z#;Vi#3^EEUON-8AM6y#hv0<3fGPwqs0&PVH&+NsmscCE#wJHY$2jz1=@CV$U?*-8o z2S>o2^VVlvEtN{!-?R84`EdO<*QD zqj59sF%^)i>yS||m3T69-`Exk_i~uIhuqlr+jTq{TIyLdm=zT4D zW}kyVLzxFeor*Nj@g{5#4NzAFrX&TfBn)abX-CPPC4G%-KRFA6Xc?^mky7=1F>+2qd)K$|jmN-;%Hff*=fD?&-bY+Upv{6({f_*sh;EFE){tY}&67xstOVVH3eVxb1MibZU+krKti#^FFCmTL zmx3>wdt!1jQw6%;51E(qM+;4`3xn9A&;_GldbNitS1*#9xw)0}zVVfbNJ(8C;_lOb#*21Tg=H_M$)ezPRV^n z%H<-;=;T3X#|zXbM-~Ti^C3#{f}AaK8lo+Ks!qqt)Qw1OH3fzaO*98ntswhNX_suS z$7hf_ErDDyahxgyae#~Ri4Z9-0%-lyO9>}?&=4&~0@Cr6q@xfH#Y5|b8hKu!zjW&g{gA!hs5tUo!>csFyhi5Y=n8ve{Dj9 z2e+-hlN^A|pDf-3!kkgqQ&vDC$FmkqhBVT1p|=%u{#+1j4UtNc1lzf7#UCSJbTsku z;w>A%%*v3!1B`~}gGg*bMEF;eAz_D@Ice*ENrzIiireF|5aX?w)jir*=4~r4A#q*_*uasj8CA_%cFamq`6c%m!_5|A{;wkBGNA9tjJ_psO5=4D|6+#le z_?;ha;q6j=!O36lcf7wk4sae?9tKTMa-Vu6e{x8QC0!JYOmCXsfzJn7?vg4jr!hRU4f#*VmOkH$$y*#J02vXmIv)x<(q>ic4sghN}^p_7%%~LVUpfNZWK@q zzZZN^eh&%0H`H`wL&#yxIn_r2XB0m_y0bp>v@5wG6-(gn@%9>XYwxY5EmNBW16^0} zwwY12t%u;+{4mYu`H$_j`{%By4Uq5Ml}XYGS8$kZTX}-z zL3~~+u)F`;qGGxx>U1H>K{jD!quw0gm7DB`(+j11TOO+_9i_|=n~*%9Mu$B<_5) zzj+-93970|Tn`?g&iG%rXqX7oc4(6XAD8_4_=+s5dgB zwlMDQGE|m14Ve^L)R|pCjATpMHkXI{KnPFD7ld-ge>c>9AVS78$a0XL&Ds*d=pmH{`(1b5n-)~g$vrh@PdYU^X2__1fTI!9`5RKqXV*m6BfSs z`N;z_rEtOx{}9mO|L_0hgAW8_HzG9D0C*L=4dzuNOJDx$_% zr^}I``#oW7M=WXXkX`0=oY8PlC@~gWc>l%;&>8}Q9*q2A9_d-&WE^?-NvplgVk6Kz zDqL|E_A%UT%{S*cS<$GZ{MxeV0@(r(9Q`y{Kr&iZ`m@V;&5eKqS zSOjRBeS4AVs9;ct8HlZq$8Br~DpfFIAKDElO-Pd(!~QXhoX(RNbD~BBf;QtTnsTjS z2W~`m;3vBDtXa*hYF{AO(#1p>W~^}2ly1yPQCD8 zv{;P6zL>EceRI2zr}J72{ZhZ4j;DY$|H0(`rny@yy{fL!G#duJ0n6^)s?LvnNsg>7 zK3o%hKzCZU;g@io7~>7(Ws3t8{gas#_%0@x+`k&D8Pf_4oyP2SHeKV7>Uj>X$$>zuv0w~6^y?71{3 zssvTw=BXc5zQxjt4#=V=LQyYak62>sd519oP1R@ExQX}3&JQ3r-HUgTgNl?Ibgl85 z4tZ*1oYJV5>hB%6?P5 zT^i}Ns5_jW2^&xUP5d}ATL@s~L=lo1Gk$(bVaMv(?q?ye*jTE|>Vd2-g3o*(7W-Dr z7|*YnRLq9=_{bSj>A^@>-bqyDzI-}3k#kfHqpggGzyOf ztZWy~)LITHE@B7u5B_W(CQk(F3J*>PN`p_X_wS`v4W7H}Eaq9zM^=J7i zP@SDU_aS6hmF?QZYYUBvo7WN-VJ(Xw6UFOW{G==cK=;2;^98P0SA2`1 z9%MM30W$UKmfz<2Y{V`UE}fjzt~@91|58$bCA zt9hFj5DJmw^O8`Q@j6DC?$1*41&8SUIWa%CGmAAI3pM~(T%alI-PT{)8EQDNgJ)g_ zr|7Ese>iA2r4rn756#e3c+lkP5QiS&!Tz z@D4ufs?u~1#m^XW6@!y32<3(v-stivNw7Z6T7Sghx ztc9AcN9jqLY8l<|z6Mic)L0*Wg7JZ^z~FOm;Xz^Yhea)1T||$rS?%;c%?yaiZ_92IqoYgfua3^Ef017LB_9;>?Xp>xBVg&j{Iz4PzS7}l9irq_aSH2u$CC@DNq{?A}t@;{&WZ!i8! k_aPtp|G(z{(|xn!XVE-PwevJw@Cf{;fz!qoC|d>oA5cg4(EtDd literal 47748 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 CfQxqk literal 31544 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%0AB4oj> z!3|vC_#HSyd8yqA<=%L~qPQ&!Y9aoID=<=?knNYwU#F_Yt$#4rJ?m*L83;tfoz1@R zW^6~!!@y!k1Q!}rTgCBPeQW1#J%T^M?27a#J9S8vIak`}eN+L7%zKD-#vjig3T&lJ zC^SQ`VDv2y6qy03*naF}Zxlg^PI(q23PY0s?VmJjX}UX^g#?~q9ORqkF`~Pn#pQMr zv(%CG_$)B06wTDKpST$+p!Zk(LfUbndTcF*^@MK{7cQ5%dlIDbB~$E~CfA zZ6S=UQA`&z4`+a8Jrp>p^1RJ+8^RRkV}Ri~1)vHzJ$e_~6_=z0<;c5B`n7h}QMdUk z0oIvHqE+!|cN;gS)*0HIZkjZ5pI#O?PN4Sc+{WDfg_a0jG5-?Ja)7BCYFti7MbU~N z<;8psn2uiXnA1Q#Z^bJ|BC7|Ho@hpT?eXd^U3%7hrA4xDo$MqmMjF&OTt>(b%@YFK zmJo4|Rx;kano<3J`vuEIaqHcsFPpZCqN<_ynx7HmVUdq+8F8!j9YKeTJvbhgk|{Du!X}pnr~Tk+Z*@PwxD`@@$>7 z=|dJl&F z+FBLT+`s3K%+w=mtg8_@%Jk}a2%IT8QoJg+WtIkW+yg;L^YqS1XX1-+0F zb))fDXBUakh@m1b9h=lju6M$-nuQB;jOV`O0RaEhF#O&W{$a7vCObt^orBidF3?uc`R*Ge%VMgOb zt1wA^zg>S~^?>V*_O#v^Bha>!kC1?VH&`<2TwE@;oitKZ+Gl#(dT3@yp!u@G;V3-KMAR{IQfR6<~LO8Q&bfHn^w> zh5>NHFTJ6^!%%Y#SA5IT4~$r26}@olM-YorSje(q+${(m4jwLfD<_u$OEGf6-zDw3so^)us<@KvOIq#zN2AkF1`5 z6n&Kd!UOZauTSFd>(hMh%8WYuJ>W7Z-19X0&gx)x^HRLhSz)5hU4Z}D0hp25DRv}h zXYgZgE8sHWJm)4X*9E-P?s#_@YqguMH19?qPg@pc5+nwI07sa;m>8>h=}KKGM}w^Y z<*d(P=18&5kc!0lE6*M?8errevrh@qe&fwYh~=DwN;(k)w!o#LccUpoN}b95sv)tK z16B0H_;3EsrOI($+V*=+5YqkGr!(9RV`MhCOW!OhhZ?RoGj`d_<^S0ybYaM)$B=T} zMO2i16#r<&pHYJ$;9~4l#r`CUu&#wLym7?Q^XiFTXGr40QGft;)Oek@Z;UtJl1^P} zBo3-n#&`TWJ~umR+*6X61^rGnV!{6U?r+rJWWVHJ_0O>I-zY;Ev@YnV8;@bn9~co0dfI0|I- z`#+R6fH_miu}Zp+!!&pID)z0(A_lTtE1z2y-N#}iSxNBO=J3Dfa15Zi-K2e8lI1{x_|0gU-Mq&|!C*Z9r8H(|;O_IA z3tO*n+m0Ez*T76sXnHTqylTECgq+N;3rv9}*ccCpGn$-NMduiN&yYqgU-?JEB{zT& zN`T!o19z(bIrB`gVwfPeD9j1MWVAK@cz5=8P)WZzdG!ckTK_R~W>;{q5D!Doa({v9e72iqH7nR=K;~2NUFEa-#+VLZkTRgR zY5ca@y1}yb25$Pep_Iu%F>YxBUFEGOMH}^t(JbY)D8v`?k7ZY8QHTY2iD^&tXs#S7 zEw7pU+G7n$?gv+sZU3byKD8zak88p_!q4Mq>0%R6cA-vGe`kGGFwU!J;BJCKTV8-de2>#M3>J@^?dpQ2 zvx~g?{bFy>AnokmwE!zaV?WHgQ{8rM2XZ!e?)?Ih^MH)NpMI5yv6Q3?jUR6Mgm%J3 z>$Q^(Rnu;hrB+|RA3eC;7e3e?9)nM6xtbI5Nq2{Fh%0eLqJ2Km&&JfZ%Zlgxc zSJ$z3d2tNip8Fhzp-af5n(-Zpe-iJe{~&VD{v!&}+EsLTlGlTP!%Nh1pX%q77&i?S zFZ&T4ua~zCuD8MsxkMh|cdzx{QxGX7={T-aUljDU79K4D@jDaN3(e-1tHxFMyeYv2mr>F|AGNt3B z1$`EtY4Wo4=X5JX9($E{9m&WLxx7s*vsPK7SSGF+Ptc!9lZ##ICVv&Mw7mWlm%gb8c*#dfiTce!%>0Tb+3lWXCd-N-Na>Q5NI zgm~I8CLwdyVt6~s-sb!r{*8y(HdfMqZ&3U}l@l2ShV)viKQUPTj$)BIR`F4!_xbfcaKH{rK zhf}4SAoq%KQ8rH=`7v*>P{J`FI_EV5+rC>tu zMOW0#yynzyTG(D4DNb>ky0(fnz(AHqr`eXRUR(nFSeGT{HQ{@CYU0i=xC#{9S^@hB zG}u2plK?AWKz88#8Cu@7`S`F7>vE<$^_*!D%}&ZigwL+cvMIHFS6I#w7D3PE`#Dm%jY|#3y#Q%{U`k@zKW|>D!be>CbwdV(ulik!N zn2SqQ-;;#XzXncZqdMX4ZT~$ca;G~>=kG7idH{?;U=`9*BY6K)jQ%rNZzt=5m+hbtP|M-$G;EHLdcV~!1|;#|%w@6{%|yEGp5fvd{x~HKS)8 z@YIKcpKk;8d86&}VpCl789}D9;Pmi0wp3$+6Ppzvoj zQHNLptYhL+1G!W)h3ObAP8b@MaVE8R?|+x8{VFgC&ANxOh<(vDOYeK;wBn?#pDOw3 zm{mAuCLUN0xi@mKUAx;;4KCBVjCU(N#@kJgBTUXZ2)UEbR7Ex( zvArYbcj|_^cDi|7C1gu($pvc&x!8I^BRZ!0lFLPu1n2Ur;Or~YAnLaT%IS^B9pL9> zqPq(lQOFwUvinIbhCr|0Jl^fS7gN9UbRpj*H%h>HQVbu^MWK7>ITef3eP;! z<%E0ysp94kC6(#w2S#Bn@I_hWHanMob??aHa*Bz-jLpi>djyD1U5o{q@tNuCJ<{Jf z=B$x#P6VMAQ>bJ#>~>|8y!cqa=y|x^l98%b(Frn*O5#`gFU>u$Ju(qFQju8mYOm z{6uLPeD>82os&!HMR{`7k;jxGZPIp64o_4W6}%LJpo{b0>YYpldppZKlAmt3ivn+1 zmU6uH;@Cgr$Lz&{;0mEBp<{7rt^OB^cYz-5dyJ>RomS~9)Shh{BXJ)gW}4HybZ^M! zVS^Ik{>O7~ui13nfY@wb4##-!B*$g>UU;5vAbbs~{3Hy-aFAdAI343sf@Sm2*q%Z* zTw;|vgH0wNf4%*h%4bQba;7q^H)H1fg66(_!&(c7+a3=w<}j%!+QcR{O$qtX)Y75N zFMLlAHl_o^>H@{hC@yw-7&Zp@hF;Znn}u%h#W95vQJOaFf=4`CYCy3}UYP;*;5MwC z2yz&!Ut_b3NlXbUM25Q8ssr6-S1JI1++|2?rTNICkX*-uom}6}b8dN6uKdxi^lgE$Xx(j7aDJ%nXT=3%l&SL{0Ikb?d;B?41`k*jOLY-v-FT#jCW zSKFn|2YJx(SE5=l8-l`#{oJs?RZY2rDm659uG0&ZlYHU4Ovi#E(`Y~`8p5dfspfU> z!-)~lMJG`0H&`4*25+uR;ZBE|0_o>521fJ)SW?Wcq^`L^pBYWP*Wu=1XSdK(&7C`p zJXuJOdU=e?vT%ErsHlZs-JKYkoU9XK8s4r4L8iXrYkuG_4<2X~==5qze`P_z_nBzB zJg@AKS*GrM`k3YHRqHr?4|kgbNqCMnjd5*o5<>)tKHBcs&YrvU{JD6O)+t#jQg(T) z##V<-vi^MtHErbO*@{F{v&VDP15QH$+GKLi=G4mTfy+2E{^UTSYVRjkso5bkNe63k zrGTW_FX3qn{e~z!l#e)(hmAb!S#$Htdrv)o@4m2{CB^I*|B$P`tJ4wysH){CKyT0% z6Qk=vW1}fRW0av>2yc-Abo||Kb8psSZA-dWU)5GM5dG0J`<=ZDSked$Q1srU^!}z6%w;x@JA|tAv zo|I+??;^@lz(DLqd-`Fi(@DSz4ZWFY1hde?o(kNvb(719^I+=u*^8YRU#QC4Iay(X z_Y{ZSSWv>V(PH zJ&#LOh#6UW$+5>{?oJCDMKI<}lC=FGaNqgC@4k5iy0bwWQ!F4QqeY(%T zjIE_O=&5*={(uE0WV_x!(FNU@)-p>tC_NtLHqfsszz!wNq;cT!Y7FqDYhU=7g7s& zWLF2OSjkKY9Gmsf_&oC7u`;tem7UOEJc+p%0{joPoc%p-kM*K7VBBQrrS~t{( z+(9Fw^|Q7kbZ)NqaAx3)?>#K&7xkbCoa-rq>huF;Zf}lZJYt0^|68J&|2rc3R=>jj zlGkLGk>Jde;(SskLXFwDbZX;+1Hgtu+A;&a@Dplf?vOVs*4|1O5Pl~ zuxzPyg@-?jwhIPNGq(`c59FWE4~sEFOY{rG0RKy!W`~xmh@<9d@JkUzw-3Fu2)p$` z#Td*cS*vQ~9tZy2jehskO6VeW42*}x&pqVvH*MqS03My4gB^<3XFEM(9&sJ>8r+S) znGP|gvvy>S1Wr9YW_g9*WXC%=WrM;#KT&*tFVNE|$6K`hp=2V{t=06x(?t)|LZG_z z)GQzXgEL2nT8Z|u+HGa0HOhm?ovSxYd=eb-x4+ZY-uzierrx02?k{|s{8*K6wNZvJ z(K)taxLsU;!s|mv4)J`i0Vv(?y8B#FBueAWMENJ8Hh84T0nVZ|JRL8K?O++{p1`7& zyf=Qmf0U>-Cx*h5KtNP0ul_>>&eenm%@oIhom~|nQ7zsC5YZgWB)pAn(tSI0mqp~R zO2>U~-#ajE1Nj`rEp`|c7~fCs+_fb8At=2>vm+N})j5-n?j2kM&3A=Drn%e))NHdt zWAc&RAM$J|*xDKITf!SyL$C0_v{iOjxr@xg^o z6(OAbYK^;tD%sG*lokVzZrwH0S@zTE?Z-$ic`lKI#$8!!qb}XDZ?dVhmo7nJAO3j1 zLtXHR>fV!!eq~ZyHJik<1IjPXow{`;g*g({!L?Jb&BI~Rx!d#5w(BO2D>ot_g3mOE zbrqe@`uGai3^@oAZDO~n1`K!*4ikLIH#D{z^H6o zE4d{(51Dl2i@KLcGLrZHf~V{G13{> zQOb5)&|V;C%H|HMPvX+4yqd|Q!Pg^CCLTnZe00PnM8fUxJ7-|shDhp3wnekM$A-{a zB#TG~lbXcf@mE&~cw7txuc?2~lB!OGl`U6`%~My$_GUEw85%E6{0v@M?{Z))%E^CC}H6*_DU z#0?{e_GZIEQK0EJGDvWCSl85D6p5deQ;-YFScqIBwBiOvjgg!!)GIWYo-&tZv%x?0 z&s`3$G?0b?y0dtojHX}gBDgVm6_FbF=fy1HRq@ow&bWHeG_V%^tV4VIb_E-Y5D)Lz zY!3X2dBi8pA`dC2W6IOVCL8(c-MaSYE4IGF+K6*88XSd*h%VhMANs5_=WZ=RU+cXY zudN0#f>1$mDGMWd7;21XzKdGSu4}2?fdYYimgqeXp%h^)gGM~oc{uco&CTO&z^GIe>mvG&`)2ZO;QWjl=^ z=$6EA9Z-G`5!FCn%A9enDH1U&?}+sJ`}gh)7w-mZs(J#G3lN?;W47f9S#H z@!RPcF|Fb_MADFkzF_`V^mis$vgP$(o}Tdmd@5R<2T-=B&ws5Pd6))3<>s4(@PB=m zV{q-EkK5kNa-Z>3iCjK0D1%BiTLt!Wnm1<)VHBOBcn&(8?=gi}DR|B}lCWnzH(omu z`#ttkRbu)a)tX_~pV(Ek5Fwy4Hn$vi`Ky7_LnBvZf*o(NacNb_cQ}8u@#EQFXoeI$ z714;4^^t;P?R!AFJKM=6rQn|^RB1>%92b;tmD7+uPv#P~j zl-BT}z7{H#3XIkwdj_>qeDj?OQ5ASjY=($Ke`@>-~iY3FhhukrIcZu#{nYOi?$ zmcg&fv&<*aJTdJTWH|9&0+}hAR4ENtiZ$`d5Q8)!V;@@kbBcEc=|EM) zxqd5~$w{ZXO3~~k#a}qNTiwwZ3KKQOB_|f>aXxzr5dHLgbt-L7K!}xNHlLj1Quz0d z9WpM?ZEOCpp|{5vnjPwy{Sxy&QIV5NZdGST)F-E5>R2_HzcXGD@k;l{-#-hKT_8MR zzI)DZq5XgA3}J71+wT15I>UrTpWwhyeExH(fq0U!^K?WXK}~yqG}lY~^Jun&6a}W? zDkJ}8g_EeW$y$4Z8-cQ4f2Lfp+vFzdeIWq35rwIzn=MEuqNVmg1>55~aYO=_@Phq| zu;AZ=sf23X0ek6)RwpH5yR1RV+#uBqpy|EbTN$bYs&>o{tBfrBcu=zmY4TlfAVUiY#NX5AY}ZG0gl5MtRI&!RMS zbvA>xzskSGthtb!3MYnUh`4#n110n$WE+2~-z5;O<9ox-wKHV2N~S^gK`^%V8pUQAoa|{E;PVa z(^6wtZZIkRxg``fc)DmF!&sOR7TP0z^GnKw{58%IwZA=dH5Bq|AJQ}%YH;rF;9&&Q z#C;l1ZQ@-n&>LVSanRx`*NTE!nfc}8IqGhoR8vf{ zgAwSA{Lc|&!Nw(R2$+u_mJ{WvwjK}u@@^g$KeA~k)j`~x^bUAkyJ)dKeqvj$mV#++ zVzWP=r)%dZevTCew9Qe;qrX_O4-hOp*WCD{645es*++fwdx~eHMm5=Dqq3#e)+}VJ z8d+oAXk66v=)rlMO)sV9F#!26*l3~JJ@+iQK9jIcY)gLGeQd)WKVoJ|NC!Ek;HK}e zu=;>UK_p6PBW|p%I!?72A#r}z=010IvUcY&e_h*NH?KkSSx?&K)^uwa-5An(3e(c0 zvN+bny;CdwSN74x7Vgqm8#TV#sddqWNf10s7x;=#N}tg?-&Lt0VaIs0M*fG&;x^5n zrRxXn89|#r+|tVtA*I{it`i0G9ChM+h`8zV-4%iL&hAabX*Ifia2!!AB!@B&FbSRh!Hq8}{n4T|c&yeR zYowZ9{_1h-Cwkx5uQE}U3W3+KG+U*JU9>ip=rpmqNq^k;?0xjccHR73j4^iqNcmah z*G!SI$FF{8=PO19W#HnB?F^*yl>&Zl{*guGfyk~V)w}Aj>M8I$a5^^W2^EqD{q;%6|mA;p-%KtU#hyLkMAI9wp>J zBX9s0tT_3zj_q`$C@#c2g6)60kG?Jvy?!{XrSE{LIZ?sPsCpDSKNIPoY-n2+9_uqT7;8UfsN3 zdR5MAlbCH+5;85Eb*nLQ>#pa;n=5f44wfSP{THrg@6%1{6nqTKyF%=X3ize%oX$ zM}1&$xHT*BJ^u^)e&tUN-aam6<%mptt@onqF0_XO{uxS%2;bHLmHP9j3^*}JNh%i) zt!(5lQ_M9_vv<-b$~YCfedya}LSgb%&C>$$^L3Wuf=(NqS;3$1+5uZ>q?E^vu9^)Za>3)Nf33&O!WPxkmF@MB}}B( zj9dS^ybS^49@$0GkBskg-6w}n%8uB+Dl7_qZPC%429GrkLv}n|clayn`#tm%F+Le! z6+Kl`8PWwMa(z?PpY{3cAULK?QDd%`zVlDEZtwIAt~MrZRGs7dbKx*OHv?q?viL<9 zY~yr0HO|n$>Fc1_G?Vo#>G~J#C&AJxt8ku>v+rCr1=bqHrv|upL;Lo1^Z8)ZU#)yVIg$zx& zE3J<@ccM#WyYBvyCw-3|9o4n3K_9M3gJOvzP;j$Q^&{!;h!k{Dc{bbj~f$eT$1o^YEIvuv@J6jSbMf{*u+30SC{ItHk zRp6&NqP~GHdRWKHibo1-jpxB`ZetIKxQyyRMaB~731&UT_N)7G+$B4R{ca|$V^_Y~5kzqB3YUp8{-=LzLxGmG+}B%vOW1Ob9%B~ppn>0JW zWH=jX3NMysdhQ1nfTKcVg!$hM?tc4Zpr%IEfUFcea}7P{dK=FzVV)Y2DGc!s#P_sYR>sQ^C@n?O!c`r`8iow zSh%4EIuGZ5%tdgDZRY>@)+vwh=A#wOH~$9GL+BU?XZlt#*R{UEJw@orQ&? zfTU|n!uWY2(H<DOZEf5{S+0P739u!D)03BlNXRNMA2BkpGBFmG(FUK+Xz(q?JPZt96Z%r_JPVpcRkvQz19hXp)kOB8Hzwscs zc>TI;;NwAbwbsVaY~*YVt#IdTFnTq%BD>Ql&R8R)FTu~%;#VUO8=A4ZuZf&4Ov=SoSVqfD zQxoG4CnC%|Y$@hG^8S_xnlBAwr0e3R;N}9=^)w<-WaUsO6F(g{oV%HciI zP}`S)!b|(gTbfYy{lVL{ur^H?fnoBxAMBP*f{Z7i%efZ8rmE7cnrH znUOp&u&JH3F<#S$EbpTQ$Gd}XkSJ|AV+A)$nk5Bopr8iIWJRhb#>7>MfJd8YN$VoPy3o?Zk){1HZs3z0g6fZRlhKv+(?@%NUt}W} zJ0t=jrDsQm_*r?%d&~Ix&?wq2G^jOH+lZu1L}?+RcsT`AFcz|xiJhIax1I+SuYQ$2bQ`P!CQeuBtvlo zqP094h9G*|m}6-)6DcnvOPZ3tnUS;}&Q8t*YT-)uvGJk$ODURJ>S8r5wH5Jx7Pcf; z9NNqX?QP>_NkY4VIdwrIwO|(RS|~G33wb=!1gEbluSG%G$$Ap0;AJM7GCn%4BsWD9 zlB*ZN5QlQrkw;=FL;}Lr72_@EO4heSLTwe1G)oUKTY450xSf$N%H7qLrs?Ug3oNaN z(lIc$b3@ypw4_X_z9tq#53;-*&Bqd^O;H426Lnp6mE@!dZg5>2Z;X)%xa4P}r|l*y zEiWanCrh)mf>~S8U~W)91lXxsL|sF0hrhRvma(EH4X&$XYis50j#YAVlO?+QXj#y7 zm!J+BzXv0&R2@;V&JK1r)Om5r{ra$W2Y%A1ND``TDfXz!YE1* zdAt?g3?*x+hd{e1TKUKs+qqIG#&BahKOc7}%FfnH+rYw%=xyiaW$gw-Vl}i31FEH;1)jN{^lYh`t|TZ0Z%6i2aHRk{;b2w}OEPnt7@K;) zO(^~f{~evwvWG$2UH7UMKUoX`{|=dHd;zl z19@8?6AKpz%|=^^xo4;f#^8b%N>>(Ug@;)qVlMUoxD*GJO>Len=?Fi@~kG{;(kFVS`wJ#UI0ji_%2k@r>b(1v`#S*ePimSjlrO?mcV0}qiNDe1Dv0X6dnV&Gqf@Tt@ycG8F={5+g@6R4|3gkd2UVe*<~Ag1?_XMast( zjka(jSSiS3&~{c(DH;jp?dJzaq5bTzXuKxT)>cNr-xv)d1lA9$YYulOZ zSs7|cYr|yC5hUjJH1?yCkVqRv6EklaeJK+;Sv+tkdY+1!)=D0l2)L_>IryiNqOPr+ z0+c9ggQKBMsY-UfrgCy-hSsvC6!3_>k{1*rRB-KP&<@~JlK2M-$Y^>a0|lrb_SEBVU$ z%ejCnXp*$K8yss#B*94-=Hi1GS$HU5ao`gIf%iaCUCFM#Mz+4DM7%Cm3Tq3;E0|g7 z>XIyE4fUkl6>Kc7e{v+sHdLm^FjXhAd zWH%)%xEq>aZsBX7TJMG)pN<9|HwzsJuSP)sVR+@KiszhX+jG1`k7F z338qgKLwhewTq%YT2l|Hmtwyvjhsnyn%6^Kx)dUm+0R*Ap5;<69ICPVk;cL6FrUlY(=<4q zgo#8OKF3QR*tLyk=kd!dCGA?L&qoy;TcEI5n$}v!Em!rd1$wo-ON>!nQ)y{i5DCbO zkxwdFp5Dr}L%lz~wpDmofOV(PC6?bm9#p?L&c^U?z83%I73O!QmxdF={<=r#l7=DM zPP(PV{rK&FdzOt+yp3(I2Fvds7AG|DNf9@{%KhuoUZL^~?ti^Y=-&QqA!`q;PGwyF z+so=yF@H7zp1k~E=idH|)DueFe`|Ut9r?%K`kbnBX;@A8KojzBO>5xI1peyEUJW5( zRyM|&ECbU&{?^5ifZo5om-Wm(p>i{*E`k4VP4De*+y1xy8{A;23p5mqX!~2!z%&Z~ zYnr|P=S?##blG`pwW~ATB<_!`pl+9IJy6jE_n{vRkZEz}6;9W!{Xb@K!KjP`N~|Mw zfK1s~>WXd`Cg#pw98*#79eEvb>{h}_Fq5Mq-`g$Cdd5GdVAhsrY^<$4hE_Yvrau`; zmP`*7Y41^O4_DvxTU#Gf$602Wmb}`d{(Kmj=-Y6()U9!MPJVtVZE3QCr~yVOr@h^P)pA|nx{j!B%aO&&IT+m z6$B3`Q>Mq?7JIcM@;4rnx^U^7?bG4M^A|^WlB68BdiI{yyEI&LD322wS8-^0vZJ}? zN4;d_t=3$-BJ`JrJM@?2&6TkX!;zO*7dKQxmmQG1eOR_3Xd!N>8<^fjK<#4rnVC{dU%xLY*}jsLwKgkW@ch#U zmD%$Qw$FbE{zfVU3V??fwW#%N2(?p=6?wIk0#o!YZ?4T&5eD(ExOXh|PhE5G%6D8IQ{U=wTnt`m zcCHk7V%+lnJ!A+i>-p{}+&QqLw-ke-4h5FUHm#rjDn7EfqA^`VOkCS41evl%t&(GCQTnb35L zQdU{752RY|%7;#r9*^aBvMshnp6}7$hwGMywl;<&%3IbGH%29c3-4b1dQ!r#(?lcL zq?Riqo^W$2p=*iu`DG}*Y}QMCEoLoe=;rcFU)5}QjlI~b>-$b#+`)(;9;1DM3biHb09hp_EpBv2AxXx&5(GUwEk6epzX4-(Zljf zc989y7s*H1YdEhj&2oMxTecQBt5f&E`Des=p5_=={>Xk#JDVeLh4?`!;{v{bXx>vS z85J;86Ug48eb?I>Ok`DMvGSe)(%0S1AGz4siNaBQ`X7$iqVJm{qkmAFByXYE!-96 z`mK!Gtw07YaCK3d95Ei7_c*Ax7)fX3l+NT9eR$U896S&hyl9_%EWpwJuJYvRuKQ_$ zQ?lgLi<6c~&l&}TH{^aG6`UQp3Q`@kh$xU=NBvN!+EX^k!PW`m^No?;$FBBIR)0DyD4U z+j0sa+iNs#Xx+1J*vU<(WFOP)~)sI)_-f+{cMV796(wq>*-Y)t_ ze6I$q-mjk6VE_@GeZCN`3N~`$m4FQ)k7zq}?@H*sytAVxv`gO}Y^5$VJ8wQ)J9dX( zKHGHHl4&+(q5*MvmjLVNiN^xA{9r&0|JV{k;0Ih3!+UPWB6%I9kVoiC9Pd@<)9^auV`H zMA))BF6QD?XCCo#xxyVcD}44XZ_m>=Med9J*qnsdPKM28>g(3!Vin{*pRp9-jxm=i zFfrq4k1QA#39t=kMJ_pIPgm3hV#bmM_y!!@Kb+)wJr)Pcx#Ywb#LczZ-Kh4B=GR`8 znyg4OeB1;FUO82~N)0}1Mt>SVP4L{)+{8_nU$*pU_4g^)-B?{3*b{NKTg+19a&_Xd ziF74~3Ow$5jTvn<{lztwTA4mmr9^Uiq(QJeuc)lC8o0DadvRCzA z;TAW#pZgb;U9>yOOLJL7{LIpfPD@&@gGyHUN39V`FM6eYQ7r1y%ns>E%svchw=%0GsK9M?A5;o#(5T5ul zy9lb?y_gD5FqpjXQ66Dt!gmhwRXJ1ctbrNt;wifY2hyD_V42B~fT(i|?e>kWvl`z# zFDI^b$61PTg539}&o0KPbv6b@_}!_f1JJM@Egq`@W#$ez6|Q@Abp4S!ag~) z0ncTwC`)bsXE@Tc=3G$@PCB2Y)3gZmE!=FkTvklpGd5niU58~(Js=m7Wpf3bY#g(5 z6<+t8xTLYdwYNVy_$Xof*4|-ZGr2$5-YrS_ZP=W2OIoORyPFF6H{)5S* z#2zLVGXwyx;40$Vk$oDEPq4LH=B-Gs3Xt0NO1?k*aY(A{aa}ddLEg%M=u}LLdPqON z@J@E%yZ|@6&EjfoZA6b8+62PJzvF!v09{rg07wb9%Zy!TVLfpC@nait>eUkeo}>`e z`+}xHIjWu}x#pZVz94Xt-H-oCN`-RlA1Nl0Z{*|karh5|#r?T&i@^NwYX;luP457Z z&L9@F_sQq#JQD({vA?YzbE>AtjM{SzuwB=ix`RqPbEmBVE6(C z#M>iBG|}&+$+M0_0eKN=Tb%;2QIc!#QxJ(T5I~wg+URHxp8^(o0`ej8%2g$Q(7i|v zrQC-naRXO(9aV0x?l*mPebEM4Z7mmY+AMk4$*A9lkUQv{OjYuBrUfhl*zz?bh<%Ng zRPS=_=(mUQGd)EaYqR})<7rugN_+qa3)utIxy(eJsXC7xIxB`Mh#7YdNx!USXyUxp z)~1UF)*ci;$p`^2`2psgaar#m^UYbTv^HY%!*c_1u^YM6g2IWJ zzOu4&_NCp2z2fh;x1~D#M9=JiA3!pJw8mSuV%K*+=Dy5a-f`@-*bDfD;JJFfJ`>1* z`<3n7hB2HOSD4Eo3{0O#yR6p@upC4lvp7eZW|$?>Z6dQ!Z59y-h*Qqc-tMln`Y~pU z1Yp-ld&q-bVB&V3dVE}&7MWvn=P*D?bFHHT-0}8>L7ga_d zSoTNU-&N0{W9rEq1qIA^cg`hN=5k3p&?=@(n`?_SQ$x0>Z#}PG`4)$DTmdk$a`dER z#n=5)t;yO*uDU@0oVKx@04%}Xt1(yp#x=lbptVl|M7F&zSy0OWqP z`TKXfcc^{e7BE}Qn0_U=`P3vqxkGIsrsb-|O(tqz4wbxE=X7zd9<~hcGA%{-xB?&p zb#KhcIe#%6tdO7PwyFfnMCY6kPyg23-QeQ8L5nH$%)9EF<&NON<*K2L5A3Th=t^Yk zdu?72Qh47E-j()v%iC8SP)45V?eP2%k7VY&Grgz+GUQ?}Ks8>CM~Jrv0vQ98iL~g- z;JzZSyK7~bzS5qojKs-}3&$+JJsc}+JhpJ})~R1z5ZcQmo31ON8HEGcQbR_;2*C9(eGpBm%qQ-)3?;+i~|XF=0;=i`n3W7u>^^PkmBRoVcoJV z=iO#&*76gARwpQ3j?^Aviz+;2Y*S@uC7g*i`5{=e^ZE$i3=?igJJFhcf>@7e$8WTO z*{WH!06<^NEcfBc=mS+%vSK8M!1Ta=&<5R8XX3zVy`|L0JLxx#X;XP+ojd7fYAfym zU+zGr!&T_`W3}s}l9=Hamnn7ZeBIMMMFX{Y4i%qDR7!3=E$g2@izq%lt^HK}_hNp- zT<@7sUQW9DQkGc{0It)l--(Rl~?*J0&p{ho|3Bk2uO)d_kl{XEPE&L zB+u@j)IXM)B!Dfi+pRJ!1)t3}!tjWi7Bk11zZtxkB3QAUA*w$4zNP;VwzoK|;Z8;( z=lHj$fMHo4zOtt>&TQa&AfO3Ika#{PzvKYIJ^Msap~gIxBU|9)w0dN5$N1h6VccG6pv#*TF5zt4uy;ZC|+tr&lDau~*mjP&NGvoT{hQw-(eL<5ZTr-B8nxkipnwuMiwBX%arQTG?pin|J& z1ur%V_g)bxnM|LZZ_d$OxwHe_jQ zwP1@-Qvpd_ooxxE6L&OBpq#F=1`izaSp&4(#N;=?35b2P3$3-c8((`e6THO;o*7TM zOVNH*JRwry@+$1Jpd9Kh6sIq&>QDLUE%#;vPnj7XO0_}b3w&EAd*H*FpZDj$3n+Dw zA%X0ry+iPt`2$pqrPpG2XqK{W^aH6`UN+i6yqV)e9nH>gymOzg{64sNp?A{c+))r( zRhQZ=4;<}>__U8}?4jtGWM#hce*T;`v(&CPb767(<1!d)Ra{+7;94aGkV24{hF4}u zY6IMPS@42H0qp{5M$E7p18N3f8rmw)GfmWuvpl6YVley(VOa4q2YT>%PZ+nrx3G8e z$WO1a6{82K8=ZH`^Vvn?@gXXY5>HHhbLLWMFU?voI0{{@ZbH|tb`u0PzJC?vuM(snEvv=+(SWv(Z7?i*Ri=QIlA!FW<%PDrXf}uTJJ*ZL`C2 zeNKOl5H@;wCELx+MWyrG#|$$;I3!ZkjFRBn%cNh?U(KPLq;fXY2pgkr{rs4OLU~ts zhwNq^E^z7vyKSUTNo9DL`M7KDV2Ac@rPr|v7$1I_$SOoQ&6SA{!rV@`cHLCucTQS+ zAjGKUItpk1xOdmmTd_kcpQ3BN(yka4elpzNY19&k$=UKgc10qB)4inW3y5O*RY)

BInTsyQrog)6r0G4vy}Z+UiTHp~}kQJVPNJ?t%$7RIYTa)X2uaPhS)S~>T&>SssE03C%6`R_(Sp8M3hlq$* z!Buj*xxR27(mauk%bR{H@$nga=je4|{}UYK~3A=ZcrZ z$3m1_76bA#GGm4}neNYY8h7A*irSw~TPc1Pj@?<(8@^d>5kMcce5dmTSfQhI)taIrR=nRviQCt3 zo|fItP(I1I9GPAuWXATDWEZ*VHhYdT*p zP?l>y{@9e)n(%>*G1;9Xx2095 zdQ^h!+_aNEr6AVKJ8AOqi{;X@%xFD6?9y}hWAzW4q5j--uDs2Z#B3(%+So8z-^nS# zpO`9`F?}w86$$naA!{o2K~bsGlU@=2u2L;)OpY^%rok%s$V`{rD>g3;Z*q^G-m`6> ze2OD2vE5VQTw(6eHr2y#=@npJIE9uLO>@#aN+*zciJO661cvaEF6&H&>f55XrBs1v z#p?Ty4#!meKYfoU&?_WE-5l$x!%ibl-wPW*otK#HZ5xh#B=%n28EBc}g57(T zrk%+h)|90Vc$dEoe`UrCN1}gwPHt3T!ySRK`3Y!}&BeAhwZMGQAlk_)+G=yj*snQw zZ`KO4=;&$BvfRVQi29Z!S>A$4C6#~O>fPVp<*#&7GoF>Um^1fq^5gk0w`F(p>ZsQk9qn-CFp#v?4=JKh_^V<3OHB6w>P+hc}795+x8;=hul`mM$xZ1lBV@TlMP z^l;6i8x19SFzY@stI%HaWkXvh)&fFt`n$A!upObSn3BAAPme6Ipn|T^f{Oy^x6WL~ zQcBJj<=>cub}qrReVHMlG8kS!^lY;Y%KMP!JI~*n?xGUoa+%+C9!zlG01Iy{EY2~% zyrDn(r8%*k)BlZC7$?1hBaJca{p49<>3EUhLJMDi+vkxP0VDkE`x{o$oZf!-JH6nS zQaLWrrgQWk^6LiyT-0^AU)%uxG=EfX>9n1?UWtiNhmXwU{ZB^Ki|rcKqLpvPwlgX# zTE{AVTiG9-JIdMv_!*u%DEs8>QtQlTefPt*eYNK>iagP?_q*8RV=HZ@D(|ax9WeTm zd6s5RS&i7&g02J{4F=_+e27zBB`u=FBu?Qy`+B8_mjZigEL-+*B>(R0jJ(N#t~NIA zsCI|bfn5 zawNsfC6kx>bH)J*CB34_h^w|MT(+tfUe#>pR9u}iH|qk?`j4_y2f8u?VPUbAKbJmv z$5lM|@~;_FUI4yeqNvv<`EBt@Zo#&Q&JRXaF2L>vQt(^M6jVvka=SsypIU%QC18c9 zZw1PaU!^_5jjOi-rWI$itn_w9*Vtpv2M(*N8VH-r?CWnwm|O#zZ5)55CVMCS7DRmQ zNJX8hWb2tVv2#rv?q!kv3YLA_#FsERNW0|hQ+IA8h&XAy()AJ8lm|IsnX!cZ46C9@ zMyM6x8dqH)q1UA@!fN%_qqmQ5TG;8-)~P~nWubS+^8yG4vtfPh!+q4A`N`0PF;^`aWBS6As2MgRrODkx&r0hf1naeF7A z3cJek(t92fwSQ^@01Ls!fab--6F>tpS($7H7U)&86x^5UrB3^Sh-5^dR`W$4Yc3Pm zr)(}JyX^BoaV=CRG$fz^XK%8XU03sGGml*XP0^g1?Z3}5#>y(>W|j+NGTFI;kml(3 zIW)cO+~mxCW;LZbKn-L+B{f-PFue1-J{z9bn&!XK%gmhs`O9Q^I=!|MIS}>K6_l0Q zvCrr9%04VID}3h=#rT4lE-v@Q*^=tLsWANP7$%3qEm`pwmP`dncFpbVhrpKR9>S@a zS9a{7;BGtzbz%p}n#~Mo34d%`391V*)NX&eoUvMJJ=hy}PftVo=exxW!NX6o<0A9q zF8eQhtGH3bj|yI&Ym5tPA20b%Q}FQbhzTf%dxFZJ3aHA& zSzB9&YD7&t4oB1m;pYaih4a{`xcw?y6!X#4@DS)1zIO$W`fd4AtYyzpwiZvv4R7XG z(VtZi$0{$?fP!FWvi1(t$0wl)ej_&|9v3***31A1$iAvVnSKf&Y;SJ~3bQglD$yz^ z=Y5Y!1O(rLdYd}T!*@vx3Y@hW%p+L3jtxm<$G4kHA=g7z4nzt}xfc7R*XO6}k6c;n zDe~$A1@>GpkrIltV9k9jsr8$4wXDbWmA(hz%?ltRNtz(E`I6Ble_efmQT^L0Ypmh) zdY^7oq%x<-9cQUpSAv`4ZJYPS-J@kjXnd{zf~SD2=WTgVB@i)<_dcpZS#)08dRyW7 zosGqyd{%*$tcLz;dz-(?sNOm^w%G19j%nIQZ9V@!M-3a0_m*x z?l8XPI77Lyi{8I9}b%T+Jr@KtgkHOf$%_1y4=Dm0Kpb-`(t}~;SU}WJn@*m7Bo|b-ezWNgSsEeV<~sIX!o03p4D<1cZmE0IepG*XVVUgCdp->M zKxY*dHwBi*lRqvxaPC+x=EFI&^xlJHT+Dj<|88o>j^*`l0SiXP_=3i>v5HlM(YFSy zYrF2Uu1h#pmft9aI+*N;Ugtgx8o{T%{4b+B;1zv+*oo&Pq6~`>P(YuafW>Rc@jq!R z#n|^1BQ2kZ^o&H*HsI$rg&Y4{D>%?f4Ioay60eOgPFym40xjj@lPK=Ufd{;|m{J_qeNRA|J?b}?4|OL@~;IB4$mR9|1#wX>Q&uW z0;*jogU|hwbKPd|4i8ln@7{cI`Huks?3Y1&lk*?tez+K0|FX9xHxh!YG6@#?b*Xb) z-{8jB+*=>BV-BhWQwp~;Vug~O*3yikSH%N42q0cGFAX*-RUC|7KXB_7WBc7GYEJ)y z?v=7zVxnYTWB%F;LG@o7Di7twBAGLe0tnVBMgK0Pj%1-QfHqE2Q|&BdfDK=2o}%|T zqV2S|!!`F*q&$g^ztv^ z7b^V;LxkpYOyr@mI-asX7vOW4^dS`|S6<}|4hP0g{hHg3N`(jamcz4#Cl0oUmzXl5fjaa%&7P0Yv$MCOhi<$#BJ&fOt}^ z0+^V|imIM|)5soOiP(q9lt_M=U871*0{)vtx1-iAEUnLXh&ZIh4QI=o)vF8Zy z*EXAqgFA2@o6CFc@k8alZVWxdhDk3|@xy39Y;Xs(oqCAMuV@$q6jNKM%ezO?@*x); z@L4(UKZZ^27h6}NY|cbP6j>D9ciKRHaY_rxs2YEA3k`Pi4$1?8e`_6p*+3?RX&f9` z%JjYb3TW?D`#`{zy6V_DzjRolyuE|&txe`Quz3Wycjz0trrM)_wyv_+ zs*M5aBzejMj`0#AK``TB1%QIU=j1#z3G7XhY0D$ngbGR|fw&}Vl=Mj2Hv(^iwd z&Z63V!=w4dGAOa*l^gn>eFh1%k9&@r2s3J0b0TWDeID7k75e8YGt&BCxH zjP+ZAmxkjN!Q;u-rbli`mg)-zw&$HX)T!4JXdAI(RG!t?X5fI_A9DW6LM^S)=5>Ii+xJ-+g49b$#K3N(+j3_E9*6|IyRV zqpuJ4!za%YY-HXH9Rr?Q_b;y`EbNuGN%33CxTDY45AXF+0tM;tD{rf?zX=y9QRPAE_=7P7D~6ADHfcKrEQ^dyDea*@E};k4eRrL!?BRhJ*bJ%Z2MpSGXh+Ybr`kJ>g#A`&U?s z8i&7?W|Va3A@ayhfaWD_+XUsOeYu(k-z3;nMO+x|L89w6faoU|taKYk$D{x94LrZO{B+7-`77@2%TJ%fP&?WKH|`O zi_sbObB>`UZEVGWpIlKd1Vj&Z1f!RUg)eER2LVx8mb z0(bF;UP<3 znmrrKv~x$V%Y%S+@YbKM=2xIqo(Y0- z(8bSu_-Ky?sz)Wh;b!&Q=Vri~OL?cZAFx4|G2yxA8V=9`B{HX<(l zqsMtcV4R@G6+po@9R+tP+#z^T%J$22H=Uyow zPXqSXJz#lSy4vqJaOu@HViGH9__^MYA6WlrWkuncv)7&E{6V_=0l8@8ig$+kei)5* z#xiAT1E5}6$M0oBmn&^+#RHDQ%hUoD@ACw+@a?^$WL0OfB&AJxwX&_R6cZPx7a^<2#xfxFgam(%It5n&C~N+%Ck@w7&t19S0yt$>gLDBdq5)+8Bt<0VPJF z+Z362uar5zH*YZ>hX2D_+(FPibXoZa+oyUFeQD87lMfr){llu$2J&qSo^jA+MN3g# z6843zp?S`=gY2uZxyhG;fMycgB+R~Q5-aDsEwG9*lWSjw1tMtcT%(?}M&aP7&m+}m z+(rk)Ai^McKY0s1${s1G+2V5WV{a(7<^vU*LYGK__4{TtXf=;sw7o6-oZa zmj-1T73_?OeD0z|)qqOVZhKs{{7eRa-^#xJM!lBHKa1>pH6FJEgr9a$0=u=wm@VUy zD1Tw9G9y=3&SC!peDOK%nf{;6T?ds8EwK|hhxiTiShj%9wK&T%L!{u6htmmw%?mVc z-u+!Z4rS^FdXxu))-Zg-OqFkXv}IwaC@2sm3I}NYBm`J4Uj@vBXs*_?n+vN`1ywB0 zIYLgs8%s^+yknwn57)dCyFGG(35SI)U7~Ia37ECGxI9~fqUohD-ZXs`Z03#xI* zTDvuJU9=egSqr>ntlvE*Xk)eBS;&z2pnQi1_4 zc*pJ~pi{0p=f%{oN6mlF>Vwn;PG-vu@~krT<_u7)yR79vXcA^BRO{_ehcl}^4`M)* z-^FeZtDSGQpo2oT6JgsX&@5m;zD0+@9m!G53itB2INZbe)<0XU;jxg69Mp)eVlMH; z;YRqmBZs%Ky*0jsLY5!U!wcqnonb5k0eSgxWoDpb%A`$Im#hMqvT-2SE$+;-j|Q#v zg8pS^%MM0Xd=3+sH@*JxRLoRDLdVo4qGWVr1;O0p`?HP5{wc(ofyyB2$Gn^&6wL->C7FJ=NVFbU#xw^peMDuAA zTtP?ck&c9rHQ-%)m{Ng|Yc=3qXyBnr1J@{J^QPB!AI;Uhb&xW0LllvscPAH^y_7oZ z#MI;i{M!w>jG5^zDZRKt08uW6n_uqD_C3dr)Mx1uc7?1NJQ5!hy3LapU-``#Flr=L z2cuU-!sUBfp0x*9Xyhj=#cHepQQJ|)evlF%LCh=#A)@p2OHe?^ynS${^SM8fFP<^c zmN9-p!s&T8iTD)LrvLzLJh!0Q^YOq_=l)-Vx3<`XKHRPr6);RmGopprx{ye1gb&HkO~ z-ndF3nBK3no@=`fy8^j*@xGIKSA(VjZPN4R{z=S-cqI=Nt82q*i=K76fA347Gfd_! z>&8g)9J91ET5_Nj^(=QVA;m>*VXUPL5MaEu+IN+hQS*=OyYOyv&2#k#HpVgWSohy- z5-bR`FbeltF}w(}?q2380;7j#nIwMndg`KU-e7e=^k^KBgKji$!hXsd()i~$@;H$1!Dk-uR7&}To3iowhj2Lw@LX|7HsNC9im=9 z&NR0Zys#@_Sk0m3G$WlnEq|E;vLN$g3bTd3(6{6@@^=op8%|>43`@1iM3&J9wry-9 z%*CD$N?~BJ(@k)X5+FFI(^K6$&Xsl62?8B=z$?rrNXS}h7c3^~uJ02M8y8-_ZEX9` zyeN@-?sFWhQ<=A_$o+Y=8IU3JkGh~#Z9taoFdO(uv}=FAXnIp>hEVSJdx@1_je-72 zjcLnn9;Pjqoa8!#Km}Lgk?Gs?xI4e`bA(0e^HFdfinIh%{OxIf)zT#spVM5TY~Ez$ z=Z9yolpHDf3p&4!I%g>qvi91BoBbC{%X0ZKm}*V-l$L_yN=%s!5TFUIUg`3E4V3Ek z;8+BYsvKBdzVE|WkNJCWDfkfJfk;#V{DAU_=pFS@x%{>%qZX*74N{87b{Ddwgpkl zG2)HSgV15MLTk%JcDK-L^SKbiJ1neC`+?z|0s$lKb+{uD=x(M54RUIseU#b3nL%6d zX#m6xgsg|HM5m|3E5npGJB98kGVNyrGBT!T$^(988OU@VZHi#}s;C9>;9SchBnv2z zEKupYn(OTkG(Y`xS_Y7)rcCc@t;O`Nya7hE1mT*C-~^tox%rWk8?1{8X|>@>+H8AI zS2IJzoycR?Ljy`Dx&>4jb(8lK*DeHo{jl#s{Am+bCif}<=Dpm-6O^<*+v$~vHuUd^ z1Pk?>KK(pv?sttMCY2k)T=>{bRWPzIhen-j&xt-#s0)-*CooSrF}dFm5D|GCl-O@J zD1%pk`0+@v;?I3v2WEmJKb}?h3wO!?=XZU8g#{Y%UZBL_f&T!sYY*^=x!Kubz8=lI z*O`{quKP_G3uS^h4Xg8;r-FT?clQ_u9DTTv!QvlY$%IbQZef6l6a#84_}-8;9r&Km zKbMdYa|tbuH0LBM{RBV!&c_Mi{W)++YLT?x_uNN zG|?MmX+_~jRrIK>ton!|&pX^l6k93N-TMOUCdF7(8Dx$*rC$Y!oe%Or_j+s+-Y2T| zEe%TAm!4gY1Si0*O_d0$UG$sw$jV`1`%m|amp2SDrn*}6ZXep$cjH~GeDmVq4ZzSf z+Jw38cA(T%d%_C-K~wj%gJWeyfUk)0l!gGcL##Z?6NIHA>_DY3O^+xYWo?gen4cOR zsSb7dXP%`VvUY(iNTq`^Q&kjE0o{E8K-wG66`8~-IM!5ofWQm_D{~u1o}xnnOmZKo zQ1iLQtNxW!K5B3~^EdvQe@_WG>SSL<$vfv<)6c%j)MT!+?NmQ--6%*N@WCQ~;rCyB zF!KA!@;#l~BktMH;6czUC5##ZzSY-Vx0k80oA^`@+&J7u+I{3oz@0LSPzBszf8DCx ze(0Byb}7)mZ(^B88jLzR2)<2{SB)IcjSVIJBb79b6s!w;T6*t6KTu+nf?(bQG#V#3 zz8~lYnNr{C@(csJG6<)D9K-FAv|EGipSk|K2c5=a&`6OUkXWL@aT<>WKjA77 z-=?8_-?_y=>WzP(Z1B=Zh*7Jg8s<%{&|i78Y0=NY-hbVXy!etgo%kdqpuzIM?hA*#C{MWox=LfB ztH06Sq~494^eZKIPmP(j_1}|9;Nj_)<*EFBkH_=6AX+OpF6vj0V@lhS_d>)(MA9eq$0Kh(H4 zop>T7U{LL0t)Xw7@OX5B!dK_Lf7MIiH-C;%i$2eDUA4T+?@XR{EvWf-Fa4cf#_cZm z+lsyL@7Bpb#azRf(Ed@;y?~pBy!#Lbk$ga&zA}$Gx_yV`Rz?96a^jy)#xkE={_{z{+K(yv zRTq@c#9gB3vHWMlxc9M++;RVyt(Q(5P)t-6(H_dcH67;4C^oIAJy?Mgyje<7QdZ0q; zRtHXW^&dQIdrz_CcVu)s9DBuR^V_9ci~^2-axaU_E$I2iF^Clq(15BadU(#h7o5x6 zpP>LMF@4WGZVmW09!-v(d1#L0HgE#N6B+#SMJKZu}k#N_szPFAnB zHSBqK0_X{82GIvEcZaNj6LgK~rU|jvtqBBi%bahwkE(Qn#F>w#D(L%q-!fo}dq6sh z=>n%oG&R+jZ0q>n*w!YytS*Cs&0=3rX~l$+CJun{;XpwK)BUt=5rXUkV%0prrli-p z;9_~H;N)QU+H5Uu(&Uh=r|}&jK_?B0;&>7?1l#YzHqkJBe`Vtl3_S?OTkv&|k7hj|ER3HE%3^NFpM^T% z<6gpBKe^O^s1rw7CwQ56w);l%?@}WoleV>0){5MHEQ{iAm*X$pP7)v`0s4fmZ z$-J>7!jc?ANd841^;l54U)_(=+8i8oSh(I_$+=%9d%22 zeyApLnva3QNm&z4-aB&H_DX>2F)OKR(!{6N*B3#JiM<09)Wh?P%fDtc)(1qs{&Ob& zDw%>r=pKpr+~;^u)&;TZ{8V?L+q4Y;hlRis^@7a7RT6ml92VdWc>XlkzbcS#?r21? z14a_m1!ico(dXOEzRiDxea$XGc&GKbZ8-he~4T|fcu{OPzd|4rEoFIWWRykSrNSTnxzv7RsbO061*w5iNk z;(V!v(NgQotAre?djLv}%r;KlD<5`Jq!}yzDouMrMS6VZr+;JE8%J(hW?mltIgn`H z|2&X=2JU#tBPNRg{rp)nKlE1l2cj|PQ!2F7tL0dn0tWF!q=kmrTmCirWj%^(q-xZ0 za`-`Ukr3_U*R=2urQc@N6e_F>+^&zB`zJ{_dB6LAKoU0o+#S~~h31&808;Qd_J2+a zG9?H=fiDXwb%N|b_5r)60J~58N4t;g1tJHvD@Fgt0IE>wq-`5O#0&m30ZpP6_bK%T z*EmS>y?~Ot2oz2f(I-_!fL8=DZP$NXRXS&2l)AtNibuHqCMO~62Mk0;?~~lW=}Fpw zFxzb5x8Q_%@BjXVj$fdRiOl|Q{Np7rw*HtRE~ML0UlGAyE@Xk~n(E|hT?qMq08K=4 AtpET3 literal 19737 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 qJrHo>(FHFMQ32LCVh*k0ZM From 4ab7faad749856bfc8178f9a12f4c1a8d40f632f Mon Sep 17 00:00:00 2001 From: Gregory Sanders Date: Wed, 15 Feb 2023 13:11:38 -0500 Subject: [PATCH 046/454] Update PSBT_IN_TAP_BIP32_DERIVATION key desc Clarify intended usage of PSBT_IN_TAP_BIP32_DERIVATION for key-spends. --- bip-0174.mediawiki | 4 ++-- bip-0371.mediawiki | 4 ++-- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/bip-0174.mediawiki b/bip-0174.mediawiki index b7e0d05e1e..6a5d5e8c4e 100644 --- a/bip-0174.mediawiki +++ b/bip-0174.mediawiki @@ -453,7 +453,7 @@ The currently defined per-input types are defined as follows: | Taproot Key BIP 32 Derivation Path | PSBT_IN_TAP_BIP32_DERIVATION = 0x16 | <32 byte xonlypubkey> -| A 32 byte X-only public key involved in this input. It may be the internal key, or a key present in a leaf script. +| A 32 byte X-only public key involved in this input. It may be the output key, the internal key, or a key present in a leaf script. | <32 byte leaf hash>* <4 byte fingerprint> <32-bit little endian uint path element>* | A compact size unsigned integer representing the number of leaf hashes, followed by a list of leaf hashes, followed by the 4 byte master key fingerprint concatenated with the derivation path of the public key. The derivation path is represented as 32-bit little endian unsigned integer indexes concatenated with each other. Public keys are those needed to spend this output. The leaf hashes are of the leaves which involve this public key. The internal key does not have leaf hashes, so can be indicated with a hashes len of 0. Finalizers should remove this field after PSBT_IN_FINAL_SCRIPTWITNESS is constructed. | @@ -591,7 +591,7 @@ determine which outputs are change outputs and verify that the change is returni | Taproot Key BIP 32 Derivation Path | PSBT_OUT_TAP_BIP32_DERIVATION = 0x07 | <32 byte xonlypubkey> -| A 32 byte X-only public key involved in this output. It may be the internal key, or a key present in a leaf script. +| A 32 byte X-only public key involved in this output. It may be the output key, the internal key, or a key present in a leaf script. | <32 byte leaf hash>* <4 byte fingerprint> <32-bit little endian uint path element>* | A compact size unsigned integer representing the number of leaf hashes, followed by a list of leaf hashes, followed by the 4 byte master key fingerprint concatenated with the derivation path of the public key. The derivation path is represented as 32-bit little endian unsigned integer indexes concatenated with each other. Public keys are those needed to spend this output. The leaf hashes are of the leaves which involve this public key. The internal key does not have leaf hashes, so can be indicated with a hashes len of 0. Finalizers should remove this field after PSBT_IN_FINAL_SCRIPTWITNESS is constructed. | diff --git a/bip-0371.mediawiki b/bip-0371.mediawiki index 452584ac35..599aa546a6 100644 --- a/bip-0371.mediawiki +++ b/bip-0371.mediawiki @@ -78,7 +78,7 @@ The new per-input types are defined as follows: | Taproot Key BIP 32 Derivation Path | PSBT_IN_TAP_BIP32_DERIVATION = 0x16 | <32 byte xonlypubkey> -| A 32 byte X-only public key involved in this input. It may be the internal key, or a key present in a leaf script. +| A 32 byte X-only public key involved in this input. It may be the output key, the internal key, or a key present in a leaf script. | <32 byte leaf hash>* <4 byte fingerprint> <32-bit little endian uint path element>* | A compact size unsigned integer representing the number of leaf hashes, followed by a list of leaf hashes, followed by the 4 byte master key fingerprint concatenated with the derivation path of the public key. The derivation path is represented as 32-bit little endian unsigned integer indexes concatenated with each other. Public keys are those needed to spend this output. The leaf hashes are of the leaves which involve this public key. The internal key does not have leaf hashes, so can be indicated with a hashes len of 0. Finalizers should remove this field after PSBT_IN_FINAL_SCRIPTWITNESS is constructed. | @@ -142,7 +142,7 @@ The new per-output types are defined as follows: | Taproot Key BIP 32 Derivation Path | PSBT_OUT_TAP_BIP32_DERIVATION = 0x07 | <32 byte xonlypubkey> -| A 32 byte X-only public key involved in this output. It may be the internal key, or a key present in a leaf script. +| A 32 byte X-only public key involved in this output. It may be the output key, the internal key, or a key present in a leaf script. | <32 byte leaf hash>* <4 byte fingerprint> <32-bit little endian uint path element>* | A compact size unsigned integer representing the number of leaf hashes, followed by a list of leaf hashes, followed by the 4 byte master key fingerprint concatenated with the derivation path of the public key. The derivation path is represented as 32-bit little endian unsigned integer indexes concatenated with each other. Public keys are those needed to spend this output. The leaf hashes are of the leaves which involve this public key. The internal key does not have leaf hashes, so can be indicated with a hashes len of 0. Finalizers should remove this field after PSBT_IN_FINAL_SCRIPTWITNESS is constructed. | From c589490f98ba1b0c606d0e2030463f1fde54b786 Mon Sep 17 00:00:00 2001 From: James O'Beirne Date: Wed, 15 Feb 2023 13:56:22 -0500 Subject: [PATCH 047/454] vaults: make recovery transaction explicit Instead of implicitly detecting whether or not an OP_VAULT/OP_UNVAULT spend is a recovery spend by scanning outputs for matching scriptPubKeys, explicitly indicate recoveries by requiring a witness stack element that is either -1 in the case of no recovery OR corresponds to an output index that is the recovery output. --- bip-vaults.mediawiki | 34 ++++++++++++++-------------------- 1 file changed, 14 insertions(+), 20 deletions(-) diff --git a/bip-vaults.mediawiki b/bip-vaults.mediawiki index 66bf7cb6ad..c5738a0672 100644 --- a/bip-vaults.mediawiki +++ b/bip-vaults.mediawiki @@ -279,32 +279,26 @@ where ** If is less than 32 bytes, script execution when spending this output MUST fail and terminate immediately. ** Because the recovery scriptPubKey is committed to with a hash, witness version upgradeability is preserved. -==== Check for recovery ==== +==== Witness stack ==== After the witness program is parsed, it must be determined whether this input -is being spent towards a recovery. If an output in the spending transaction is -found whose scriptPubKey hashes to the recovery sPK hash (the -first component of ), the interpreter will -evaluate for recovery. Otherwise, the interpreter will evaluate assuming a withdrawal -is being triggered. +is being spent towards a recovery. -In pseudocode: +Witness stack shown top to bottom: - -is_recovery = False -recovery_out: Optional[CTxOut] = None - -for out in spending_tx.vout: - if tagged_hash("VaultRecoverySPK", out.scriptPubKey) == recovery_sPK_hash: - is_recovery = True - recovery_out = out - -if is_recovery: - eval_for_recovery(recovery_out) -else: - eval_for_withdrawal_trigger() + + +[other potential witness stack items ...] +where + +* is an integer indicating which output, if any, is a recovery output. +** If this value cannot be decoded as a CScriptNum and cast to an integer, script execution MUST fail and terminate immediately. +** If this value is less than -1, script execution MUST fail and terminate immediately. +** If this value is greater than or equal to 0, this spend is a recovery transaction and this value denotes the recovery output that corresponds to this vault input. +* The parse of the other stack items depends on whether or not this is a recovery spend. + ==== OP_VAULT evaluation for recovery spend ==== * If the recovery output does not have an nValue greater than this input's amount, the script MUST fail and terminate immediately. From 43fa7cf13d3ed35bcd2dd518c2fa0f41a4d2caa7 Mon Sep 17 00:00:00 2001 From: Christian Lewe Date: Sun, 19 Feb 2023 16:16:13 +0100 Subject: [PATCH 048/454] Mark Taproot BIPs as Final --- README.mediawiki | 6 +++--- bip-0340.mediawiki | 2 +- bip-0341.mediawiki | 2 +- bip-0342.mediawiki | 2 +- 4 files changed, 6 insertions(+), 6 deletions(-) diff --git a/README.mediawiki b/README.mediawiki index f4a9ac027b..cf28af514b 100644 --- a/README.mediawiki +++ b/README.mediawiki @@ -1028,21 +1028,21 @@ Those proposing changes should consider that ultimately consent may rest with th | Schnorr Signatures for secp256k1 | Pieter Wuille, Jonas Nick, Tim Ruffing | Standard -| Draft +| Final |- | [[bip-0341.mediawiki|341]] | Consensus (soft fork) | Taproot: SegWit version 1 spending rules | Pieter Wuille, Jonas Nick, Anthony Towns | Standard -| Draft +| Final |- | [[bip-0342.mediawiki|342]] | Consensus (soft fork) | Validation of Taproot Scripts | Pieter Wuille, Jonas Nick, Anthony Towns | Standard -| Draft +| Final |- style="background-color: #ffffcf" | [[bip-0343.mediawiki|343]] | Consensus (soft fork) diff --git a/bip-0340.mediawiki b/bip-0340.mediawiki index 8128650cc0..c99b77aa34 100644 --- a/bip-0340.mediawiki +++ b/bip-0340.mediawiki @@ -6,7 +6,7 @@ Tim Ruffing Comments-Summary: No comments yet. Comments-URI: https://github.com/bitcoin/bips/wiki/Comments:BIP-0340 - Status: Draft + Status: Final Type: Standards Track License: BSD-2-Clause Created: 2020-01-19 diff --git a/bip-0341.mediawiki b/bip-0341.mediawiki index 8d2af3ccc6..8a4f1a6767 100644 --- a/bip-0341.mediawiki +++ b/bip-0341.mediawiki @@ -7,7 +7,7 @@ Anthony Towns Comments-Summary: No comments yet. Comments-URI: https://github.com/bitcoin/bips/wiki/Comments:BIP-0341 - Status: Draft + Status: Final Type: Standards Track Created: 2020-01-19 License: BSD-3-Clause diff --git a/bip-0342.mediawiki b/bip-0342.mediawiki index bbefcaaa11..64d07cc2a0 100644 --- a/bip-0342.mediawiki +++ b/bip-0342.mediawiki @@ -7,7 +7,7 @@ Anthony Towns Comments-Summary: No comments yet. Comments-URI: https://github.com/bitcoin/bips/wiki/Comments:BIP-0342 - Status: Draft + Status: Final Type: Standards Track Created: 2020-01-19 License: BSD-3-Clause From 58cbc4e9b1c73995b9972b06b46693a313b26dfa Mon Sep 17 00:00:00 2001 From: James O'Beirne Date: Tue, 21 Feb 2023 11:40:31 -0500 Subject: [PATCH 049/454] vaults: various feedback MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Thanks to Vojtěch Strnad for most of this. --- bip-vaults.mediawiki | 38 ++++++++++++++++++++------------------ 1 file changed, 20 insertions(+), 18 deletions(-) diff --git a/bip-vaults.mediawiki b/bip-vaults.mediawiki index c5738a0672..fcd16c870e 100644 --- a/bip-vaults.mediawiki +++ b/bip-vaults.mediawiki @@ -68,9 +68,9 @@ key winds up being ''too'' highly secure. Institutional custodians of Bitcoin would likely use vaults in similar fashion. -===== Avoiding the $5 wrench attack ===== +===== Provable timelocks ===== -This proposal uniquely provides a solution to the +This proposal provides a solution to the [https://web.archive.org/web/20230210123933/https://xkcd.com/538/ "$5 wrench attack."] By setting the spend delay to, say, a week, and using as the recovery path a script that enforces a longer relative timelock, the owner of the vault can @@ -122,8 +122,8 @@ Having a "general" covenant mechanism that can encode arbitrary transactional state machines would allow us to solve these issues, but at the cost of complex and large scripts that would probably be duplicated many times over in the blockchain. The particular design and deployment timeline of such a general -framework is also uncertain. There are no sample vault implementations using -these means known to the author. +framework is also uncertain. This approach was demonstrated +[https://blog.blockstream.com/en-covenants-in-elements-alpha/ in 2016]. This proposal intends to address the problems outlined above by providing a delay period/recovery path use with minimal transactional and @@ -135,7 +135,7 @@ The design goals of the proposal are: * '''batched operations''' for recovery and withdrawal to allow managing multiple vault coins efficiently. -* '''unbounded partial withdrawals''', which allows users to withdrawal partial vault balances without having to perform the setup ceremony for a new vault. +* '''unbounded partial withdrawals''', which allows users to withdraw partial vault balances without having to perform the setup ceremony for a new vault. * '''dynamic unvault targets''', which allow the proposed withdrawal target for a vault to be specified at withdrawal time rather than when the vault is first created. This would remove the need for a prespecified, intermediate wallet that only exists to route unvaulted funds to their desired destination. @@ -145,7 +145,7 @@ These goals are accompanied by basic safety considerations (e.g. not being vulnerable to pinning) and a desire for concision, both in terms of the number of outputs created as well as script sizes. -This proposal is designed to be compatible with any future sighash modes (e.g. SIGHASH_GROUP) or fee management strategies (e.g. [https://lists.linuxfoundation.org/pipermail/bitcoin-dev/2020-September/018168.html transaction sponsors]) that may be introduced. Use of these opcodes will benefit from, but do not strictly rely on, future transaction versions (e.g. [https://lists.linuxfoundation.org/pipermail/bitcoin-dev/2022-September/020937.html v3]) and [https://github.com/instagibbs/bips/blob/ephemeral_anchor/bip-ephemeralanchors.mediawik ephemeral anchors]. +This proposal is designed to be compatible with any future sighash modes (e.g. SIGHASH_GROUP) or fee management strategies (e.g. [https://lists.linuxfoundation.org/pipermail/bitcoin-dev/2020-September/018168.html transaction sponsors]) that may be introduced. Use of these opcodes will benefit from, but do not strictly rely on, [https://lists.linuxfoundation.org/pipermail/bitcoin-dev/2022-September/020937.html v3 transaction relay] and [https://github.com/instagibbs/bips/blob/ephemeral_anchor/bip-ephemeralanchors.mediawiki ephemeral anchors]. == Design == @@ -249,11 +249,9 @@ The tapscript opcodes OP_SUCCESS187 (0xbb) and ==== Witness program ==== When evaluating OP_VAULT (OP_SUCCESS187, -0xbb), the witness program is pushed onto the stack for the -following result (stack shown top to bottom): +0xbb), the expected format of the stack, shown top to bottom, is: -OP_VAULT (*) being evaluated @@ -262,7 +260,7 @@ OP_VAULT (*) being evaluated where * is a 32 byte tagged hash of the scriptPubKey used to authorize the spend of this output into an OP_UNVAULT trigger output -** tagged_hash("VaultTriggerSPK", spk), per BIP-0340. +** tagged_hash("VaultTriggerSPK", ), per BIP-0340. ** If this value is not 32 bytes, script execution when spending this output MUST fail and terminate immediately. ** Because this parameter's scriptPubKey is committed to using a hash, witness version upgradeability for the trigger key is preserved. @@ -301,12 +299,8 @@ where ==== OP_VAULT evaluation for recovery spend ==== -* If the recovery output does not have an nValue greater than this input's amount, the script MUST fail and terminate immediately. -* (Deferred) if the recovery output does not have an nValue equal to the sum of all OP_VAULT/OP_UNVAULT inputs with a corresponding recovery sPK hash, the transaction validation MUST fail.'''How do recovery transactions pay for fees?''' If the recovery is unauthorized, fees are attached either via CPFP with an ephemeral anchor or as inputs which are solely spent to fees (i.e. no change output). If the recovery is authorized, fees can be attached in any manner, e.g. unrelated inputs and outputs or CPFP via anchor. -** Note that in the draft implementation, this is facilitated by a "deferred check" which is queued by the script interpreter, but executed after the script interpreter has finished, in other validation code.'''Why does this proposal require a "deferred checks" framework for correct script evaluation?''' The deferred checks framework is an augmentation to execution of the Bitcoin script interpreter. Currently, the validity of each input is checked in an order-indepdendent manner across all inputs in a transaction. Because this proposal allows batching the spend of multiple vault inputs into a single recovery or withdrawal output, we need a mechanism to ensure that all expected values per output can be summed and then checked. This necessitates the introduction of an "aggregating" set of checks which can only be executed after each input's script is evaluated. Note that similar functionality would be required for batch input validation or cross-input signature aggregation. -* The script must FAIL (by policy, not consensus) and terminate immediately if neither'''Why are recovery transactions required to be replaceable?''' In the case of unauthorized recoveries, an attacker may attempt to pin recovery transactions by broadcasting a "rebundled" version with a low fee rate. Vault owners must be able to overcome this with replacement. In the case of authorized recovery, if an attacker steals the recovery authorization key, the attacker may try to pin the recovery transaction during theft. Requiring replaceability ensures that the owner can always raise the fee rate of the recovery transaction, even if they are RBF rule #3 griefed in the process. -*# the input is marked as opt-in replaceable by having an nSequence number less than 0xffffffff - 1, per [https://github.com/bitcoin/bips/blob/master/bip-0125.mediawiki BIP-0125], nor -*# the version of the recovery transaction has an nVersion equal to 3. +* If the recovery output does not have an nValue greater than or equal to this input's amount, the script MUST fail and terminate immediately. +* (Deferred'''What is a deferred check and why does this proposal require them for correct script evaluation?''' A deferred check is a validation check that is executed only after all input scripts have been validated, and is based on aggregate information collected during each input's EvalScript run.

Currently, the validity of each input is (usually) checked concurrently across all inputs in a transaction. Because this proposal allows batching the spend of multiple vault inputs into a single recovery or withdrawal output, we need a mechanism to ensure that all expected values per output can be summed and then checked. This necessitates the introduction of an "aggregating" set of checks which can only be executed after each input's script is evaluated. Note that similar functionality would be required for batch input validation or cross-input signature aggregation.
) if the recovery output does not have an nValue equal to the sum of all OP_VAULT/OP_UNVAULT inputs with a corresponding recovery sPK hash, the transaction validation MUST fail.'''How do recovery transactions pay for fees?''' If the recovery is unauthorized, fees are attached either via CPFP with an ephemeral anchor or as inputs which are solely spent to fees (i.e. no change output). If the recovery is authorized, fees can be attached in any manner, e.g. unrelated inputs and outputs or CPFP via anchor. The stack may now have 0 or more elements. Any items on the stack will be used to verify the recovery authorization witness program, if any. @@ -378,9 +372,10 @@ spent. Its presence is optional. For each vault input citing a particular , the output located at vout[] (the "trigger output") must: -* have as its scriptPubKey a witness program version 1 with a single OP_UNVAULT tapscript, having the internal key lift_x(0x0250929b74c1a04954b78b4b6035e97a5e078a5a0f28ec96d547bfee9ace803ac0), per the NUMS point mentioned in [https://github.com/bitcoin/bips/blob/master/bip-0341.mediawiki#user-content-Design BIP-0341].'''Why must the OP_UNVAULT taproot use a NUMS point as its internal key?''' This ensures that an OP_UNVAULT trigger output is verifiable as expected. It also ensures that it is spendable only by the conditions of the vault. +* have as its scriptPubKey a witness program with a single OP_UNVAULT tapscript, having the internal x-only key 0x0250929b74c1a04954b78b4b6035e97a5e078a5a0f28ec96d547bfee9ace803ac0, per the NUMS point mentioned in [https://github.com/bitcoin/bips/blob/master/bip-0341.mediawiki#constructing-and-spending-taproot-outputs BIP-0341].'''Why must the OP_UNVAULT taproot use a predefined NUMS point as its internal key?''' This ensures that an OP_UNVAULT trigger output is verifiable as expected. It also ensures that it is spendable only by the conditions of the vault. ** If the witness program has a version less than 1, the script MUST fail and terminate immediately. -** If the scriptPubKey of the output does not match the expected scriptPubKey, as computed by creating a taproot output using the cited NUMS point and a single tapscript spend condition of the form
OP_UNVAULT,
the script MUST fail and terminate immediately. +** If the witness program has a version greater than 1, the script MUST succeed to enable upgradeability. +** If the witness program has a version of 1 and the scriptPubKey of the output does not match the expected scriptPubKey, as computed by creating a taproot output using the cited NUMS point and a single tapscript spend condition of the form
OP_UNVAULT,
the script MUST fail and terminate immediately. ** Witness versions greater than 1 are allowed for upgradeability. * If there does not exist a revault output in the transaction for this input: @@ -486,6 +481,13 @@ def serialize_txout(txo: CTxOut) -> bytes: If the above conditions do not fail, a single true value (0x01) is pushed to the stack. +== Policy changes == + +In order to prevent possible pinning attacks, recovery transactions must be replaceable. + +* When validating an OP_VAULT/OP_UNVAULT input being spent towards a recovery, the script must FAIL (by policy, not consensus) and terminate immediately if neither'''Why are recovery transactions required to be replaceable?''' In the case of unauthorized recoveries, an attacker may attempt to pin recovery transactions by broadcasting a "rebundled" version with a low fee rate. Vault owners must be able to overcome this with replacement. In the case of authorized recovery, if an attacker steals the recovery authorization key, the attacker may try to pin the recovery transaction during theft. Requiring replaceability ensures that the owner can always raise the fee rate of the recovery transaction, even if they are RBF rule #3 griefed in the process. +*# the input is marked as opt-in replaceable by having an nSequence number less than 0xffffffff - 1, per [https://github.com/bitcoin/bips/blob/master/bip-0125.mediawiki BIP-0125], nor +*# the version of the recovery transaction has an nVersion equal to 3. == Implementation == From 0204c9a1f9a9075f2483450f1bab034d453270b7 Mon Sep 17 00:00:00 2001 From: James O'Beirne Date: Tue, 21 Feb 2023 11:58:11 -0500 Subject: [PATCH 050/454] vaults: make recovery output structure a matter of policy Since constraints on unauthorized recovery transaction structure exist only to avoid pinning, make them a matter of policy and not consensus. --- bip-vaults.mediawiki | 28 +++++++++++++--------------- 1 file changed, 13 insertions(+), 15 deletions(-) diff --git a/bip-vaults.mediawiki b/bip-vaults.mediawiki index fcd16c870e..c9af765479 100644 --- a/bip-vaults.mediawiki +++ b/bip-vaults.mediawiki @@ -259,10 +259,9 @@ When evaluating OP_VAULT (OP_SUCCESS187, where -* is a 32 byte tagged hash of the scriptPubKey used to authorize the spend of this output into an OP_UNVAULT trigger output +* is a 32 byte tagged hash of the scriptPubKey used to authorize the spend of this output into an OP_UNVAULT trigger outputBecause the trigger scriptPubKey is committed to using a hash, witness version upgradeability for the trigger key is preserved. ** tagged_hash("VaultTriggerSPK", ), per BIP-0340. ** If this value is not 32 bytes, script execution when spending this output MUST fail and terminate immediately. -** Because this parameter's scriptPubKey is committed to using a hash, witness version upgradeability for the trigger key is preserved. * is a CScriptNum-encoded number (up to 4 bytes) ** It is interpreted as the least significant 23 bits of a [https://github.com/bitcoin/bips/blob/master/bip-0068.mediawiki BIP-0068] relative timelock. @@ -270,12 +269,10 @@ where ** If this value is less than 0, script execution when spending this output MUST fail and terminate immediately. * is a variable length data push, consisting of two components: -*# a 32 byte tagged hash, the ''recovery sPK hash'', committing to the scriptPubKey which coins may be recovered to -*#* tagged_hash("VaultRecoverySPK", spk) from the [https://github.com/bitcoin/bips/blob/master/bip-0340/reference.py BIP-0340 reference code]. -*# 0 or more bytes that optionally specify a scriptPubKey that needs to be satisfied to authorize the recovery transaction. -*#* This optional parameter changes the allowable structure of recovery transactions. +*# a 32 byte tagged hash, the ''recovery sPK hash''Because the recovery scriptPubKey is committed to with a hash, witness version upgradeability is preserved., committing to the scriptPubKey which coins may be recovered to +*#* tagged_hash("VaultRecoverySPK", ) from the [https://github.com/bitcoin/bips/blob/master/bip-0340/reference.py BIP-0340 reference code]. +*# 0 or more bytes that optionally specify a scriptPubKey that needs to be satisfied to authorize the recovery transaction, referred to as . ** If is less than 32 bytes, script execution when spending this output MUST fail and terminate immediately. -** Because the recovery scriptPubKey is committed to with a hash, witness version upgradeability is preserved. ==== Witness stack ==== @@ -302,17 +299,11 @@ where * If the recovery output does not have an nValue greater than or equal to this input's amount, the script MUST fail and terminate immediately. * (Deferred'''What is a deferred check and why does this proposal require them for correct script evaluation?''' A deferred check is a validation check that is executed only after all input scripts have been validated, and is based on aggregate information collected during each input's EvalScript run.

Currently, the validity of each input is (usually) checked concurrently across all inputs in a transaction. Because this proposal allows batching the spend of multiple vault inputs into a single recovery or withdrawal output, we need a mechanism to ensure that all expected values per output can be summed and then checked. This necessitates the introduction of an "aggregating" set of checks which can only be executed after each input's script is evaluated. Note that similar functionality would be required for batch input validation or cross-input signature aggregation.
) if the recovery output does not have an nValue equal to the sum of all OP_VAULT/OP_UNVAULT inputs with a corresponding recovery sPK hash, the transaction validation MUST fail.'''How do recovery transactions pay for fees?''' If the recovery is unauthorized, fees are attached either via CPFP with an ephemeral anchor or as inputs which are solely spent to fees (i.e. no change output). If the recovery is authorized, fees can be attached in any manner, e.g. unrelated inputs and outputs or CPFP via anchor. -The stack may now have 0 or more elements. Any items on the stack will be used to verify the recovery authorization witness program, if any. +The stack may now have 0 or more elements. Any items on the stack will be used to verify the witness program, if any. -* If the ''recovery authorization sPK'' is not null: +* If is not null: ** If VerifyWitnessProgram(, , ...) fails, the script MUST fail and terminate immediately. ** (This validates that the recovery has been authorized.) -* else (if the recovery is allowed to be unauthorized): -** If the spending transaction has more than two outputs, the script MUST fail and terminate immediately. -** If the spending transaction has two outputs, and the output not the recovery output is not an ephemeral anchor, the script MUST fail and terminate immediately.'''Why can unauthorized recoveries only process a single recovery path?''' Because there is no signature required for unauthorized recoveries, if additional outputs were allowed, someone observing a recovery in the mempool would be able to rebundle and broadcast the recovery with a lower fee rate. - - -(Note: the above rules imply that if all inputs have a recovery authorization sPK specified, the structure of the recovery transaction is "free form," and the only requirement is that for each OP_VAULT/OP_UNVAULT input, there exists a compatible ''recovery output'' which preserves its full nValue.) If none of the conditions fail, a single true value (0x01) is left on the stack. @@ -489,6 +480,13 @@ In order to prevent possible pinning attacks, recovery transactions must be repl *# the input is marked as opt-in replaceable by having an nSequence number less than 0xffffffff - 1, per [https://github.com/bitcoin/bips/blob/master/bip-0125.mediawiki BIP-0125], nor *# the version of the recovery transaction has an nVersion equal to 3. +In order to prevent pinning attacks in the case of unauthorized recovery, the output structure of unauthorized recovery +transaction is limited. + +* If (as determined from ) is null, the recovery transaction MUST (by policy) abide by the following constraints: +** If the spending transaction has more than two outputs, the script MUST fail and terminate immediately. +** If the spending transaction has two outputs, and the output not the recovery output is not an ephemeral anchor, the script MUST fail and terminate immediately.'''Why can unauthorized recoveries only process a single recovery path?''' Because there is no signature required for unauthorized recoveries, if additional outputs were allowed, someone observing a recovery in the mempool would be able to rebundle and broadcast the recovery with a lower fee rate. + == Implementation == A sample implementation is available [https://github.com/jamesob/bitcoin/tree/2023-01-opvault here], with an associated [https://github.com/bitcoin/bitcoin/pull/26857 pull request]. From f4a05c1ced66f9f6a10fb1d741648dbe5be10301 Mon Sep 17 00:00:00 2001 From: Christian Lewe Date: Tue, 21 Feb 2023 22:05:30 +0100 Subject: [PATCH 051/454] Mark BIP 343 as Final --- README.mediawiki | 2 +- bip-0343.mediawiki | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/README.mediawiki b/README.mediawiki index cf28af514b..489900c4ae 100644 --- a/README.mediawiki +++ b/README.mediawiki @@ -1049,7 +1049,7 @@ Those proposing changes should consider that ultimately consent may rest with th | Mandatory activation of taproot deployment | Shinobius, Michael Folkson | Standard -| Proposed +| Final |- | [[bip-0350.mediawiki|350]] | Applications diff --git a/bip-0343.mediawiki b/bip-0343.mediawiki index 3d2f392560..a47edc05f2 100644 --- a/bip-0343.mediawiki +++ b/bip-0343.mediawiki @@ -6,7 +6,7 @@ Michael Folkson Comments-Summary: No comments yet. Comments-URI: https://github.com/bitcoin/bips/wiki/Comments:BIP-0343 - Status: Proposed + Status: Final Type: Standards Track Created: 2021-04-25 License: BSD-3-Clause From 6ff8efd3d195cf46b9353af3ad49886a50eda734 Mon Sep 17 00:00:00 2001 From: James O'Beirne Date: Tue, 21 Feb 2023 16:08:23 -0500 Subject: [PATCH 052/454] vaults: blank deployment --- bip-vaults.mediawiki | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/bip-vaults.mediawiki b/bip-vaults.mediawiki index c9af765479..63aadfd40d 100644 --- a/bip-vaults.mediawiki +++ b/bip-vaults.mediawiki @@ -633,8 +633,7 @@ Script descriptors for vault-related outputs will be covered in a subsequent BIP == Deployment == -It is anticipated that deployment would happen in the same way [https://github.com/bitcoin/bips/blob/master/bip-0341.mediawiki#user-content-Deployment that BIP-0341 was deployed]. Parameters to be determined. - +TBD == Rationale == From 24241ee26bc59a3d3f094190030865d921f553f4 Mon Sep 17 00:00:00 2001 From: Jameson Lopp Date: Wed, 22 Feb 2023 07:27:03 -0600 Subject: [PATCH 053/454] typos / gramma cleanup --- bip-vaults.mediawiki | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/bip-vaults.mediawiki b/bip-vaults.mediawiki index 63aadfd40d..5a91447f4d 100644 --- a/bip-vaults.mediawiki +++ b/bip-vaults.mediawiki @@ -27,7 +27,7 @@ the prespecified path. The hazard of custodying Bitcoin is well known. Users of Bitcoin must go to significant effort to secure their private keys, and hope that once provisioned their custody system does not yield to any number of evolving and -persistent threats. Users have little means to intervene once compromise is +persistent threats. Users have little means to intervene once a compromise is detected. This proposal introduces a mechanism that significantly mitigates the worst-case outcome of key compromise: coin loss. @@ -94,12 +94,12 @@ key. This approach was first demonstrated [https://lists.linuxfoundation.org/pipermail/bitcoin-dev/2020-April/017755.html in 2020]. Unfortunately, this approach has a number of practical shortcomings: -* generating and securely delete ephemeral keys, which are used to emulate the vault covenant, is required, +* generating and securely deleting ephemeral keys, which are used to emulate the vault covenant, is required, * amounts and withdrawal patterns must be precommitted to, * there is a necessity to precommit to an address that the funds must pass through on their way to the final withdrawal target, which is likely only known at unvault time, * the particular fee management technique or wallet must be decided upon vault creation, * coin loss follows if a vault address is reused, -* the transaction data that represents the "bearer asset" of the vault must be stored for perpetuity else value is lost, and +* the transaction data that represents the "bearer asset" of the vault must be stored for perpetuity, otherwise value is lost, and * the vault creation ceremony must be performed each time a new balance is to be deposited. The deployment of a "precomputed" covenant mechanism like @@ -157,7 +157,7 @@ The vault has a number of stages, some of them optional: * '''vault transaction''': encumbers some coins with an OP_VAULT script invocation. -* '''trigger transaction''': spends one or more OP_VAULT inputs into an OP_UNVAULT output which carries forward the same recovery and delay parameters, along with a commitment to the proposed withdrawal target outputs. This publicly broadcasts the intent to withdrawal to some specific set of outputs. This transaction may have an additional output which allocates some of the vault balance into a partial revault, which simply encumbers the revaulted portion of the value into the same scriptPubKey of the originating OP_VAULT output(s). +* '''trigger transaction''': spends one or more OP_VAULT inputs into an OP_UNVAULT output which carries forward the same recovery and delay parameters, along with a commitment to the proposed withdrawal target outputs. This publicly broadcasts the intent to withdraw to some specific set of outputs. This transaction may have an additional output which allocates some of the vault balance into a partial revault, which simply encumbers the revaulted portion of the value into the same scriptPubKey of the originating OP_VAULT output(s). * '''withdrawal transaction''': spends OP_UNVAULT trigger inputs into a compatible set of final withdrawal outputs per the target hash, after the trigger inputs have matured per the spend delay. The only authorization for this spend (aside from the relative timelock) is the content hash of the withdrawal outputs. @@ -224,7 +224,7 @@ An arbitrary set of target withdrawal outputs that is specified as a parameter t A primary consideration of this proposal is how fee management is handled. Providing dynamic fee management is critical to the operation of a vault, since -* precalculated fees are prone to making transactions unconfirmable by high fee environments, and +* precalculated fees are prone to making transactions unconfirmable in high fee environments, and * a fee wallet that is prespecified might be compromised or lost before use. But dynamic fee management can introduce @@ -416,7 +416,7 @@ def find_revault_for_vault(vault_in) -> int: return None -=== OP_UNVAULT evaulation === +=== OP_UNVAULT evaluation === ==== Witness program ==== From be78b633e3561ba0f9b0696d2acd0b2c16067c8c Mon Sep 17 00:00:00 2001 From: cmd Date: Thu, 23 Feb 2023 09:11:04 -0600 Subject: [PATCH 054/454] Update bip-0370.mediawiki Small typo. Changed 'gemeric' to 'generic'. --- bip-0370.mediawiki | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/bip-0370.mediawiki b/bip-0370.mediawiki index 7ba0af4ccd..b3f65ffb9f 100644 --- a/bip-0370.mediawiki +++ b/bip-0370.mediawiki @@ -288,7 +288,7 @@ The Extractor should produce a fully valid, network serialized transaction if al ==Backwards Compatibility== -PSBTv2 shares the same gemeric format as PSBTv0 as defined in BIP 174. Parsers for PSBTv0 should +PSBTv2 shares the same generic format as PSBTv0 as defined in BIP 174. Parsers for PSBTv0 should be able to deserialize PSBTv2 with only changes to support the new fields. However PSBTv2 is incompatible with PSBTv0, and vice versa due to the use of the PSBT_GLOBAL_VERSION. From ee8a4a3bc5ac4b7cc8c5a6610bf30b42ece2ad20 Mon Sep 17 00:00:00 2001 From: dhruv <856960+dhruv@users.noreply.github.com> Date: Tue, 28 Feb 2023 09:53:19 -0800 Subject: [PATCH 055/454] Updates to BIP324 since January 11 2023 --- bip-0324.mediawiki | 89 ++++++++++++++++++++-------------------------- 1 file changed, 39 insertions(+), 50 deletions(-) diff --git a/bip-0324.mediawiki b/bip-0324.mediawiki index 47032ddccb..c0572a3313 100644 --- a/bip-0324.mediawiki +++ b/bip-0324.mediawiki @@ -31,7 +31,7 @@ Bitcoin is a permissionless network whose purpose is to reach consensus over pub This proposal for a new P2P protocol version (v2) aims to improve upon this by raising the costs for performing these attacks substantially, primarily through the use of unauthenticated, opportunistic transport encryption. In addition, the bytestream on the wire is made pseudorandom (i.e., indistinguishable from uniformly random bytes) to a passive eavesdropper. -* Encryption, even when it is unauthenticated and only used when both endpoints support v2, impedes eavesdropping by forcing the attacker to become active: either by performing a persistent man-in-the-middle (MitM) attack, by downgrading connections to v1, or by spinning up their own nodes and getting honest nodes to make connections to them. Active attacks at scale are more resource intensive in general, but in case of manual, deliberate connections (as opposed to automatic, random ones) they are also in principle detectable: even very basic checks, e.g., operators manually comparing protocol versions and session IDs (as supported by the proposed protocol), will expose the attacker. +* Encryption, even when it is unauthenticated and only used when both endpoints support v2, impedes eavesdropping by forcing the attacker to become active: either by performing a persistent man-in-the-middle (MitM) attack, by downgrading connections to v1, or by spinning up their own nodes and getting honest nodes to make connections to them. Active attacks at scale are more resource intensive in general, but in the case of manual, deliberate connections (as opposed to automatic, random ones), they are also in principle detectable: even very basic checks, e.g., operators manually comparing protocol versions and session IDs (as supported by the proposed protocol), will expose the attacker. * Tampering, while already an inherently active attack, is costlier if the attacker is forced to maintain the state necessary for a full MitM interception. * A pseudorandom bytestream excludes identification techniques based on pattern matching, and makes it easier to shape the bytestream in order to mimic other protocols used on the Internet. This raises the cost of a connection censoring firewall, forcing them to either resort to a full MitM attack, or operate on a more obvious allowlist basis, rather than a blocklist basis. @@ -39,7 +39,7 @@ This proposal for a new P2P protocol version (v2) aims to improve upon this by r As we have argued above, unauthenticated encryption'''What does ''authentication'' mean in this context?''' Unfortunately, the term authentication in the context of secure channel protocols is ambiguous. It can refer to: * The encryption scheme guaranteeing that a message obtained via successful decryption was encrypted by someone having access to the (symmetric) encryption key, and not modified after encryption by a third party. The proposal in this document achieves that property through the use of an AEAD. -* The communication protocol establishing that the communication partner's identity matches who we expect them to be, through some public key mechanism. The proposal in this document does '''not''' include such a mechanism. provides strictly better security than no encryption. Thus all connections should use encryption, even if they are unauthenticated. +* The communication protocol establishing that the communication partner's identity matches who we expect them to be, through some public key mechanism. The proposal in this document does '''not''' include such a mechanism. provides strictly better security than no encryption. Thus, all connections should use encryption, even if they are unauthenticated. When it comes to authentication, the situation is not as clear as for encryption. Due to Bitcoin's permissionless nature, authentication will always be restricted to specific scenarios (e.g., connections between peers belonging to the same operator), and whether some form of (possibly partially anonymous) authentication is desired depends on the specific requirements of the involved peers. As a consequence, we believe that authentication should be addressed separately (if desired), and this proposal aims to provide a solid technical basis for future protocol upgrades, including the addition of optional authentication (see [https://github.com/sipa/writeups/tree/main/private-authentication-protocols Private authentication protocols]). @@ -51,9 +51,9 @@ A pseudorandom bytestream is not self-identifying. Moreover, it is unopinionated ''' Why not use a secure tunnel protocol? ''' -Our goal includes making opportunistic encryption ubiquitously available, as that provides the best defense against large-scale attacks. That implies protecting both the manual, deliberate connections node operators instruct their software to make, as well as the the automatic connections Bitcoin nodes make with each other based on IP addresses obtained via gossip. While encryption per se is already possible with proxy networks or VPN networks, these are not desirable or applicable for automatic connections at scale: -* Proxy networks like Tor or I2P introduce a separate address space, independent from network topology, with a very low cost per address making eclipse attacks cheaper. In comparison, clearnet IPv4 and IPv6 networks make obtaining multiple network identities in distinct, well-known network partitions carry a non-trivial cost. Thus, it is not desirable to have a substantial portion of nodes be exclusively connected this way, as this would significantly reduce Eclipse attack costs.'''Why is it a bad idea to have nodes exclusively connected over Tor?''' See the [https://arxiv.org/abs/1410.6079 Bitcoin over Tor isn't a Good Idea] paper Additionally, Tor connections come with significant bandwidth and latency costs that may not be desirable for all network users. -* VPN networks like WireGuard or OpenVPN inherently define a private network, which requires manual configuration and therefore is not a realistic avenue for automatic connections. +Our goal includes making opportunistic encryption ubiquitously available, as that provides the best defense against large-scale attacks. That implies protecting both the manual, deliberate connections node operators instruct their software to make, and the automatic connections Bitcoin nodes make with each other based on IP addresses obtained via gossip. While encryption per se is already possible with proxy networks or VPN protocols, these are not desirable or applicable for automatic connections at scale: +* Proxy networks like Tor or I2P introduce a separate address space, independent of network topology, with a very low cost per address making eclipse attacks cheaper. In comparison, clearnet IPv4 and IPv6 networks make obtaining multiple network identities in distinct, well-known network partitions carry a non-trivial cost. Thus, it is not desirable to have a substantial portion of nodes be exclusively connected this way, as this would significantly reduce Eclipse attack costs.'''Why is it a bad idea to have nodes exclusively connected over Tor?''' See the [https://arxiv.org/abs/1410.6079 Bitcoin over Tor isn't a Good Idea] paper Additionally, Tor connections come with significant bandwidth and latency costs that may not be desirable for all network users. +* VPN protocols like WireGuard or OpenVPN inherently define a private network, which requires manual configuration and therefore is not a realistic avenue for automatic connections. Thus, to achieve our goal, we need a solution that has minimal costs, works without configuration, and is always enabled – on top of any network layer rather than be part of the network layer. @@ -61,16 +61,16 @@ Thus, to achieve our goal, we need a solution that has minimal costs, works with While it would be possible to rely on an off-the-shelf transport encryption protocol such as TLS or Noise, the specific requirements of the Bitcoin P2P network laid out above make these protocols an unsuitable choice. -The primary requirement which existing protocols fail to meet is a sufficiently modular treatment of encryption and authentication. As we argue above, whether and which form of authentication is desired in the Bitcoin P2P network will depend on the specific requirements of the involved peers (resulting in a mix of authenticated and unauthenticated connections), and thus the question of authentication should be decoupled from encryption. However, native support for a handful of standard authentication scenarios (e.g., using digital signatures and certificates) is at core of the design of existing general-purpose transport encryption protocols. This focus on authentication would not provide clear benefits for the Bitcoin P2P network but would come with a large amount of additional complexity. +The primary requirement which existing protocols fail to meet is a sufficiently modular treatment of encryption and authentication. As we argue above, whether and which form of authentication is desired in the Bitcoin P2P network will depend on the specific requirements of the involved peers (resulting in a mix of authenticated and unauthenticated connections), and thus the question of authentication should be decoupled from encryption. However, native support for a handful of standard authentication scenarios (e.g., using digital signatures and certificates) is at the core of the design of existing general-purpose transport encryption protocols. This focus on authentication would not provide clear benefits for the Bitcoin P2P network but would come with a large amount of additional complexity. -In contrast, our proposal instead aims for simple modular design that makes it possible to address authentication separately. Our proposal provides a foundation for authentication by exporting a ''session ID'' that uniquely identifies the encrypted channel. After an encrypted channel has been established, the two endpoints are able to use any authentication protocol to confirm that they have the same session ID. (This is sometimes called ''channel binding'' because the session ID binds the encrypted channel to the authentication protocol.) Since in our proposal, any authentication needs to run after an encrypted connection has been established, the price we pay for this modularity is a possibly higher number of roundtrips as opposed to other protocols that perform authentication alongside with the Diffie-Hellman key exchange.'''Do other protocols not support exporting a session ID?''' While [https://noiseprotocol.org/noise.html#channel-binding Noise] and [https://datatracker.ietf.org/doc/draft-ietf-kitten-tls-channel-bindings-for-tls13/ TLS (as a draft)] offer similar protocol extensions for exporting session IDs, using channel binding for authentication is not at the focus of their design and would not avoid the bulk of additional complexity due to the native support of authentication methods. However, the resulting increase in connection establishment latency is a not a concern for Bitcoin's long-lived connections, [https://www.dsn.kastel.kit.edu/bitcoin/ which typically live for hours or even weeks]. +In contrast, our proposal instead aims for a simple modular design that makes it possible to address authentication separately. Our proposal provides a foundation for authentication by exporting a ''session ID'' that uniquely identifies the encrypted channel. After an encrypted channel has been established, the two endpoints are able to use any authentication protocol to confirm that they have the same session ID. (This is sometimes called ''channel binding'' because the session ID binds the encrypted channel to the authentication protocol.) Since in our proposal, any authentication needs to run after an encrypted connection has been established, the price we pay for this modularity is a possibly higher number of roundtrips as opposed to other protocols that perform authentication alongside the Diffie-Hellman key exchange.'''Do other protocols not support exporting a session ID?''' While [https://noiseprotocol.org/noise.html#channel-binding Noise] and [https://datatracker.ietf.org/doc/draft-ietf-kitten-tls-channel-bindings-for-tls13/ TLS (as a draft)] offer similar protocol extensions for exporting session IDs, using channel binding for authentication is not at the focus of their design and would not avoid the bulk of additional complexity due to the native support of authentication methods. However, the resulting increase in connection establishment latency is a not a concern for Bitcoin's long-lived connections, [https://www.dsn.kastel.kit.edu/bitcoin/ which typically live for hours or even weeks]. Besides this fundamentally different treatment of authentication, further technical issues arise when applying TLS or Noise to our desired use case: * Neither offers a pseudorandom bytestream. * Neither offers native support for elliptic curve cryptography on the curve secp256k1 as otherwise used in Bitcoin. While using secp256k1 is not strictly necessary, it is the obvious choice is for any new asymmetric cryptography in Bitcoin because it minimizes the cryptographic hardness assumptions as well as the dependencies that Bitcoin software will need. * Neither offers shapability of the bytestream. -* Both provide a stream-based interface to the application layer whereas Bitcoin requires a packet-based interface, resulting in the need for an additional thin layer to perform packet serialization and deserialization. +* Both provide a stream-based interface to the application layer, whereas Bitcoin requires a packet-based interface, resulting in the need for an additional thin layer to perform packet serialization and deserialization. While existing protocols could be amended to address all of the aforementioned issues, this would negate the benefits of using them as off-the-shelf solution, e.g., the possibility to re-use existing implementations and security analyses. @@ -97,7 +97,7 @@ The specification consists of three parts: === Transport layer specification === -In this section we define the encryption protocol for messages between peers. +In this section, we define the encryption protocol for messages between peers. ==== Overview and design ==== @@ -105,7 +105,7 @@ We first give an informal overview of the entire protocol flow and packet encryp '''Protocol flow overview''' -Given a newly-established connection (typically TCP/IP) between two v2 P2P nodes, there are 3 phases the connection goes through. The first starts immediately, i.e. there are no v1 messages or any other bytes exchanged on the link beforehand. The two parties are called the '''initiator''' (who established the connection) and the '''responder''' (who accepted the connection). +Given a newly established connection (typically TCP/IP) between two v2 P2P nodes, there are 3 phases the connection goes through. The first starts immediately, i.e. there are no v1 messages or any other bytes exchanged on the link beforehand. The two parties are called the '''initiator''' (who established the connection) and the '''responder''' (who accepted the connection). # The '''Key exchange phase''', where nodes exchange data to establish shared secrets. #* The initiator: @@ -119,7 +119,7 @@ Given a newly-established connection (typically TCP/IP) between two v2 P2P nodes #** Receive (the remainder of) the full 64-byte public key from the other side. #** Use X-only'''Why use X-only ECDH?''' Using only the X coordinate provides the same security as using a full encoding of the secret curve point but allows for more efficient implementation by avoiding the need for square roots to compute Y coordinates. ECDH to compute a shared secret from their private key and the exchanged public keys'''Why is the shared secret computation a function of the exact 64-byte public encodings sent?''' This makes sure that an attacker cannot modify the public key encoding used without modifying the rest of the stream. If a third party wants the ability to modify stream bytes, they need to perform a full MitM attack on the connection., and deterministically derive from the secret 4 '''encryption keys''' (two in each direction: one for packet lengths, one for content encryption), a '''session id''', and two 16-byte '''garbage terminators''''''What length is sufficient for garbage terminators?''' The length of the garbage terminators determines the probability of accidental termination of a legitimate v2 connection due to garbage bytes (sent prior to ECDH) inadvertently including the terminator. 16 byte terminators with 4095 bytes of garbage yield a negligible probability of such collision which is likely orders of magnitude lower than random connection failure on the Internet.'''What does a garbage terminator in the wild look like?'''

[[File:bip-0324/garbage_terminator.png|none|256px|A garbage terminator model TX-v2 in the wild... sent by the responder]]
(one in each direction) using HKDF-SHA256. -#** Send their 16-byte garbage terminator'''Why does the protocol need a garbage terminator?''' While it is in principle possible to use the garbage authentication packet directly as a terminator (scan until a valid authentication packet follows), this would be significantly slower than just scanning for a fixed byte sequence, as it would require recomputing a Poly1305 tag after every received byte. followed by a '''garbage authentication packet''''''Why does the protocol require a garbage authentication packet?''' Otherwise the garbage would be modifiable by a third party without consequences. We want to force any active attacker to have to maintain a full protocol state. In addition, such malleability without the consequence of connection termination could enable protocol fingerprinting., an '''encrypted packet''' (see further) with arbitrary '''contents''', and '''associated data''' equal to the garbage. +#** Send their 16-byte garbage terminator'''Why does the protocol need a garbage terminator?''' While it is in principle possible to use the garbage authentication packet directly as a terminator (scan until a valid authentication packet follows), this would be significantly slower than just scanning for a fixed byte sequence, as it would require recomputing a Poly1305 tag after every received byte. followed by a '''garbage authentication packet''''''Why does the protocol require a garbage authentication packet?''' Without the garbage authentication packet, the garbage would be modifiable by a third party without consequences. We want to force any active attacker to have to maintain a full protocol state. In addition, such malleability without the consequence of connection termination could enable protocol fingerprinting., an '''encrypted packet''' (see further) with arbitrary '''contents''', and '''associated data''' equal to the garbage. #** Receive up to 4111 bytes, stopping when encountering the garbage terminator. #** Receive an encrypted packet, verify that it decrypts correctly with associated data set to the garbage received, and then ignore its contents. #* At this point, both parties have the same keys, and all further communication proceeds in the form of encrypted packets. Packets have an '''ignore bit''', which makes them '''decoy packets''' if set. Decoy packets are to be ignored by the receiver apart from verifying they decrypt correctly. Either peer may send such decoy packets at any point after this. These form the primary shapability mechanism in the protocol. How and when to use them is out of scope for this document. @@ -134,7 +134,7 @@ Given a newly-established connection (typically TCP/IP) between two v2 P2P nodes # The '''Application phase''', where the packets exchanged have contents to be interpreted as application data. #* Whenever either peer has a message to send, it sends a packet with that application message as '''contents'''. -In order to provide a means of avoiding the recognizable pattern of first messages being at least 64 bytes, a future backwards-compatible upgrade to this protocol may allow both peers to send their public key + garbage + garbage terminator in multiple rounds, slicing those bytes up into messages arbitrarily, as long as progress is guaranteed.'''How can progress be guaranteed in a backwards-compatible way?''' In order to guarantee progress, it must be ensured that no deadlock occurs, i.e., no state is reached in which each party waits for the other party indefinitely. For example, any upgrade that adheres to the following conditions will guarantee progress: +To avoid the recognizable pattern of first messages being at least 64 bytes, a future backwards-compatible upgrade to this protocol may allow both peers to send their public key + garbage + garbage terminator in multiple rounds, slicing those bytes up into messages arbitrarily, as long as progress is guaranteed.'''How can progress be guaranteed in a backwards-compatible way?''' In order to guarantee progress, it must be ensured that no deadlock occurs, i.e., no state is reached in which each party waits for the other party indefinitely. For example, any upgrade that adheres to the following conditions will guarantee progress: * The initiator must start by sending at least as many bytes as necessary to mismatch the magic/version 12 bytes prefix. * The responder must start sending after having received at least one byte that mismatches that 12-byte prefix. @@ -157,19 +157,19 @@ All data on the wire after the garbage terminators takes the form of encrypted p Each packet consists of: * A 3-byte encrypted '''length''' field, encoding the length of the '''contents''' (between ''0'' and ''224-1'''''Is ''224-1'' bytes sufficient as maximum content size?''' The current Bitcoin P2P protocol has no messages which support more than 4000000 bytes of application payload. By supporting up to ''224-1'' we can accommodate future evolutions needing more than 4 times that value. Hypothetical protocol changes that have even more data to exchange than that should probably use multiple separate messages anyway, because of the per-peer receive buffer sizes involved, and the inability to start processing a message before it is fully received. Of course, future versions of the transport protocol could change the size of the length field, if this were really needed., inclusive). * An authenticated encryption of the '''plaintext''', which consists of: -** A 1-byte '''header''' which consists of transport layer protocol flags. Currently only the highest bit is defined as the '''ignore bit'''. The other bits are ignored, but this may change in future versions'''Why is the header a part of the plaintext and not included alongside the length field?''' The packet length field is the minimum information that must be available before we can leverage the standard RFC8439 AEAD. Any other data, including metadata like the header being in the content encryption makes it easier to reason about the protocol security w.r.t. data being used before it is authenticated. If the ignore bit was not part of the content, another mechanism would be needed to authenticate it; for example, it could be fed as AAD to the AEAD cipher. We feel the complexity of such an approach outweighs the benefit of saving one byte per message.. +** A 1-byte '''header''' which consists of transport layer protocol flags. Currently, only the highest bit is defined as the '''ignore bit'''. The other bits are ignored, but this may change in future versions'''Why is the header a part of the plaintext and not included alongside the length field?''' The packet length field is the minimum information that must be available before we can leverage the standard RFC8439 AEAD. Any other data, including metadata like the header being in the content encryption makes it easier to reason about the protocol security w.r.t. data being used before it is authenticated. If the ignore bit was not part of the content, another mechanism would be needed to authenticate it; for example, it could be fed as AAD to the AEAD cipher. We feel the complexity of such an approach outweighs the benefit of saving one byte per message.. ** The variable-length '''contents'''. -The encryption of the plaintext uses '''[https://en.wikipedia.org/wiki/ChaCha20-Poly1305 ChaCha20Poly1305]''''''Why is ChaCha20Poly1305 chosen as basis for packet encryption?''' It is a very widely used authenticated encryption cipher (used amongst others in SSH, TLS 1.2, TLS 1.3, [https://en.wikipedia.org/wiki/QUIC QUIC], Noise, and [https://www.wireguard.com/protocol/ WireGuard]; in the latter it is currently even the only supported cipher), with very good performance in general purpose software implementations. While AES-based ciphers (including the winners in the [https://competitions.cr.yp.to/caesar.html CAESAR] competition in non-lightweight categories) perform significantly better on systems with AES hardware acceleration, they are also significantly slower in pure software implementations. We choose to optimize for the weakest hardware., an [https://en.wikipedia.org/wiki/Authenticated_encryption authenticated encryption with associated data] (AEAD) cipher specified in [https://datatracker.ietf.org/doc/html/rfc8439 RFC 8439]. Every packet's plaintext is treated as a separate AEAD message, with a different nonce for each. +The encryption of the plaintext uses '''[https://en.wikipedia.org/wiki/ChaCha20-Poly1305 ChaCha20Poly1305]''''''Why is ChaCha20Poly1305 chosen as the basis for packet encryption?''' It is a very widely used authenticated encryption cipher (used among others in SSH, TLS 1.2, TLS 1.3, [https://en.wikipedia.org/wiki/QUIC QUIC], Noise, and [https://www.wireguard.com/protocol/ WireGuard]; in the latter it is currently even the only supported cipher), with very good performance in general purpose software implementations. While AES-based ciphers (including the winners in the [https://competitions.cr.yp.to/caesar.html CAESAR] competition in non-lightweight categories) perform significantly better on systems with AES hardware acceleration, they are also significantly slower in pure software implementations. We choose to optimize for the weakest hardware., an [https://en.wikipedia.org/wiki/Authenticated_encryption authenticated encryption with associated data] (AEAD) cipher specified in [https://datatracker.ietf.org/doc/html/rfc8439 RFC 8439]. Every packet's plaintext is treated as a separate AEAD message, with a different nonce for each. The length must be dealt with specially, as it is needed to determine packet boundaries before the whole packet is received and authenticated. As we want a stream that is pseudorandom to a passive attacker, it still needs encryption. We use unauthenticated'''Why is the length encryption not separately authenticated?''' Informally, the relevant security goal we aim for is to hide the number of packets and their lengths (i.e., the packet boundaries) against a passive attacker that receives the bytestream without timing or fragmentation information. (A formal definition can be found for example in [https://himsen.github.io/pdf/thesis.pdf Hansen 2016 (Definition 22)] under the name "boundary hiding against chosen-plaintext attacks (BH-CPA)".) However, we do not aim to hide packet boundaries against active attackers because active attackers can always exploit the fact that the Bitcoin P2P protocol is largely query-response based: they can trickle the bytes on the stream one-by-one unmodified and observe when a response comes (see [https://himsen.github.io/pdf/thesis.pdf Hansen 2016 (Section 3.9)] for a in-depth discussion). With that in mind, we accept that an active (non-MitM) attacker is able to figure out some information about packet boundaries by flipping certain bits in the unauthenticated length field, and observing the other side disconnecting immediately or later. Thus, we choose to use unauthenticated encryption for the length data, which is sufficient to achieve boundary hiding against passive attackers, and saves 16 bytes of bandwidth per packet. '''ChaCha20''' encryption for this, with an independent key. Note that the plaintext length is still implicitly authenticated by the encryption of the plaintext, but this can only be verified after receiving the whole packet. This design is inspired by that of the ChaCha20Poly1305 cipher suite in [http://bxr.su/OpenBSD/usr.bin/ssh/PROTOCOL.chacha20poly1305 OpenSSH].'''How does packet encryption differ from the OpenSSH design?''' The differences are: * The length field is only 3 bytes instead of 4, as that is sufficient for our purposes. * Length encryption keeps drawing pseudorandom bytes from the same ChaCha20 cipher for multiple packets, rather than incrementing the nonce for every packet. * The Poly1305 authentication tag only covers the encrypted plaintext, and not the encrypted length field. This means that plaintext encryption uses the standard ChaCha20Poly1305 construction without any modifications, maximizing applicability of analysis and review of that cipher. The length encryption can be seen as a separate layer, using a separate key, and thus cannot affect any of the confidentiality or integrity guarantees of the plaintext encryption. On the other hand, this change w.r.t. OpenSSH also does not worsen any properties, as incorrect lengths will still trigger authentication failure for the overall packet (the plaintext length is implicitly authenticated by ChaCha20Poly1305). -* A hash step is performed every 224'''How was the rekeying interval 224 chosen?''' Assuming a node sends only ping messages every 20 minutes (the timeout interval for post-[https://github.com/bitcoin/bips/blob/master/bip-0031.mediawiki BIP31] connections) on a connection, the node will transmit 224 packets in about 3.11 days. This means ''soft rekeying'' after a fixed number of packets automatically translates to an upper-bound of time interval for rekeying, while being much simpler to coordinate than an actual time-based rekeying regime. At the same time, doing it once every 224 messages is sufficiently infrequent that it has only negligible impact on performance. Furthermore, 224 times 3 bytes (the number of bytes consumed by each length encryption) is 672, which is a multiple of 64 minus 32. This means that at the end of 224 length encryptions, exactly 32 bytes of keystream data remain that can be used as next key. messages to rekey the the encryption ciphers, in order to provide forward security. +* A hash step is performed every 224'''How was the rekeying interval 224 chosen?''' Assuming a node sends only ping messages every 20 minutes (the timeout interval for post-[https://github.com/bitcoin/bips/blob/master/bip-0031.mediawiki BIP31] connections) on a connection, the node will transmit 224 packets in about 3.11 days. This means ''soft rekeying'' after a fixed number of packets automatically translates to an upper-bound of time interval for rekeying, while being much simpler to coordinate than an actual time-based rekeying regime. At the same time, doing it once every 224 messages is sufficiently infrequent that it has only negligible impact on performance. Furthermore, 224 times 3 bytes (the number of bytes consumed by each length encryption) is 672, which is a multiple of 64 minus 32. This means that at the end of 224 length encryptions, exactly 32 bytes of keystream data remain that can be used as next key. messages to rekey the encryption ciphers, in order to provide forward security. Because only fixed-length chunks (3-byte length fields) are encrypted, we do not need to treat all length chunks as separate messages. Instead, a single cipher (with the same nonce) is used for multiple consecutive length fields. This avoids wasting 61 pseudorandom bytes per packet, and makes the cost of having a separate cipher for length encryption negligible.'''Is it acceptable to use a less standard construction for length encryption?''' The fact that multiple (non-overlapping) bytes generated by a single ChaCha20 cipher are used for the encryption of multiple consecutive length fields is uncommon. We feel the performance cost gained by this deviation is worth it (especially for small packets, which are very common in Bitcoin's P2P protocol), given the low guarantees that are feasible for length encryption in the first place, and the result is still sufficient to provide pseudorandomness from the view of passive attackers. For plaintext encryption, we independently use a very standard construction, as the stakes for confidentiality and integrity there are much higher. -In order to provide forward security'''What value does forward security provide?''' Re-keying ensures [https://eprint.iacr.org/2001/035.pdf forward secrecy within a session], i.e., an attacker compromising the current session secrets cannot derive past encryption keys in the same session.'''Why have a cipher with forward secrecy but no periodical refresh of the ECDH key exchange?''' Our cipher ratchets encryption keys forward in order to protect messages encrypted under ''past'' encryption keys. In contrast, re-performing ECDH key exchange would protect messages encrypted under ''future'' encryption keys, i.e., it would re-establish security after the attacker had compromised one of the peers ''temporarily'' (e.g., the attacker obtains a memory dump). We do not believe protecting against that is a priority: an attacker that, for whatever reason, is capable of an attack that reveals encryption keys (or other session secrets) of a peer once is likely capable of performing the same attack again after peers have re-performed the ECDH key exchange. Thus, we do not believe the benefits of re-performing key exchange outweigh the additional complexity that comes with the necessary coordination between the peers. We note that the initiator could choose to close and re-open the entire connection in order to force a refresh of the ECDH key exchange, but that introduces other issues: a connection slot needs to be kept open at the responder side, it is not cryptographically guaranteed that really the same initiator will use it, and the observable TCP reset and handshake may create a detectable pattern., the encryption keys for both plaintext and length encryption are cycled every 224 messages, by switching to a new key that is generated by the key stream using the old key. +In order to provide forward security'''What value does forward security provide?''' Re-keying ensures [https://eprint.iacr.org/2001/035.pdf forward secrecy within a session], i.e., an attacker compromising the current session secrets cannot derive past encryption keys in the same session.'''Why have a cipher with forward secrecy but no periodical refresh of the ECDH key exchange?''' Our cipher ratchets encryption keys forward in order to protect messages encrypted under ''past'' encryption keys. In contrast, re-performing ECDH key exchange would protect messages encrypted under ''future'' encryption keys, i.e., it would re-establish security after the attacker had compromised one of the peers ''temporarily'' (e.g., the attacker obtains a memory dump). We do not believe protecting against that is a priority: an attacker that, for whatever reason, is capable of an attack that reveals encryption keys (or other session secrets) of a peer once is likely capable of performing the same attack again after peers have re-performed the ECDH key exchange. Thus, we do not believe the benefits of re-performing key exchange outweigh the additional complexity that comes with the necessary coordination between the peers. We note that the initiator could choose to close and re-open the entire connection to force a refresh of the ECDH key exchange, but that introduces other issues: a connection slot needs to be kept open at the responder side, it is not cryptographically guaranteed that really the same initiator will use it, and the observable TCP reset and handshake may create a detectable pattern., the encryption keys for both plaintext and length encryption are cycled every 224 messages, by switching to a new key that is generated by the key stream using the old key. ==== Handshake: key exchange and version negotiation ==== @@ -242,19 +242,19 @@ To define the needed functions, we first introduce a helper function, matching t ** For every ''x'' in ''{u + 4Y2, (-X/Y - u)/2, (X/Y - u)/2}'' (all ''mod p''; the order matters): *** If ''lift_x(x)'' succeeds, return ''x''. There is at least one such ''x''. -To find encodings of a given X coordinate ''x'', we first need the inverse of ''XSwiftEC''. The function ''XSwiftECInv(x, u, case)'' either returns ''t'' such that ''XSwiftEC(u, t) = x'', or ''None''. The ''case'' variable is an integer in range 0 to 7 inclusive, which selects which of the up to 8 valid such ''t'' values to return: +To find encodings of a given X coordinate ''x'', we first need the inverse of ''XSwiftEC''. The function ''XSwiftECInv(x, u, case)'' either returns ''t'' such that ''XSwiftEC(u, t) = x'', or ''None''. The ''case'' variable is an integer in range ''0..7'', which selects which of the up to 8 valid such ''t'' values to return: * ''XSwiftECInv(x, u, case)'': ** If ''case & 2 = 0'': *** If ''lift_x(-x - u)'' succeeds, return ''None''. *** Let ''v = x''. *** Let ''s = -(u3 + 7)/(u2 + uv + v2) (mod p)''. -** If ''case & 2 = 2'': +** Else (''case & 2 = 2''): *** Let ''s = x - u (mod p)''. *** If ''s = 0'', return ''None''. *** Let ''r'' be the square root of ''-s(4(u3 + 7) + 3u2s) (mod p).'''''How to compute a square root mod ''p''?''' Due to the structure of ''p'', a candidate for the square root of ''a'' mod ''p'' can be computed as ''x = a(p+1)/4 mod p''. If ''a'' is not a square mod ''p'', this formula returns the square root of ''-a mod p'' instead, so it is necessary to verify that ''x2 mod p = a''. If that is the case ''-x mod p'' is a solution too, but we define "the" square root to be equal to that expression (the square root will therefore always be a square itself, as ''(p+1)/4'' is even). This algorithm is a specialization of the [https://en.wikipedia.org/wiki/Tonelli%E2%80%93Shanks_algorithm Tonelli-Shanks algorithm]. Return ''None'' if it does not exist. -** If ''case & 1 = 1'' and ''r = 0'', return ''None''. -*** Let ''v = (-u + r/s)/2''. +*** If ''case & 1 = 1'' and ''r = 0'', return ''None''. +*** Let ''v = (r/s - u)/2''. ** Let ''w'' be the square root of ''s (mod p)''. Return ''None'' if it does not exist. ** If ''case & 5 = 0'', return ''-w(u(1 - c)/2 + v)''. ** If ''case & 5 = 1'', return ''w(u(1 + c)/2 + v)''. @@ -357,7 +357,7 @@ def respond_v2_handshake(peer, garbage_len): use_v1_protocol()
-Upon receiving the encoded responder public key, the initiator derives the shared ECDH secret and instantiates the encrypted transport. It then sends the derived 16-byte initiator_garbage_terminator followed by an authenticated, encrypted packet with empty contents'''Does the content of the garbage authentication packet need to be empty?''' The receiver ignores the content of the garbage authentication packet, so its content can be anything, and it can in principle be used as a shaping mechanism too. There is however no need for that, as immediately afterwards the initiator can start using decoy packets as (much more flexible) shaping mechanism instead. to authenticate the garbage, and its own version packet. It then receives the responder's garbage and garbage authentication packet (delimited by the garbage terminator), and checks if the garbage is authenticated correctly. The responder performs very similar steps, but includes the earlier received prefix bytes in the public key. As mentioned before, the encrypted packets for the '''version negotiation phase''' can be piggybacked with the garbage authentication packet to minimize roundtrips. +Upon receiving the encoded responder public key, the initiator derives the shared ECDH secret and instantiates the encrypted transport. It then sends the derived 16-byte initiator_garbage_terminator followed by an authenticated, encrypted packet with empty contents'''Does the content of the garbage authentication packet need to be empty?''' The receiver ignores the content of the garbage authentication packet, so its content can be anything, and it can in principle be used as a shaping mechanism too. There is however no need for that, as immediately afterward the initiator can start using decoy packets as (a much more flexible) shaping mechanism instead. to authenticate the garbage, and its own version packet. It then receives the responder's garbage and garbage authentication packet (delimited by the garbage terminator), and checks if the garbage is authenticated correctly. The responder performs very similar steps but includes the earlier received prefix bytes in the public key. As mentioned before, the encrypted packets for the '''version negotiation phase''' can be piggybacked with the garbage authentication packet to minimize roundtrips.
 def complete_handshake(peer, initiating):
@@ -405,7 +405,7 @@ These will be used for plaintext encryption and length encryption, respectively.
 
 To provide re-keying every 224 packets, we specify two wrappers.
 
-The first is '''FSChaCha20Poly1305''', which represents a ChaCha20Poly1305 AEAD, which automatically changes the nonce after every message, and rekeys every 224 messages by encrypting 32 zero bytes'''Why is rekeying implemented in terms of an invocation of the AEAD?''' This means the FSChaCha20Poly1305 wrapper can be thought of as a pure layer around the ChaCha20Poly1305 AEAD. Actual implementations can take advantage of the fact that this formulation is equivalent to using byte 64 through 95 of the keystream output of the underlying ChaCha20 cipher as new key, avoiding the need for Poly1305 in the process., and using the first 32 bytes of the result. Each message will be used for one packet. Note that in our protocol, any FSChaCha20Poly1305 instance is always either exclusively encryption or exclusively decryption, as separate instances are used for each direction of the protocol. The nonce used for a message is composed of the 32-bit little endian encoding of the number of messages with the current key, followed by the 64-bit little endian encoding of the number of rekeyings performed. For rekeying, the first 32-bit integer is set to ''0xffffffff''.
+The first is '''FSChaCha20Poly1305''', which represents a ChaCha20Poly1305 AEAD, which automatically changes the nonce after every message, and rekeys every 224 messages by encrypting 32 zero bytes'''Why is rekeying implemented in terms of an invocation of the AEAD?''' This means the FSChaCha20Poly1305 wrapper can be thought of as a pure layer around the ChaCha20Poly1305 AEAD. Actual implementations can take advantage of the fact that this formulation is equivalent to using byte 64 through 95 of the keystream output of the underlying ChaCha20 cipher as new key, avoiding the need for Poly1305 in the process., and using the first 32 bytes of the result. Each message will be used for one packet. Note that in our protocol, any FSChaCha20Poly1305 instance is always either exclusively encryption or exclusively decryption, as separate instances are used for each direction of the protocol. The nonce used for a message is composed of the 32-bit little-endian encoding of the number of messages with the current key, followed by the 64-bit little-endian encoding of the number of rekeyings performed. For rekeying, the first 32-bit integer is set to ''0xffffffff''.
 
 
 REKEY_INTERVAL = 224
@@ -437,7 +437,7 @@ class FSChaCha20Poly1305:
         return self.crypt(aad, plaintext, False)
 
-The second is '''FSChaCha20''', a (single) stream cipher which is used for the lengths of all packets. Encryption and decryption are identical here, so a single function crypt is exposed. It XORs the input with bytes generated using the ChaCha20 block function, rekeying every 224 chunks using the next 32 bytes of the block function output as new key. A ''chunk'' refers here to a single invocation of crypt. As explained before, the same cipher is used for 224 consecutive chunks, to avoid wasting cipher output. The nonce used for these batches of 224 chunks is composed of 4 zero bytes followed by the 64-bit little endian encoding of the number of rekeyings performed. The block counter is reset to 0 after every rekeying. +The second is '''FSChaCha20''', a (single) stream cipher which is used for the lengths of all packets. Encryption and decryption are identical here, so a single function crypt is exposed. It XORs the input with bytes generated using the ChaCha20 block function, rekeying every 224 chunks using the next 32 bytes of the block function output as new key. A ''chunk'' refers here to a single invocation of crypt. As explained before, the same cipher is used for 224 consecutive chunks, to avoid wasting cipher output. The nonce used for these batches of 224 chunks is composed of 4 zero bytes followed by the 64-bit little-endian encoding of the number of rekeyings performed. The block counter is reset to 0 after every rekeying.
 class FSChaCha20:
@@ -515,12 +515,12 @@ v2 Bitcoin P2P transport layer packets use the encrypted message structure shown
 {|class="wikitable"
 ! Field !! Size in bytes !! Comments
 |-
-| message_type || ''1..13'' || either a one byte ID or an ASCII string prefixed with a length byte
+| message_type || 1 or 13 || either a one byte ID in range ''1..255'' or b'\x00' followed by a 12-byte ASCII message type (as in the v1 P2P protocol)
 |-
 | message_payload || message_length || message payload
 |}
 
-If the first byte of message_type is in the range ''1..12'', it is interpreted as the number of ASCII bytes that follow for the message type. If it is in the range ''13..255'', it is interpreted as a message type ID. This structure results in smaller messages than the v1 protocol as most messages sent/received will have a message type ID.'''How do the length between v1 and v2 compare?''' For messages that use the 1-byte short message type ID, v2 packets use 3 bytes less per message than v1.
+If the first byte of message_type is b'\x00', the following 12 bytes are interpreted as an ASCII message type (as in the v1 P2P protocol), trailing padded with b'\x00' as necessary. If the first byte of message_type is in the range ''1..255'', it is interpreted as a message type ID. This structure results in smaller messages than the v1 protocol, as most messages sent/received will have a message type ID. We recommend reserving 1-byte type IDs for message types that are sent more than once per direction per connection.'''How do the lengths between v1 and v2 compare?''' For messages that use the 1-byte short message type ID, v2 packets use 3 bytes less per message than v1.'''Why not allow variable length long message type IDs?''' Allowing for variable length long IDs reduces the available 1-byte ID space by 12 (to encode the length itself) and incentivizes less descriptive message types. In addition, limiting message types to fixed lengths of 1 or 13 hampers traffic analysis.
 
 The following table lists currently defined message type IDs:
 
@@ -533,50 +533,38 @@ The following table lists currently defined message type IDs:
 !3
 |-
 !+0
-|(undefined)||(1 byte string)||(2 byte string)||(3 byte string)
+|(12 bytes follow)||ADDR||BLOCK||BLOCKTXN
 |-
 !+4
-|(4 byte string)||(5 byte string)||(6 byte string)||(7 byte string)
+|CMPCTBLOCK||FEEFILTER||FILTERADD||FILTERCLEAR
 |-
 !+8
-|(8 byte string)||(9 byte string)||(10 byte string)||(11 byte string)
+|FILTERLOAD||GETBLOCKS||GETBLOCKTXN||GETDATA
 |-
 !+12
-|(12 byte string)||ADDR||BLOCK||BLOCKTXN
+|GETHEADERS||HEADERS||INV||MEMPOOL
 |-
 !+16
-|CMPCTBLOCK||FEEFILTER||FILTERADD||FILTERCLEAR
+|MERKLEBLOCK||NOTFOUND||PING||PONG
 |-
 !+20
-|FILTERLOAD||GETADDR||GETBLOCKS||GETBLOCKTXN
+|SENDCMPCT||TX||GETCFILTERS||CFILTER
 |-
 !+24
-|GETDATA||GETHEADERS||HEADERS||INV
+|GETCFHEADERS||CFHEADERS||GETCFCHECKPT||CFCHECKPT
 |-
 !+28
-|MEMPOOL||MERKLEBLOCK||NOTFOUND||PING
+|ADDRV2||REQRECON||SKETCH||REQSKETCHEXT
 |-
 !+32
-|PONG||SENDCMPCT||SENDHEADERS||TX
-|-
-!+36
-|VERACK||VERSION||GETCFILTERS||CFILTER
-|-
-!+40
-|GETCFHEADERS||CFHEADERS||GETCFCHECKPT||CFCHECKPT
-|-
-!+44
-|WTXIDRELAY||ADDRV2||SENDADDRV2||SENDTXRCNCL
-|-
-!+48
-|REQRECON||SKETCH||REQSKETCHEXT||RECONCILDIFF
+|RECONCILDIFF
 |-
-!≥52
+!≥33
 || colspan="4" | (undefined)
 |}
 
 
-The message types may be updated separately after BIP finalization.
+Additional message types may be added separately after BIP finalization.
 
 === Signaling specification ===
 ==== Signaling v2 support ====
@@ -586,8 +574,8 @@ Peers supporting the v2 transport protocol signal support by advertising the 
Date: Sat, 4 Mar 2023 11:13:16 +0000
Subject: [PATCH 056/454] Update Simple Signer Algorithm for SegWitv0 inputs

It is no longer expected that SegWitV0 inputs have no witness-utxo field.
Reverting the order of checks avoids this assumption (while still relying on the mandatory lack of witness-utxo for legacy inputs).
---
 bip-0174.mediawiki | 18 +++++++++---------
 1 file changed, 9 insertions(+), 9 deletions(-)

diff --git a/bip-0174.mediawiki b/bip-0174.mediawiki
index 6a5d5e8c4e..f4c0807c94 100644
--- a/bip-0174.mediawiki
+++ b/bip-0174.mediawiki
@@ -718,15 +718,8 @@ sign_non_witness(script_code, i):
         if IsMine(key) and IsAcceptable(sighash_type):
             sign(non_witness_sighash(script_code, i, input))
 
-for input,i in enumerate(psbt.inputs):
-    if non_witness_utxo.exists:
-        assert(sha256d(non_witness_utxo) == psbt.tx.input[i].prevout.hash)
-        if redeemScript.exists:
-            assert(non_witness_utxo.vout[psbt.tx.input[i].prevout.n].scriptPubKey == P2SH(redeemScript))
-            sign_non_witness(redeemScript, i)
-        else:
-            sign_non_witness(non_witness_utxo.vout[psbt.tx.input[i].prevout.n].scriptPubKey, i)
-    else if witness_utxo.exists:
+for input, i in enumerate(psbt.inputs):
+    if witness_utxo.exists:
         if redeemScript.exists:
             assert(witness_utxo.scriptPubKey == P2SH(redeemScript))
             script = redeemScript
@@ -737,6 +730,13 @@ for input,i in enumerate(psbt.inputs):
         else if IsP2WSH(script):
             assert(script == P2WSH(witnessScript))
             sign_witness(witnessScript, i)
+    else if non_witness_utxo.exists:
+        assert(sha256d(non_witness_utxo) == psbt.tx.input[i].prevout.hash)
+        if redeemScript.exists:
+            assert(non_witness_utxo.vout[psbt.tx.input[i].prevout.n].scriptPubKey == P2SH(redeemScript))
+            sign_non_witness(redeemScript, i)
+        else:
+            sign_non_witness(non_witness_utxo.vout[psbt.tx.input[i].prevout.n].scriptPubKey, i)
     else:
         assert False
 
From 5cf651155d8b7d2a53dd19084f299247ce03e5bc Mon Sep 17 00:00:00 2001 From: Salvatore Ingala <6681844+bigspider@users.noreply.github.com> Date: Sat, 4 Mar 2023 11:24:05 +0000 Subject: [PATCH 057/454] Relax transaction version requirement when the Creator is also a Constructor. --- bip-0370.mediawiki | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/bip-0370.mediawiki b/bip-0370.mediawiki index b3f65ffb9f..cb5980144b 100644 --- a/bip-0370.mediawiki +++ b/bip-0370.mediawiki @@ -235,9 +235,9 @@ PSBTv2 introduces new roles and modifies some existing roles. ===Creator=== In PSBTv2, the Creator initializes the PSBT with 0 inputs and 0 outputs. -The PSBT version number is set to 2. The transaction version number must be set to at least 2. '''Why does the transaction version number need to be at least 2?''' The transaction version number is part of the validation rules for some features such as OP_CHECKSEQUENCEVERIFY. Since it is backwards compatible, and there are other ways to disable those features (e.g. through sequence numbers), it is easier to require transactions be able to support these features than to try to negotiate the transaction version number. +The PSBT version number is set to 2. The Creator should also set PSBT_GLOBAL_FALLBACK_LOCKTIME. -If the Creator is not also a Constructor and will be giving the PSBT to others to add inputs and outputs, the PSBT_GLOBAL_TX_MODIFIABLE field must be present and and the Inputs Modifiable and Outputs Modifiable flags set appropriately. +If the Creator is not also a Constructor and will be giving the PSBT to others to add inputs and outputs, the PSBT_GLOBAL_TX_MODIFIABLE field must be present and the Inputs Modifiable and Outputs Modifiable flags set appropriately; moreover, the transaction version number must be set to at least 2. '''Why does the transaction version number need to be at least 2?''' The transaction version number is part of the validation rules for some features such as OP_CHECKSEQUENCEVERIFY. Since it is backwards compatible, and there are other ways to disable those features (e.g. through sequence numbers), it is easier to require transactions be able to support these features than to try to negotiate the transaction version number. If the Creator is a Constructor and no inputs and outputs will be added by other entities, PSBT_GLOBAL_TX_MODIFIABLE may be omitted. ===Constructor=== From ebea569f193577af8be51a48f0838fab38add0a9 Mon Sep 17 00:00:00 2001 From: kallewoof Date: Thu, 9 Mar 2023 11:57:21 +0900 Subject: [PATCH 058/454] replace travis with Github Actions (#1432) replace travis with Github Actions --- .github/workflows/github-action-checks.yml | 19 +++++++++++++++++++ .travis.yml | 7 ------- scripts/diffcheck.sh | 13 +++++++++++++ 3 files changed, 32 insertions(+), 7 deletions(-) create mode 100644 .github/workflows/github-action-checks.yml delete mode 100644 .travis.yml create mode 100755 scripts/diffcheck.sh diff --git a/.github/workflows/github-action-checks.yml b/.github/workflows/github-action-checks.yml new file mode 100644 index 0000000000..bfc014ba5a --- /dev/null +++ b/.github/workflows/github-action-checks.yml @@ -0,0 +1,19 @@ +name: GitHub Actions Check +run-name: ${{ github.actor }} Checks 🚀 +on: [push, pull_request] +jobs: + Link-Format-Checks: + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@v3 + - run: scripts/link-format-chk.sh + Build-Table-Checks: + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@v3 + - run: scripts/buildtable.pl >/tmp/table.mediawiki || exit 1 + Diff-Checks: + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@v3 + - run: scripts/diffcheck.sh diff --git a/.travis.yml b/.travis.yml deleted file mode 100644 index 70d339ae65..0000000000 --- a/.travis.yml +++ /dev/null @@ -1,7 +0,0 @@ -os: linux -language: generic -script: - - scripts/link-format-chk.sh - - scripts/buildtable.pl >/tmp/table.mediawiki || exit 1 - - diff README.mediawiki /tmp/table.mediawiki | grep '^[<>] |' >/tmp/after.diff || true - - if git checkout HEAD^ && scripts/buildtable.pl >/tmp/table.mediawiki 2>/dev/null; then diff README.mediawiki /tmp/table.mediawiki | grep '^[<>] |' >/tmp/before.diff || true; newdiff=$(diff -s /tmp/before.diff /tmp/after.diff -u | grep '^+'); if [ -n "$newdiff" ]; then echo "$newdiff"; exit 1; fi; else echo 'Cannot build previous commit table for comparison'; fi diff --git a/scripts/diffcheck.sh b/scripts/diffcheck.sh new file mode 100755 index 0000000000..4e4c4592f3 --- /dev/null +++ b/scripts/diffcheck.sh @@ -0,0 +1,13 @@ +#!/bin/bash + +diff README.mediawiki /tmp/table.mediawiki | grep '^[<>] |' >/tmp/after.diff || true +if git checkout HEAD^ && scripts/buildtable.pl >/tmp/table.mediawiki 2>/dev/null; then + diff README.mediawiki /tmp/table.mediawiki | grep '^[<>] |' >/tmp/before.diff || true + newdiff=$(diff -s /tmp/before.diff /tmp/after.diff -u | grep '^+') + if [ -n "$newdiff" ]; then + echo "$newdiff" + exit 1 + fi +else + echo 'Cannot build previous commit table for comparison' +fi From c0148c872d886d20ea10663febf34691c91badd7 Mon Sep 17 00:00:00 2001 From: raphjaph Date: Fri, 10 Mar 2023 22:19:31 +0100 Subject: [PATCH 059/454] Improve BIP-341 wording Reading the spec closely the different language used for serialization of input outpoints and input amounts was confusing on first read. This change uses the same language for both, which makes it easier to read. --- bip-0341.mediawiki | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/bip-0341.mediawiki b/bip-0341.mediawiki index 8a4f1a6767..392ad67dbc 100644 --- a/bip-0341.mediawiki +++ b/bip-0341.mediawiki @@ -105,7 +105,7 @@ If the parameters take acceptable values, the message is the concatenation of th ** ''nLockTime'' (4): the ''nLockTime'' of the transaction. ** If the ''hash_type & 0x80'' does not equal SIGHASH_ANYONECANPAY: *** ''sha_prevouts'' (32): the SHA256 of the serialization of all input outpoints. -*** ''sha_amounts'' (32): the SHA256 of the serialization of all spent output amounts. +*** ''sha_amounts'' (32): the SHA256 of the serialization of all input amounts. *** ''sha_scriptpubkeys'' (32): the SHA256 of all spent outputs' ''scriptPubKeys'', serialized as script inside CTxOut. *** ''sha_sequences'' (32): the SHA256 of the serialization of all input ''nSequence''. ** If ''hash_type & 3'' does not equal SIGHASH_NONE or SIGHASH_SINGLE: From e761066fbcd41b6a10b1614d974ea09531c3f945 Mon Sep 17 00:00:00 2001 From: Andrew Poelstra Date: Fri, 17 Mar 2023 02:39:01 +0000 Subject: [PATCH 060/454] new BIP: codex32 (#1425) new BIP: codex32 --------- Co-authored-by: Russell O'Connor --- README.mediawiki | 7 + bip-0093.mediawiki | 596 +++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 603 insertions(+) create mode 100644 bip-0093.mediawiki diff --git a/README.mediawiki b/README.mediawiki index 9dae2da4d0..966de69caf 100644 --- a/README.mediawiki +++ b/README.mediawiki @@ -484,6 +484,13 @@ Those proposing changes should consider that ultimately consent may rest with th | Standard | Final |- +| [[bip-0093.mediawiki|93]] +| Applications +| codex32: Checksummed SSSS-aware BIP32 seeds +| Leon Olsson Curr, Pearlwort Sneed +| Informational +| Draft +|- | [[bip-0098.mediawiki|98]] | Consensus (soft fork) | Fast Merkle Trees diff --git a/bip-0093.mediawiki b/bip-0093.mediawiki new file mode 100644 index 0000000000..434e479c80 --- /dev/null +++ b/bip-0093.mediawiki @@ -0,0 +1,596 @@ +
+  BIP: 93
+  Layer: Applications
+  Title: codex32: Checksummed SSSS-aware BIP32 seeds
+  Author: Leon Olsson Curr and Pearlwort Sneed 
+  Comments-URI: https://github.com/bitcoin/bips/wiki/Comments:BIP-0093
+  Status: Draft
+  Type: Informational
+  Created: 2023-02-13
+  License: BSD-3-Clause
+  Post-History: https://lists.linuxfoundation.org/pipermail/bitcoin-dev/2023-February/021469.html
+
+ +==Introduction== + +===Abstract=== + +This document describes a standard for backing up and restoring the master seed of a +[https://github.com/bitcoin/bips/blob/master/bip-0032.mediawiki BIP-0032] hierarchical deterministic wallet, using Shamir's secret sharing. +It includes an encoding format, a BCH error-correcting checksum, and algorithms for share generation and secret recovery. +Secret data can be split into up to 31 shares. +A minimum threshold of shares, which can be between 1 and 9, is needed to recover the secret, whereas without sufficient shares, no information about the secret is recoverable. + +===Copyright=== + +This document is licensed under the 3-clause BSD license. + +===Motivation=== + +BIP-0032 master seed data is the source entropy used to derive all private keys in an HD wallet. +Safely storing this secret data is the hardest and most important part of self-custody. +However, there is a tension between security, which demands limiting the number of backups, and resilience, which demands widely replicated backups. +Encrypting the seed does not change this fundamental tradeoff, since it leaves essentially the same problem of how to back up the encryption key(s). + +To allow users freedom to make this tradeoff, we use Shamir's secret sharing, which guarantees that any number of shares less than the threshold leaks no information about the secret. +This approach allows increasing safety by widely distributing the generated shares, while also providing security against the compromise of one or more shares (as long as fewer than the threshold have been compromised). + +[https://github.com/satoshilabs/slips/blob/master/slip-0039.md SLIP-0039] has essentially the same motivations as this standard. +However, unlike SLIP-0039, + +* this standard aims to be simple enough for hand computation +* we use the bech32 alphabet rather than a word list, resulting in fixed-length compact encodings +* we do not support multi-level secret sharing (splitting of shares), although it is technically possible and may be added in a future BIP +* because of the need to support hand computation, we '''do not''' support passphrases or key hardening + +Users who demand a higher level of security for particular secrets, or have a general distrust in digital electronic devices, have the option of using hand computation to backup and restore secret data in an interoperable manner. +In particular, all computations can be done with simple lookup tables. +'''It is therefore possible to compute and verify checksums, and to split and recover seeds, entirely using pen and paper.''' +For long-lived rarely-used seeds, the ability to hand-verify checksums has a significant benefit even for users who do not care to do any other part of this process by hand. +It means that they can verify the integrity (against non-malicious tampering) of their shares regularly, say, on an annual basis, without needing to continually expose secret data to new hardware. + +The ability to compute properties by hand comes from our choice of a small field and our use of linear error correcting codes. +It does not come with any reduction in security, as long as users use high-quality randomness. +Note that hand computation is optional, the particular details of hand computation are outside the scope of this standard, and implementers do not need to be concerned with this possibility. + +[https://github.com/bitcoin/bips/blob/master/bip-0039.mediawiki BIP-0039] serves the same purpose as this standard: encoding master seeds for storage by users. +However, BIP-0039 has no error-correcting ability, cannot sensibly be extended to support secret sharing, has no support for versioning or other metadata, and has many technical design decisions that make implementation and interoperability difficult (for example, the use of SHA-512 to derive seeds, or the use of 11-bit words). + +==Specification== + +===codex32=== + +A codex32 string is similar to a Bech32 string defined in [https://github.com/bitcoin/bips/blob/master/bip-0173.mediawiki BIP-0173]. +It reuses the base32 character set from BIP-0173, and consists of: + +* A human-readable part, which is the string "ms" (or "MS"). +* A separator, which is always "1". +* A data part which is in turn subdivided into: +** A threshold parameter, which MUST be a single digit between "2" and "9", or the digit "0". +*** If the threshold parameter is "0" then the share index, defined below, MUST have a value of "s" (or "S"). +** An identifier consisting of 4 Bech32 characters. +** A share index, which is any Bech32 character. Note that a share index value of "s" (or "S") is special and denotes the unshared secret (see section "Unshared Secret"). +** A payload which is a sequence of up to 74 Bech32 characters. (However, see '''Long codex32 Strings''' below for an exception to this limit.) +** A checksum which consists of 13 Bech32 characters as described below. + +As with Bech32 strings, a codex32 string MUST be entirely uppercase or entirely lowercase. +For presentation, lowercase is usually preferable, but uppercase SHOULD be used for handwritten codex32 strings. +If a codex32 string is encoded in a QR code, it SHOULD use the uppercase form, as this is encoded more compactly. + +===Checksum=== + +The last thirteen characters of the data part form a checksum and contain no information. +Valid strings MUST pass the criteria for validity specified by the Python3 code snippet below. +The function ms32_verify_checksum must return true when its argument is the data part as a list of integers representing the characters converted using the bech32 character table from BIP-0173. + +To construct a valid checksum given the data-part characters (excluding the checksum), the ms32_create_checksum function can be used. + + +MS32_CONST = 0x10ce0795c2fd1e62a + +def ms32_polymod(values): + GEN = [ + 0x19dc500ce73fde210, + 0x1bfae00def77fe529, + 0x1fbd920fffe7bee52, + 0x1739640bdeee3fdad, + 0x07729a039cfc75f5a, + ] + residue = 0x23181b3 + for v in values: + b = (residue >> 60) + residue = (residue & 0x0fffffffffffffff) << 5 ^ v + for i in range(5): + residue ^= GEN[i] if ((b >> i) & 1) else 0 + return residue + +def ms32_verify_checksum(data): + if len(data) >= 96: # See Long codex32 Strings + return ms32_verify_long_checksum(data) + if len(data) <= 93: + return ms32_polymod(data) == MS32_CONST + return False + +def ms32_create_checksum(data): + if len(data) > 80: # See Long codex32 Strings + return ms32_create_long_checksum(data) + values = data + polymod = ms32_polymod(values + [0] * 13) ^ MS32_CONST + return [(polymod >> 5 * (12 - i)) & 31 for i in range(13)] + + +===Error Correction=== + +A codex32 string without a valid checksum MUST NOT be used. +The checksum is designed to be an error correcting code that can correct up to 4 character substitutions, up to 8 unreadable characters (called erasures), or up to 13 consecutive erasures. +Implementations SHOULD provide the user with a corrected valid codex32 string if possible. +However, implementations SHOULD NOT automatically proceed with a corrected codex32 string without user confirmation of the corrected string, either by prompting the user, or returning a corrected string in an error message and allowing the user to repeat their action. +We do not specify how an implementation should implement error correction. However, we recommend that: + +* Implementations make suggestions to substitute non-bech32 characters with bech32 characters in some situations, such as replacing "B" with "8", "O" with "0", "I" with "l", etc. +* Implementations interpret "?" as an erasure. +* Implementations optionally interpret other non-bech32 characters, or characters with incorrect case, as erasures. +* If a string with 8 or fewer erasures can have those erasures filled in to make a valid codex32 string, then the implementation suggests such a string as a correction. +* If a string consisting of valid Bech32 characters in the proper case can be made valid by substituting 4 or fewer characters, then the implementation suggests such a string as a correction. + +===Unshared Secret=== + +When the share index of a valid codex32 string (converted to lowercase) is the letter "s", we call the string a codex32 secret. +The payload in a codex32 secret is a direct encoding of a BIP-0032 HD master seed. + +The master seed is decoded by converting the payload to bytes: + +* Translate the characters to 5 bits values using the bech32 character table from BIP-0173, most significant bit first. +* Re-arrange those bits into groups of 8 bits. Any incomplete group at the end MUST be 4 bits or less, and is discarded. + +Note that unlike the decoding process in BIP-0173, we do NOT require that the incomplete group be all zeros. + +For an unshared secret, the threshold parameter (the first character of the data part) is ignored (beyond the fact it must be a digit for the codex32 string to be valid). +We recommend using the digit "0" for the threshold parameter in this case. +The 4 character identifier also has no effect beyond aiding users in distinguishing between multiple different master seeds in cases where they have more than one. + +===Recovering Master Seed=== + +When the share index of a valid codex32 string (converted to lowercase) is not the letter "s", we call the string an codex32 share. +The first character of the data part indicates the threshold of the share, and it is required to be a non-"0" digit. + +In order to recover a master seed, one needs a set of valid codex32 shares such that: + +* All shares have the same threshold value, the same identifier, and the same length. +* All of the share index values are distinct. +* The number of codex32 shares is exactly equal to the (common) threshold value. + +If all the above conditions are satisfied, the ms32_recover function will return a codex32 secret when its argument is the list of codex32 shares with each share represented as a list of integers representing the characters converted using the bech32 character table from BIP-0173. + + +bech32_inv = [ + 0, 1, 20, 24, 10, 8, 12, 29, 5, 11, 4, 9, 6, 28, 26, 31, + 22, 18, 17, 23, 2, 25, 16, 19, 3, 21, 14, 30, 13, 7, 27, 15, +] + +def bech32_mul(a, b): + res = 0 + for i in range(5): + res ^= a if ((b >> i) & 1) else 0 + a *= 2 + a ^= 41 if (32 <= a) else 0 + return res + +def bech32_lagrange(l, x): + n = 1 + c = [] + for i in l: + n = bech32_mul(n, i ^ x) + m = 1 + for j in l: + m = bech32_mul(m, (x if i == j else i) ^ j) + c.append(m) + return [bech32_mul(n, bech32_inv[i]) for i in c] + +def ms32_interpolate(l, x): + w = bech32_lagrange([s[5] for s in l], x) + res = [] + for i in range(len(l[0])): + n = 0 + for j in range(len(l)): + n ^= bech32_mul(w[j], l[j][i]) + res.append(n) + return res + +def ms32_recover(l): + return ms32_interpolate(l, 16) + + +===Generating Shares=== + +If we already have ''t'' valid codex32 strings such that: + +* All strings have the same threshold value ''t'', the same identifier, and the same length +* All of the share index values are distinct + +Then we can derive additional shares with the ms32_interpolate function by passing it a list of exactly ''t'' of these codex32 strings, together with a fresh share index distinct from all of the existing share indexes. +The newly derived share will have the provided share index. + +Once a user has generated ''n'' codex32 shares, they may discard the codex32 secret (if it exists). +The ''n'' shares form a ''t'' of ''n'' Shamir's secret sharing scheme of a codex32 secret. + +There are two ways to create an initial set of ''t'' valid codex32 strings, depending on whether the user already has an existing master seed to split. + +====For a fresh master seed==== + +In the case that the user wishes to generate a fresh master seed, the user generates random initial shares, as follows: + +# Choose a bitsize, between 128 and 512, which must be a multiple of 8. +# Choose a threshold value ''t'' between 2 and 9, inclusive +# Choose a 4 bech32 character identifier +#* We do not define how to choose the identifier, beyond noting that it SHOULD be distinct for every master seed the user may need to disambiguate. +# ''t'' many times, generate a random share by: +## Take the next available letter from the bech32 alphabet, in alphabetical order, as a, c, d, ..., to be the share index +## Set the first nine characters to be the prefix ms1, the threshold vaue ''t'', the 4-character identifier, and then the share index +## Choose the next ceil(''bitlength / 5'') characters uniformly at random +## Generate a valid checksum in accordance with the Checksum section, and append this to the resulting shares + +The result will be ''t'' distinct shares, all with the same initial 8 characters, and a distinct share index as the 9th character. + +With this set of ''t'' codex32 shares, new shares can be derived as discussed above. This process generates a fresh master seed, whose value can be retrieved by running the recovery process on any ''t'' of these shares. + +====For an existing master seed==== + +Before generating shares for an existing master seed, it first must be converted into a codex32 secret, as described above. +The conversion process consists of: + +# Choose a threshold value ''t'' between 2 and 9, inclusive +# Choose a 4 bech32 character identifier +#* We do not define how to choose the identifier, beyond noting that it SHOULD be distinct for every master seed the user may need to disambiguate. +# Set the share index to s +# Set the payload to a Bech32 encoding of the master seed, padded with arbitrary bits +# Generating a valid checksum in accordance with the Checksum section + +Along with the codex32 secret, the user must generate ''t''-1 other codex32 shares, each with the same threshold value, the same identifier, and a distinct share index. +These shares should be generated as described in the "fresh master seed" section. + +The codex32 secret and the ''t''-1 codex32 shares form a set of ''t'' valid codex32 strings from which additional shares can be derived as described above. + +===Long codex32 Strings=== + +The 13 character checksum design only supports up to 80 data characters. +Excluding the threshold, identifier and index characters, this limits the payload to 74 characters or 46 bytes. +While this is enough to support the 32-byte advised size of BIP-0032 master seeds, BIP-0032 allows seeds to be up to 64 bytes in size. +We define a long codex32 string format to support these longer seeds by defining an alternative checksum. + + +MS32_LONG_CONST = 0x43381e570bf4798ab26 + +def ms32_long_polymod(values): + GEN = [ + 0x3d59d273535ea62d897, + 0x7a9becb6361c6c51507, + 0x543f9b7e6c38d8a2a0e, + 0x0c577eaeccf1990d13c, + 0x1887f74f8dc71b10651, + ] + residue = 0x23181b3 + for v in values: + b = (residue >> 70) + residue = (residue & 0x3fffffffffffffffff) << 5 ^ v + for i in range(5): + residue ^= GEN[i] if ((b >> i) & 1) else 0 + return residue + +def ms32_verify_long_checksum(data): + return ms32_long_polymod(data) == MS32_LONG_CONST + +def ms32_create_long_checksum(data): + values = data + polymod = ms32_long_polymod(values + [0] * 15) ^ MS32_LONG_CONST + return [(polymod >> 5 * (14 - i)) & 31 for i in range(15)] + + +A long codex32 string follows the same specification as a regular codex32 string with the following changes. + +* The payload is a sequence of between 75 and 103 Bech32 characters. +* The checksum consists of 15 Bech32 characters as defined above. + +A codex32 string with a data part of 94 or 95 characters is never legal as a regular codex32 string is limited to 93 data characters and a long codex32 string is at least 96 characters. + +Generation of long shares and recovery of the master seed from long shares proceeds in exactly the same way as for regular shares with the ms32_interpolate function. + +The long checksum is designed to be an error correcting code that can correct up to 4 character substitutions, up to 8 unreadable characters (called erasures), or up to 15 consecutive erasures. +As with regular checksums we do not specify how an implementation should implement error correction, and all our recommendations for error correction of regular codex32 strings also apply to long codex32 strings. + +==Rationale== + +This scheme is based on the observation that the Lagrange interpolation of valid codewords in a BCH code will always be a valid codeword. +This means that derived shares will always have valid checksum, and a sufficient threshold of shares with valid checksums will derive a secret with a valid checksum. + +The header system is also compatible with Lagrange interpolation, meaning all derived shares will have the same identifier and will have the appropriate share index. +This fact allows the header data to be covered by the checksum. + +The checksum size and identifier size have been chosen so that the encoding of 128-bit seeds and shares fit within 48 characters. +This is a standard size for many common seed storage formats, which has been popularized by the 12 four-letter word format of the BIP-0039 mnemonic. + +The 13 character checksum is adequate to correct 4 errors in up to 93 characters (80 characters of data and 13 characters of the checksum). +We can correct up to 8 erasures (errors with known locations), and up to 13 consecutive errors (burst errors). +Beyond that, our code is guaranteed to detect up to 8 errors. +More generally, any number of random errors will be detected with overwhelming (1 - 2^65) probability. However, the checksum does not protect against maliciously constructed errors. +These parameters are slightly better than those of the checksum used in SLIP-0039. + +For 256-bit seeds and shares our strings are 74 characters, which fits into the 96 character format of the 24 four-letter word format of the BIP-0039 mnemonic, with plenty of room to spare. + +A longer checksum is needed to support up to 512-bit seeds, the longest seed length specified in BIP-0032, as the 13 character checksum isn't adequate for more than 80 data characters. +While we could use the 15 character checksum for both cases, we prefer to keep the strings as short as possible for the more common cases of 128-bit and 256-bit master seeds. +We only guarantee to correct 4 characters no matter how long the string is. +Longer strings mean more chances for transcription errors, so shorter strings are better. + +The longest data part using the regular 13 character checksum is 93 characters and corresponds to a 400-bit secret. +At this length, the prefix MS1 is not covered by the checksum. +This is acceptable because the checksum scheme itself requires you to know that the MS1 prefix is being used in the first place. +If the prefix is damaged and a user is guessing that the data might be using this scheme, then the user can enter the available data explicitly using the suspected MS1 prefix. + +===Not BIP-0039 Entropy=== + +Instead of encoding a BIP-0032 master seed, an alternative would be to encode BIP-0039 entropy. +However this alternative approach is fraught with difficulties. + +On approach would be to encode the BIP-0039 entropy along with the BIP-0039 checksum data. +This data can directly be recovered from the BIP-0039 mnemonic, and the process can be reversed if one knows the target language. +However, for a 128-bit seed, there is a 4 bit checksum yeilding 132 bits of data that needs to be encoded. +This exceeds the 130-bits of room that we have for storing 128 bit seeds. +We would have to compromise on the 48 character size, or the size of the headers, or the size of the checksum in order to add room for an additional character of data. + +This approach would also eliminate our short cut generation of a fresh master secret from generating random shares. +One would be required to first generate BIP-0039 entropy, and then add a BIP-0039 checksum, before adding a Codex32 checksum and then generate other shares. +In particular, this process could no longer be perfored by hand since it is effecitvely impossible to hand compute a BIP-0039 checksum. + +An alternative approach is to discard the BIP-0039 checksum, since it is inadqueate for error correction anyways, and rely on the Codex32 checksum. +However, this approach ends up eliminating the benefits of BIP-0039 compatibility. +While it is now possible to hand generate fresh shares, it is impossible to recover compatible BIP-0039 words by hand because, again, the BIP-0039 checksum is not hand computable. +The only way of generating the compatible BIP-0039 mnemonic is to use wallet software. +But if the wallet software is need to support this approach to decoding entropy, we may as well bypasss all of the overhead of BIP-0039 and directly encode the entropy of a BIP-0032 master seed, which is what we do in our Codex32 proposal. + +Beyond the problems above, BIP-0039 does not define a single transformation from entropy to BIP-0032 master seed. +Instead every different language has it own word list (or word lists) and each choice of word list yeilds a different transformation from entropy to master seed. +We would need to encode the choice of word list in our share's meta-data, which takes up even more room, and is difficult to specify due to the the ever evolving choice of word lists. + +Alternatively we could standardize on the choice of the English word list, something that is nearly a defacto standard, and simply be incompatible with BIP-0039 wallets of other langauges. +Such a choice also risks users of BIP-0039 recovering their entropy from their language, encoding it in in Codex32 and then failing to recover thier wallet because the English word lists has replaced their language's word list. + +The main advantage of this alternative approach would be that wallets could give users an option switch between backing up their entropy as a BIP-0039 mnemonic and in Codex32 format, but again, only if their language choice happens to be the English word list. +In practice, we do not expect users in switch back and forth between backup formats, and instead just generate a fresh master seed using Codex32. + +Seeing little value with BIP-0039 compatiabilty (English-only), all the difficulties with BIP-0039 langauge choice, not to mention the PBKDF2 overhead of using BIP-0039, we think it is best to abandon BIP-0039 and encode BIP-0032 master seeds directly. +Our aproach is semi-convertable with BIP-0039's 512-bit master seeds (in all languages, see Backwards Compatibility) and fully interconvertable with SLIP-39 encoded master seeds or any other encoding of BIP-0032 master seeds. + +==Backwards Compatibility== + +codex32 is an alternative to BIP-0039 and SLIP-0039. +It is technically possible to derive the BIP32 master seed from seed words encoded in one of these schemes, and then to encode this seed in codex32. +For BIP-0039 this process is irreversible, since it involves hashing the original words. +Furthermore, the resulting seed will be 512 bits long, which may be too large to be safely and conveniently handled. + +SLIP-0039 seed words can be reversibly converted to master seeds, so it is possible to interconvert between SLIP-0039 and codex32. +However, SLIP-0039 '''shares''' cannot be converted to codex32 shares because the two schemes use a different underlying field. + +The authors of this BIP do not recommend interconversion. +Instead, users who wish to switch to codex32 should generate a fresh seed and sweep their coins. + +==Reference Implementation== + +Our [https://github.com/BlockstreamResearch/codex32](reference implementation repository) contains implementations in Rust and PostScript. +The inline code in this BIP text can be used as a Python reference. + +==Test Vectors== + +===Test vector 1=== + +This example shows the codex32 format, when used without splitting the secret into any shares. +The payload contains 26 Bech32 characters, which corresponds to 130 bits. We truncate the last two bits in order to obtain a 128-bit master seed. + +codex32 secret (Bech32): ms10testsxxxxxxxxxxxxxxxxxxxxxxxxxx4nzvca9cmczlw + +Master secret (hex): 318c6318c6318c6318c6318c6318c631 + +* human-readable part: ms +* separator: 1 +* k value: 0 (no secret splitting) +* identifier: test +* share index: s (the secret) +* payload: xxxxxxxxxxxxxxxxxxxxxxxxxx +* checksum: 4nzvca9cmczlw +* master node xprv: xprv9s21ZrQH143K3taPNekMd9oV5K6szJ8ND7vVh6fxicRUMDcChr3bFFzuxY8qP3xFFBL6DWc2uEYCfBFZ2nFWbAqKPhtCLRjgv78EZJDEfpL + +===Test vector 2=== + +This example shows generating a new master seed using "random" codex32 shares, as well as deriving an additional codex32 share, using ''k''=2 and an identifier of NAME. +Although codex32 strings are canonically all lowercase, it's also valid to use all uppercase. + +Share with index A: MS12NAMEA320ZYXWVUTSRQPNMLKJHGFEDCAXRPP870HKKQRM + +Share with index C: MS12NAMECACDEFGHJKLMNPQRSTUVWXYZ023FTR2GDZMPY6PN + +* Derived share with index D: MS12NAMEDLL4F8JLH4E5VDVULDLFXU2JHDNLSM97XVENRXEG +* Secret share with index S: MS12NAMES6XQGUZTTXKEQNJSJZV4JV3NZ5K3KWGSPHUH6EVW +* Master secret (hex): d1808e096b35b209ca12132b264662a5 +* master node xprv: xprv9s21ZrQH143K2NkobdHxXeyFDqE44nJYvzLFtsriatJNWMNKznGoGgW5UMTL4fyWtajnMYb5gEc2CgaKhmsKeskoi9eTimpRv2N11THhPTU + +Note that per BIP-0173, the lowercase form is used when determining a character's value for checksum purposes. +In particular, given an all uppercase codex32 string, we still use lowercase ms as the human-readable part during checksum construction. + +===Test vector 3=== + +This example shows splitting an existing 128-bit master seed into "random" codex32 shares, using ''k''=3 and an identifier of cash. +We appended two zero bits in order to obtain 26 Bech32 characters (130 bits of data) from the 128-bit master seed. + +Master secret (hex): ffeeddccbbaa99887766554433221100 + +Secret share with index s: ms13cashsllhdmn9m42vcsamx24zrxgs3qqjzqud4m0d6nln + +Share with index a: ms13casha320zyxwvutsrqpnmlkjhgfedca2a8d0zehn8a0t + +Share with index c: ms13cashcacdefghjklmnpqrstuvwxyz023949xq35my48dr + +* Derived share with index d: ms13cashd0wsedstcdcts64cd7wvy4m90lm28w4ffupqs7rm +* Derived share with index e: ms13casheekgpemxzshcrmqhaydlp6yhms3ws7320xyxsar9 +* Derived share with index f: ms13cashf8jh6sdrkpyrsp5ut94pj8ktehhw2hfvyrj48704 +* master node xprv: xprv9s21ZrQH143K266qUcrDyYJrSG7KA3A7sE5UHndYRkFzsPQ6xwUhEGK1rNuyyA57Vkc1Ma6a8boVqcKqGNximmAe9L65WsYNcNitKRPnABd + +Any three of the five shares among acdef can be used to recover the secret. + +Note that the choice to append two zero bits was arbitrary, and any of the following four secret shares would have been valid choices. +However, each choice would have resulted in a different set of derived shares. + +* ms13cashsllhdmn9m42vcsamx24zrxgs3qqjzqud4m0d6nln +* ms13cashsllhdmn9m42vcsamx24zrxgs3qpte35dvzkjpt0r +* ms13cashsllhdmn9m42vcsamx24zrxgs3qzfatvdwq5692k6 +* ms13cashsllhdmn9m42vcsamx24zrxgs3qrsx6ydhed97jx2 + +===Test vector 4=== + +This example shows converting a 256-bit secret into a codex32 secret, without splitting the secret into any shares. +We appended four zero bits in order to obtain 52 Bech32 characters (260 bits of data) from the 256-bit secret. + +256-bit secret (hex): ffeeddccbbaa99887766554433221100ffeeddccbbaa99887766554433221100 + +* codex32 secret: ms10leetsllhdmn9m42vcsamx24zrxgs3qrl7ahwvhw4fnzrhve25gvezzyqqtum9pgv99ycma +* master node xprv: xprv9s21ZrQH143K3s41UCWxXTsU4TRrhkpD1t21QJETan3hjo8DP5LFdFcB5eaFtV8x6Y9aZotQyP8KByUjgLTbXCUjfu2iosTbMv98g8EQoqr + +Note that the choice to append four zero bits was arbitrary, and any of the following sixteen codex32 secrets would have been valid: + +* ms10leetsllhdmn9m42vcsamx24zrxgs3qrl7ahwvhw4fnzrhve25gvezzyqqtum9pgv99ycma +* ms10leetsllhdmn9m42vcsamx24zrxgs3qrl7ahwvhw4fnzrhve25gvezzyqpj82dp34u6lqtd +* ms10leetsllhdmn9m42vcsamx24zrxgs3qrl7ahwvhw4fnzrhve25gvezzyqzsrs4pnh7jmpj5 +* ms10leetsllhdmn9m42vcsamx24zrxgs3qrl7ahwvhw4fnzrhve25gvezzyqrfcpap2w8dqezy +* ms10leetsllhdmn9m42vcsamx24zrxgs3qrl7ahwvhw4fnzrhve25gvezzyqy5tdvphn6znrf0 +* ms10leetsllhdmn9m42vcsamx24zrxgs3qrl7ahwvhw4fnzrhve25gvezzyq9dsuypw2ragmel +* ms10leetsllhdmn9m42vcsamx24zrxgs3qrl7ahwvhw4fnzrhve25gvezzyqx05xupvgp4v6qx +* ms10leetsllhdmn9m42vcsamx24zrxgs3qrl7ahwvhw4fnzrhve25gvezzyq8k0h5p43c2hzsk +* ms10leetsllhdmn9m42vcsamx24zrxgs3qrl7ahwvhw4fnzrhve25gvezzyqgum7hplmjtr8ks +* ms10leetsllhdmn9m42vcsamx24zrxgs3qrl7ahwvhw4fnzrhve25gvezzyqf9q0lpxzt5clxq +* ms10leetsllhdmn9m42vcsamx24zrxgs3qrl7ahwvhw4fnzrhve25gvezzyq28y48pyqfuu7le +* ms10leetsllhdmn9m42vcsamx24zrxgs3qrl7ahwvhw4fnzrhve25gvezzyqt7ly0paesr8x0f +* ms10leetsllhdmn9m42vcsamx24zrxgs3qrl7ahwvhw4fnzrhve25gvezzyqvrvg7pqydv5uyz +* ms10leetsllhdmn9m42vcsamx24zrxgs3qrl7ahwvhw4fnzrhve25gvezzyqd6hekpea5n0y5j +* ms10leetsllhdmn9m42vcsamx24zrxgs3qrl7ahwvhw4fnzrhve25gvezzyqwcnrwpmlkmt9dt +* ms10leetsllhdmn9m42vcsamx24zrxgs3qrl7ahwvhw4fnzrhve25gvezzyq0pgjxpzx0ysaam + +===Test vector 5=== + +This example shows generating a new 512-bit master seed using "random" codex32 characters and appending a checksum. +The payload contains 103 Bech32 characters, which corresponds to 515 bits. The last three bits are discarded when converting to a 512-bit master seed. + +This is an example of a '''Long codex32 String'''. + +* Secret share with index S: MS100C8VSM32ZXFGUHPCHTLUPZRY9X8GF2TVDW0S3JN54KHCE6MUA7LQPZYGSFJD6AN074RXVCEMLH8WU3TK925ACDEFGHJKLMNPQRSTUVWXY06FHPV80UNDVARHRAK +* Master secret (hex): dc5423251cb87175ff8110c8531d0952d8d73e1194e95b5f19d6f9df7c01111104c9baecdfea8cccc677fb9ddc8aec5553b86e528bcadfdcc201c17c638c47e9 +* master node xprv: xprv9s21ZrQH143K4UYT4rP3TZVKKbmRVmfRqTx9mG2xCy2JYipZbkLV8rwvBXsUbEv9KQiUD7oED1Wyi9evZzUn2rqK9skRgPkNaAzyw3YrpJN + +===Invalid test vectors=== + +These examples have incorrect checksums. + +* ms10fauxsxxxxxxxxxxxxxxxxxxxxxxxxxxve740yyge2ghq +* ms10fauxsxxxxxxxxxxxxxxxxxxxxxxxxxxve740yyge2ghp +* ms10fauxsxxxxxxxxxxxxxxxxxxxxxxxxxxxxlk3yepcstwr +* ms10fauxsxxxxxxxxxxxxxxxxxxxxxxxxxxx6pgnv7jnpcsp +* ms10fauxsxxxxxxxxxxxxxxxxxxxxxxxxxxxx0cpvr7n4geq +* ms10fauxsxxxxxxxxxxxxxxxxxxxxxxxxxxxxm5252y7d3lr +* ms10fauxsxxxxxxxxxxxxxxxxxxxxxxxxxxxrd9sukzl05ej +* ms10fauxsxxxxxxxxxxxxxxxxxxxxxxxxxxxxc55srw5jrm0 +* ms10fauxsxxxxxxxxxxxxxxxxxxxxxxxxxxxxgc7rwhtudwc +* ms10fauxsxxxxxxxxxxxxxxxxxxxxxxxxxxx4gy22afwghvs +* ms10fauxsxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxme084q0vpht7pe0 +* ms10fauxsxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxme084q0vpht7pew +* ms10fauxsxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxqyadsp3nywm8a +* ms10fauxsxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxzvg7ar4hgaejk +* ms10fauxsxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxcznau0advgxqe +* ms10fauxsxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxch3jrc6j5040j +* ms10fauxsxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx52gxl6ppv40mcv +* ms10fauxsxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx7g4g2nhhle8fk +* ms10fauxsxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx63m45uj8ss4x8 +* ms10fauxsxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxy4r708q7kg65x + +These examples use the wrong checksum for their given data sizes. + +* ms10fauxsxxxxxxxxxxxxxxxxxxxxxxxxurfvwmdcmymdufv +* ms10fauxsxxxxxxxxxxxxxxxxxxxxxxxxxxcsyppjkd8lz4hx3 +* ms10fauxsxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxu6hwvl5p0l9xf3c +* ms10fauxsxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxwqey9rfs6smenxa +* ms10fauxsxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxv70wkzrjr4ntqet +* ms10fauxsxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx3hmlrmpa4zl0v +* ms10fauxsxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxrfggf88znkaup +* ms10fauxsxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxpt7l4aycv9qzj +* ms10fauxsxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxus27z9xtyxyw3 +* ms10fauxsxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxcwm4re8fs78vn + +These examples have improper lengths. +They are either too short, too long, or would decode to byte sequence with an incomplete group greater than 4 bits. + +* ms10fauxsxxxxxxxxxxxxxxxxxxxxxxxxw0a4c70rfefn4 +* ms10fauxsxxxxxxxxxxxxxxxxxxxxxxxxxk4pavy5n46nea +* ms10fauxsxxxxxxxxxxxxxxxxxxxxxxxxxxx9lrwar5zwng4w +* ms10fauxsxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxr335l5tv88js3 +* ms10fauxsxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxvu7q9nz8p7dj68v +* ms10fauxsxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxpq6k542scdxndq3 +* ms10fauxsxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxkmfw6jm270mz6ej +* ms12fauxxxxxxxxxxxxxxxxxxxxxxxxxxzhddxw99w7xws +* ms12fauxxxxxxxxxxxxxxxxxxxxxxxxxxxx42cux6um92rz +* ms12fauxxxxxxxxxxxxxxxxxxxxxxxxxxxxxarja5kqukdhy9 +* ms12fauxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxky0ua3ha84qk8 +* ms12fauxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx9eheesxadh2n2n9 +* ms12fauxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx9llwmgesfulcj2z +* ms12fauxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx02ev7caq6n9fgkf + +This example uses a "0" threshold with a non-"s" index + +* ms10fauxxxxxxxxxxxxxxxxxxxxxxxxxxxx0z26tfn0ulw3p + +This example has a threshold that is not a digit. + +* ms1fauxxxxxxxxxxxxxxxxxxxxxxxxxxxxxda3kr3s0s2swg + +These examples do not begin with the required "ms" or "MS" prefix and/or are missing the "1" separator. + +* 0fauxsxxxxxxxxxxxxxxxxxxxxxxxxxxuqxkk05lyf3x2 +* 10fauxsxxxxxxxxxxxxxxxxxxxxxxxxxxuqxkk05lyf3x2 +* ms0fauxsxxxxxxxxxxxxxxxxxxxxxxxxxxuqxkk05lyf3x2 +* m10fauxsxxxxxxxxxxxxxxxxxxxxxxxxxxuqxkk05lyf3x2 +* s10fauxsxxxxxxxxxxxxxxxxxxxxxxxxxxuqxkk05lyf3x2 +* 0fauxsxxxxxxxxxxxxxxxxxxxxxxxxxxhkd4f70m8lgws +* 10fauxsxxxxxxxxxxxxxxxxxxxxxxxxxxhkd4f70m8lgws +* m10fauxsxxxxxxxxxxxxxxxxxxxxxxxxxx8t28z74x8hs4l +* s10fauxsxxxxxxxxxxxxxxxxxxxxxxxxxxh9d0fhnvfyx3x + +These examples all incorrectly mix upper and lower case characters. + +* Ms10fauxsxxxxxxxxxxxxxxxxxxxxxxxxxxuqxkk05lyf3x2 +* mS10fauxsxxxxxxxxxxxxxxxxxxxxxxxxxxuqxkk05lyf3x2 +* MS10fauxsxxxxxxxxxxxxxxxxxxxxxxxxxxuqxkk05lyf3x2 +* ms10FAUXsxxxxxxxxxxxxxxxxxxxxxxxxxxuqxkk05lyf3x2 +* ms10fauxSxxxxxxxxxxxxxxxxxxxxxxxxxxuqxkk05lyf3x2 +* ms10fauxsXXXXXXXXXXXXXXXXXXXXXXXXXXuqxkk05lyf3x2 +* ms10fauxsxxxxxxxxxxxxxxxxxxxxxxxxxxUQXKK05LYF3X2 + +==Appendix== + +===Mathematical Companion=== + +Below we use the Bech32 character set to denote values in GF[32]. +In Bech32, the letter Q denotes zero and the letter P denotes one. +The digits 0 and 2 through 9 do ''not'' denote their numeric values. +They are simply elements of GF[32]. + +The generating polynomial for our BCH code is as follows. + +We extend GF[32] to GF[1024] by adjoining a primitive cube root of unity, ζ, satisfying ζ^2 = ζ + P. + +We select β := G ζ which has order 93, and construct the product (x - β^i) for i in {17, 20, 46, 49, 52, 77, 78, 79, 80, 81, 82, 83, 84}. +The resulting polynomial is our generating polynomial for our 13 character checksum: + + x^13 + E x^12 + M x^11 + 3 x^10 + G x^9 + Q x^8 + E x^7 + E x^6 + E x^5 + L x^4 + M x^3 + C x^2 + S x + S + +For our long checksum, we select γ := E + X ζ, which has order 1023, and construct the product (x - γ^i) for i in {32, 64, 96, 895, 927, 959, 991, 1019, 1020, 1021, 1022, 1023, 1024, 1025, 1026}. +The resulting polynomial is our generating polynomial for our 15 character checksum for long strings: + + x^15 + 0 x^14 + 2 x^13 + E x^12 + 6 x^11 + F x^10 + E x^9 + 4 x^8 + X x^7 + H x^6 + 4 x^5 + X x^4 + 9 x^3 + K x^2 + Y x^1 + H + +(Reminder: the character 0 does ''not'' denote the zero of the field.) From 59915dfc71ddc558f76a72ebd8e84cad184d3143 Mon Sep 17 00:00:00 2001 From: Sebastian Falbesoner Date: Sun, 19 Mar 2023 19:12:29 +0100 Subject: [PATCH 061/454] bip-0324: remove `initiating` parameter from `ellswift_create` calls --- bip-0324.mediawiki | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/bip-0324.mediawiki b/bip-0324.mediawiki index c0572a3313..a85e7da967 100644 --- a/bip-0324.mediawiki +++ b/bip-0324.mediawiki @@ -181,11 +181,11 @@ As explained before, these messages are sent to set up the connection: ---------------------------------------------------------------------------------------------------- | Initiator Responder | | | - | x, ellswift_X = ellswift_create(initiating=True) | + | x, ellswift_X = ellswift_create() | | | | --- ellswift_X + initiator_garbage (initiator_garbage_len bytes; max 4095) ---> | | | - | y, ellswift_Y = ellswift_create(initiating=False) | + | y, ellswift_Y = ellswift_create() | | ecdh_secret = v2_ecdh( | | y, ellswift_X, ellswift_Y, initiating=False) | | v2_initialize(initiator, ecdh_secret, initiating=False) | @@ -333,7 +333,7 @@ To establish a v2 encrypted connection, the initiator generates an ephemeral sec
 def initiate_v2_handshake(peer, garbage_len):
-    peer.privkey_ours, peer.ellswift_ours = ellswift_create(initiating=True)
+    peer.privkey_ours, peer.ellswift_ours = ellswift_create()
     peer.sent_garbage = rand_bytes(garbage_len)
     send(peer, peer.ellswift_ours + peer.sent_garbage)
 
@@ -350,7 +350,7 @@ def respond_v2_handshake(peer, garbage_len): while len(peer.received_prefix) < 12: peer.received_prefix += receive(peer, 1) if peer.received_prefix[-1] != V1_PREFIX[len(peer.received_prefix) - 1]: - peer.privkey_ours, peer.ellswift_ours = ellswift_create(initiating=False) + peer.privkey_ours, peer.ellswift_ours = ellswift_create() peer.sent_garbage = rand_bytes(garbage_len) send(peer, ellswift_Y + peer.sent_garbage) return From 4f03aaea2c1a830e0676830713c45577f6f45989 Mon Sep 17 00:00:00 2001 From: James O'Beirne Date: Thu, 23 Feb 2023 08:57:45 -0500 Subject: [PATCH 062/454] vaults: add backwards compatibility --- bip-vaults.mediawiki | 12 ++++++++++++ 1 file changed, 12 insertions(+) diff --git a/bip-vaults.mediawiki b/bip-vaults.mediawiki index 5a91447f4d..570b95b811 100644 --- a/bip-vaults.mediawiki +++ b/bip-vaults.mediawiki @@ -635,6 +635,18 @@ Script descriptors for vault-related outputs will be covered in a subsequent BIP TBD +== Backwards compatibility == + +OP_VAULT and OP_UNVAULT replace, respectively, the witness v1-only opcodes OP_SUCCESS187 and OP_SUCCESS188 with +stricter verification semantics. Consequently, scripts using those opcodes which previously were valid will cease to be valid with this change. + +Stricter verification semantics for an OP_SUCCESSx opcode are a soft fork, so existing software will be fully functional without upgrade except for mining and block validation. + +Backwards compatibility considerations are very comparable to previous +deployments for OP_CHECKSEQUENCEVERIFY and OP_CHECKLOCKTIMEVERIFY (see [https://github.com/bitcoin/bips/blob/master/bip-0065.mediawiki BIP-0065] +and [https://github.com/bitcoin/bips/blob/master/bip-0112.mediawiki BIP-0112]). + + == Rationale == From 6dc766d937a20ce3bb0f56979c203562508112a3 Mon Sep 17 00:00:00 2001 From: James O'Beirne Date: Thu, 23 Feb 2023 09:14:15 -0500 Subject: [PATCH 063/454] vaults: add Corey Haddad reference --- bip-vaults.mediawiki | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/bip-vaults.mediawiki b/bip-vaults.mediawiki index 570b95b811..5acedbafde 100644 --- a/bip-vaults.mediawiki +++ b/bip-vaults.mediawiki @@ -83,7 +83,7 @@ timelocked coins for perpetuity or relying on a trusted third party. [[File:bip-VAULT/vaults-Basic.png|frame|center]] Vaults in Bitcoin have been discussed formally since 2016 -([http://fc16.ifca.ai/bitcoin/papers/MES16.pdf MES16]) or earlier. The value of +([http://fc16.ifca.ai/bitcoin/papers/MES16.pdf MES16]) and informally since [https://web.archive.org/web/20160220215151/https://bitcointalk.org/index.php?topic=511881.0 2014]. The value of having a configurable delay period with recovery capability in light of an unexpected spend has been widely recognized. From f30fb52bbb165982823f8af131c8ff6ffb56eba6 Mon Sep 17 00:00:00 2001 From: Jameson Lopp Date: Tue, 28 Feb 2023 15:59:11 -0500 Subject: [PATCH 064/454] date fix copypasta FTW --- bip-vaults.mediawiki | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/bip-vaults.mediawiki b/bip-vaults.mediawiki index 5acedbafde..1ac8de9ffb 100644 --- a/bip-vaults.mediawiki +++ b/bip-vaults.mediawiki @@ -6,7 +6,7 @@ Comments-URI: https://github.com/bitcoin/bips/wiki/Comments:BIP-xxxx Status: Draft Type: Standards Track - Created: 2020-02-03 + Created: 2023-02-03 License: BSD-3-Clause Post-History: 2023-01-09: https://lists.linuxfoundation.org/pipermail/bitcoin-dev/2023-January/021318.html [bitcoin-dev] OP_VAULT announcment
From 997e4f4f0e92ccbc5f5cdf34c265c7e5e41fa4bc Mon Sep 17 00:00:00 2001 From: James O'Beirne Date: Thu, 2 Mar 2023 09:35:01 -0500 Subject: [PATCH 065/454] Update bip-vaults.mediawiki Co-authored-by: kallewoof --- bip-vaults.mediawiki | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/bip-vaults.mediawiki b/bip-vaults.mediawiki index 1ac8de9ffb..3f56d01a01 100644 --- a/bip-vaults.mediawiki +++ b/bip-vaults.mediawiki @@ -476,9 +476,9 @@ If the above conditions do not fail, a single true value (0x01) is In order to prevent possible pinning attacks, recovery transactions must be replaceable. -* When validating an OP_VAULT/OP_UNVAULT input being spent towards a recovery, the script must FAIL (by policy, not consensus) and terminate immediately if neither'''Why are recovery transactions required to be replaceable?''' In the case of unauthorized recoveries, an attacker may attempt to pin recovery transactions by broadcasting a "rebundled" version with a low fee rate. Vault owners must be able to overcome this with replacement. In the case of authorized recovery, if an attacker steals the recovery authorization key, the attacker may try to pin the recovery transaction during theft. Requiring replaceability ensures that the owner can always raise the fee rate of the recovery transaction, even if they are RBF rule #3 griefed in the process. -*# the input is marked as opt-in replaceable by having an nSequence number less than 0xffffffff - 1, per [https://github.com/bitcoin/bips/blob/master/bip-0125.mediawiki BIP-0125], nor -*# the version of the recovery transaction has an nVersion equal to 3. +* When validating an OP_VAULT/OP_UNVAULT input being spent towards a recovery, the script must FAIL (by policy, not consensus) and terminate immediately if both'''Why are recovery transactions required to be replaceable?''' In the case of unauthorized recoveries, an attacker may attempt to pin recovery transactions by broadcasting a "rebundled" version with a low fee rate. Vault owners must be able to overcome this with replacement. In the case of authorized recovery, if an attacker steals the recovery authorization key, the attacker may try to pin the recovery transaction during theft. Requiring replaceability ensures that the owner can always raise the fee rate of the recovery transaction, even if they are RBF rule #3 griefed in the process. +*# the input is not marked as opt-in replaceable by having an nSequence number less than 0xffffffff - 1, per [https://github.com/bitcoin/bips/blob/master/bip-0125.mediawiki BIP-0125], and +*# the version of the recovery transaction has an nVersion other than 3. In order to prevent pinning attacks in the case of unauthorized recovery, the output structure of unauthorized recovery transaction is limited. From 915ede327af11e7fe41041d98c88e1511763fde5 Mon Sep 17 00:00:00 2001 From: James O'Beirne Date: Thu, 2 Mar 2023 09:41:15 -0500 Subject: [PATCH 066/454] fixup! add Kalle reference --- bip-vaults.mediawiki | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/bip-vaults.mediawiki b/bip-vaults.mediawiki index 3f56d01a01..d6da2bbf41 100644 --- a/bip-vaults.mediawiki +++ b/bip-vaults.mediawiki @@ -739,8 +739,9 @@ CTransaction 9595af9728de3ae9ca6110c040ad34f02f9db8b610296f99618354b99d5ec395: ( == References == -* [https://lists.linuxfoundation.org/pipermail/bitcoin-dev/2016-February/012470.html Bitcoin Vaults (2016)] -* [https://lists.linuxfoundation.org/pipermail/bitcoin-dev/2020-April/017755.html On-chain vaults prototype (2020)] +* [https://lists.linuxfoundation.org/pipermail/bitcoin-dev/2016-February/012470.html [bitcoin-dev] Bitcoin Vaults (2016)] +* [https://lists.linuxfoundation.org/pipermail/bitcoin-dev/2018-February/015793.html [bitcoin-dev] Simple lock/unlock mechanism (2018)] +* [https://lists.linuxfoundation.org/pipermail/bitcoin-dev/2020-April/017755.html [bitcoin-dev] On-chain vaults prototype (2020)] * [https://arxiv.org/abs/2005.11776 Custody Protocols Using Bitcoin Vaults (2020)] * [https://jameso.be/vaults.pdf Vaults and Covenants (2023)] From 87394eaeb436d02e0a68b38a1e94bc526d50056e Mon Sep 17 00:00:00 2001 From: Jonas Nick Date: Tue, 5 Apr 2022 22:29:59 +0000 Subject: [PATCH 067/454] Add BIP327: MuSig2 for BIP340-compatible Multi-Signatures --- README.mediawiki | 7 + bip-0327.mediawiki | 828 ++++++++++++++++++++ bip-0327/gen_vectors_helper.py | 184 +++++ bip-0327/reference.py | 880 ++++++++++++++++++++++ bip-0327/tests.sh | 8 + bip-0327/vectors/det_sign_vectors.json | 144 ++++ bip-0327/vectors/key_agg_vectors.json | 88 +++ bip-0327/vectors/key_sort_vectors.json | 18 + bip-0327/vectors/nonce_agg_vectors.json | 51 ++ bip-0327/vectors/nonce_gen_vectors.json | 44 ++ bip-0327/vectors/sig_agg_vectors.json | 151 ++++ bip-0327/vectors/sign_verify_vectors.json | 212 ++++++ bip-0327/vectors/tweak_vectors.json | 84 +++ 13 files changed, 2699 insertions(+) create mode 100644 bip-0327.mediawiki create mode 100644 bip-0327/gen_vectors_helper.py create mode 100644 bip-0327/reference.py create mode 100755 bip-0327/tests.sh create mode 100644 bip-0327/vectors/det_sign_vectors.json create mode 100644 bip-0327/vectors/key_agg_vectors.json create mode 100644 bip-0327/vectors/key_sort_vectors.json create mode 100644 bip-0327/vectors/nonce_agg_vectors.json create mode 100644 bip-0327/vectors/nonce_gen_vectors.json create mode 100644 bip-0327/vectors/sig_agg_vectors.json create mode 100644 bip-0327/vectors/sign_verify_vectors.json create mode 100644 bip-0327/vectors/tweak_vectors.json diff --git a/README.mediawiki b/README.mediawiki index 966de69caf..72f26a3942 100644 --- a/README.mediawiki +++ b/README.mediawiki @@ -1009,6 +1009,13 @@ Those proposing changes should consider that ultimately consent may rest with th | Informational | Draft |- +| [[bip-0327.mediawiki|327]] +| +| MuSig2 for BIP340-compatible Multi-Signatures +| Jonas Nick, Tim Ruffing, Elliott Jin +| Informational +| Draft +|- | [[bip-0329.mediawiki|329]] | Applications | Wallet Labels Export Format diff --git a/bip-0327.mediawiki b/bip-0327.mediawiki new file mode 100644 index 0000000000..17ccbe5223 --- /dev/null +++ b/bip-0327.mediawiki @@ -0,0 +1,828 @@ +
+  BIP: 327
+  Title: MuSig2 for BIP340-compatible Multi-Signatures
+  Author: Jonas Nick 
+          Tim Ruffing 
+          Elliott Jin 
+  Status: Draft
+  License: BSD-3-Clause
+  Type: Informational
+  Created: 2022-03-22
+  Post-History: 2022-04-05: https://lists.linuxfoundation.org/pipermail/bitcoin-dev/2022-April/020198.html [bitcoin-dev] MuSig2 BIP
+                2022-10-11: https://lists.linuxfoundation.org/pipermail/bitcoin-dev/2022-October/021000.html [bitcoin-dev] MuSig2 BIP
+
+ +== Introduction == + +=== Abstract === + +This document proposes a standard for the [https://eprint.iacr.org/2020/1261.pdf MuSig2] multi-signature scheme. +The standard is compatible with [https://github.com/bitcoin/bips/blob/master/bip-0340.mediawiki BIP340] public keys and signatures. +It supports ''tweaking'', which allows deriving [https://github.com/bitcoin/bips/blob/master/bip-0032.mediawiki BIP32] child keys from aggregate public keys and creating [https://github.com/bitcoin/bips/blob/master/bip-0341.mediawiki BIP341] Taproot outputs with key and script paths. + +=== Copyright === + +This document is licensed under the 3-clause BSD license. + +=== Motivation === + +MuSig2 is a multi-signature scheme that allows multiple signers to create a single aggregate public key and cooperatively create ordinary Schnorr signatures valid under the aggregate public key. +Signing requires interaction between ''all'' signers involved in key aggregation. +(MuSig2 is a ''n-of-n'' multi-signature scheme and not a ''t-of-n'' threshold-signature scheme.) + +The primary motivation is to create a standard that allows users of different software projects to jointly control Taproot outputs ([https://github.com/bitcoin/bips/blob/master/bip-0341.mediawiki BIP341]). +Such an output contains a public key which, in this case, would be the aggregate of all users' individual public keys. +It can be spent using MuSig2 to produce a signature for the key-based spending path. + +The on-chain footprint of a MuSig2 Taproot output is essentially a single BIP340 public key, and a transaction spending the output only requires a single signature cooperatively produced by all signers. This is '''more compact''' and has '''lower verification cost''' than each signer providing an individual public key and signature, as would be required by an ''n-of-n'' policy implemented using OP_CHECKSIGADD as introduced in ([https://github.com/bitcoin/bips/blob/master/bip-0342.mediawiki BIP342]). +As a side effect, the number ''n'' of signers is not limited by any consensus rules when using MuSig2. + +Moreover, MuSig2 offers a '''higher level of privacy''' than OP_CHECKSIGADD: MuSig2 Taproot outputs are indistinguishable for a blockchain observer from regular, single-signer Taproot outputs even though they are actually controlled by multiple signers. By tweaking an aggregate public key, the shared Taproot output can have script spending paths that are hidden unless used. + +There are multi-signature schemes other than MuSig2 that are fully compatible with Schnorr signatures. +The MuSig2 variant proposed below stands out by combining all the following features: +* '''Simple Key Setup''': Key aggregation is non-interactive and fully compatible with BIP340 public keys. +* '''Two Communication Rounds''': MuSig2 is faster in practice than previous three-round multi-signature schemes such as [https://eprint.iacr.org/2018/068.pdf MuSig1], particularly when signers are connected through high-latency anonymous links. Moreover, the need for fewer communication rounds simplifies the algorithms and reduces the probability that implementations and users make security-relevant mistakes. +* '''Provable security''': MuSig2 has been [https://eprint.iacr.org/2020/1261.pdf proven existentially unforgeable] under the algebraic one-more discrete logarithm (AOMDL) assumption (instead of the discrete logarithm assumption required for single-signer Schnorr signatures). AOMDL is a falsifiable and weaker variant of the well-studied OMDL problem. +* '''Low complexity''': MuSig2 has a substantially lower computational and implementation complexity than alternative schemes like [https://eprint.iacr.org/2020/1057 MuSig-DN]. However, this comes at the cost of having no ability to generate nonces deterministically and the requirement to securely handle signing state. + +=== Design === + +* '''Compatibility with BIP340''': In this proposal, the aggregate public key is a BIP340 X-only public key, and the signature output at the end of the signing protocol is a BIP340 signature that passes BIP340 verification for the aggregate public key and a message. The individual public keys that are input to the key aggregation algorithm are ''plain'' public keys in compressed format. +* '''Tweaking for BIP32 derivations and Taproot''': This proposal supports tweaking aggregate public keys and signing for tweaked aggregate public keys. We distinguish two modes of tweaking: ''Plain'' tweaking can be used to derive child aggregate public keys per [https://github.com/bitcoin/bips/blob/master/bip-0032.mediawiki BIP32]. ''X-only'' tweaking, on the other hand, allows creating a [https://github.com/bitcoin/bips/blob/master/bip-0341.mediawiki BIP341] tweak to add script paths to a Taproot output. See [[#tweaking-the-aggregate-public-key|below]] for details. +* '''Non-interactive signing with preprocessing''': The first communication round, exchanging the nonces, can happen before the message or the exact set of signers is determined. Once the parameters of the signing session are finalized, the signers can send partial signatures without additional interaction. +* '''Key aggregation optionally independent of order''': The output of the key aggregation algorithm depends on the order in which the individual public keys are provided as input. Key aggregation does not sort the individual public keys by default because applications often already have a canonical order of signers. Nonetheless, applications can mandate sorting before aggregation,Applications that sort individual public keys before aggregation should ensure that the implementation of sorting is reasonably efficient, and in particular does not degenerate to quadratic runtime on pathological inputs. and this proposal specifies a canonical order to sort the individual public keys before key aggregation. Sorting will ensure the same output, independent of the initial order. +* '''Third-party nonce and partial signature aggregation''': Instead of every signer sending their nonce and partial signature to every other signer, it is possible to use an untrusted third-party ''aggregator'' in order to reduce the communication complexity from quadratic to linear in the number of signers. In each of the two rounds, the aggregator collects all signers' contributions (nonces or partial signatures), aggregates them, and broadcasts the aggregate back to the signers. A malicious aggregator can force the signing session to fail to produce a valid Schnorr signature but cannot negatively affect the unforgeability of the scheme. +* '''Partial signature verification''': If any signer sends a partial signature contribution that was not created by honestly following the signing protocol, the signing session will fail to produce a valid Schnorr signature. This proposal specifies a partial signature verification algorithm to identify disruptive signers. It is incompatible with third-party nonce aggregation because the individual nonce is required for partial verification. +* '''MuSig2* optimization''': This proposal uses an optimized scheme MuSig2*, which allows saving a point multiplication in key aggregation as compared to MuSig2. MuSig2* is proven secure in the appendix of the [https://eprint.iacr.org/2020/1261 MuSig2 paper]. The optimization consists of assigning the constant key aggregation coefficient ''1'' to the second distinct key in the list of individual public keys to be aggregated (as well as to any key identical to this key). +* '''Size of the nonce and security''': In this proposal, each signer's nonce consists of two elliptic curve points. The [https://eprint.iacr.org/2020/1261 MuSig2 paper] gives distinct security proofs depending on the number of points that constitute a nonce. See section [[#choosing-the-size-of-the-nonce|Choosing the Size of the Nonce]] for a discussion. + +== Overview == + +Implementers must make sure to understand this section thoroughly to avoid subtle mistakes that may lead to catastrophic failure. + +=== Optionality of Features === + +The goal of this proposal is to support a wide range of possible application scenarios. +Given a specific application scenario, some features may be unnecessary or not desirable, and implementers can choose not to support them. +Such optional features include: +* Applying plain tweaks after x-only tweaks. +* Applying tweaks at all. +* Dealing with messages that are not exactly 32 bytes. +* Identifying a disruptive signer after aborting (aborting itself remains mandatory). +* Dealing with duplicate individual public keys in key aggregation. +If applicable, the corresponding algorithms should simply fail when encountering inputs unsupported by a particular implementation. (For example, the signing algorithm may fail when given a message which is not 32 bytes.) +Similarly, the test vectors that exercise the unimplemented features should be re-interpreted to expect an error, or be skipped if appropriate. + +=== General Signing Flow === + +The signers start by exchanging their individual public keys and computing an aggregate public key using the ''KeyAgg'' algorithm. +Whenever they want to sign a message, the basic order of operations to create a multi-signature is as follows: + +'''First broadcast round:''' +The signers start the signing session by running ''NonceGen'' to compute ''secnonce'' and ''pubnonce''.We treat the ''secnonce'' and ''pubnonce'' as grammatically singular even though they include serializations of two scalars and two elliptic curve points, respectively. This treatment may be confusing for readers familiar with the MuSig2 paper. However, serialization is a technical detail that is irrelevant for users of MuSig2 interfaces. +Then, the signers broadcast their ''pubnonce'' to each other and run ''NonceAgg'' to compute an aggregate nonce. + +'''Second broadcast round:''' +At this point, every signer has the required data to sign, which, in the algorithms specified below, is stored in a data structure called [[#session-context|Session Context]]. +Every signer computes a partial signature by running ''Sign'' with the secret signing key, the ''secnonce'' and the session context. +Then, the signers broadcast their partial signatures to each other and run ''PartialSigAgg'' to obtain the final signature. +If all signers behaved honestly, the result passes [https://github.com/bitcoin/bips/blob/master/bip-0340.mediawiki BIP340] verification. + +Both broadcast rounds can be optimized by using an aggregator who collects all signers' nonces or partial signatures, aggregates them using ''NonceAgg'' or ''PartialSigAgg'', respectively, and broadcasts the aggregate result back to the signers. A malicious aggregator can force the signing session to fail to produce a valid Schnorr signature but cannot negatively affect the unforgeability of the scheme, i.e., even a malicious aggregator colluding with all but one signer cannot forge a signature. + +'''IMPORTANT''': The ''Sign'' algorithm must '''not''' be executed twice with the same ''secnonce''. +Otherwise, it is possible to extract the secret signing key from the two partial signatures output by the two executions of ''Sign''. +To avoid accidental reuse of ''secnonce'', an implementation may securely erase the ''secnonce'' argument by overwriting it with 64 zero bytes after it has been read by ''Sign''. +A ''secnonce'' consisting of only zero bytes is invalid for ''Sign'' and will cause it to fail. + +To simplify the specification of the algorithms, some intermediary values are unnecessarily recomputed from scratch, e.g., when executing ''GetSessionValues'' multiple times. +Actual implementations can cache these values. +As a result, the [[#session-context|Session Context]] may look very different in implementations or may not exist at all. +However, computation of ''GetSessionValues'' and storage of the result must be protected against modification from an untrusted third party. +This party would have complete control over the aggregate public key and message to be signed. + +=== Public Key Aggregation === + +We distinguish between two public key types, namely ''plain public keys'', the key type traditionally used in Bitcoin, and ''X-only public keys''. +Plain public keys are byte strings of length 33 (often called ''compressed'' format). +In contrast, X-only public keys are 32-byte strings defined in [https://github.com/bitcoin/bips/blob/master/bip-0340.mediawiki BIP340]. + +The individual public keys of signers as input to the key aggregation algorithm ''KeyAgg'' (and to ''GetSessionValues'' and ''PartialSigVerify'') are plain public keys. +The output of ''KeyAgg'' is a [[#keyagg-context|KeyAgg Context]] which stores information required for tweaking the aggregate public key (see [[#tweaking-the-aggregate-public-key|below]]), +and it can be used to produce an X-only aggregate public key, or a plain aggregate public key. +In order to obtain an X-only public key compatible with BIP340 verification, implementations call the ''GetXonlyPubkey'' function with the KeyAgg Context. +To get the plain aggregate public key, which is required for some applications of [[#tweaking-the-aggregate-public-key|tweaking]], implementations call ''GetPlainPubkey'' instead. + +The aggregate public key produced by ''KeyAgg'' (regardless of the type) depends on the order of the individual public keys. +If the application does not have a canonical order of the signers, the individual public keys can be sorted with the ''KeySort'' algorithm to ensure that the aggregate public key is independent of the order of signers. + +The same individual public key is allowed to occur more than once in the input of ''KeyAgg'' and ''KeySort''. +This is by design: All algorithms in this proposal handle multiple signers who (claim to) have identical individual public keys properly, +and applications are not required to check for duplicate individual public keys. +In fact, applications are recommended to omit checks for duplicate individual public keys in order to simplify error handling. +Moreover, it is often impossible to tell at key aggregation which signer is to blame for the duplicate, i.e., which signer came up with an individual public key honestly and which disruptive signer copied it. +In contrast, MuSig2 is designed to identify disruptive signers at signing time (see [[#identifiying-disruptive-signers|Identifiying Disruptive Signers]]). + +While the algorithms in this proposal are able to handle duplicate individual public keys, there are scenarios where applications may choose to abort when encountering duplicates. +For example, we can imagine a scenario where a single entity creates a MuSig2 setup with multiple signing devices. +In that case, duplicates may not result from a malicious signing device copying an individual public key of another signing device but from accidental initialization of two devices with the same seed. +Since MuSig2 key aggregation would accept the duplicate keys and not error out, which would in turn reduce the security compared to the intended key setup, applications may reject duplicate individual public keys before passing them to MuSig2 key aggregation and ask the user to investigate. + +=== Nonce Generation === + +'''IMPORTANT''': ''NonceGen'' must have access to a high-quality random generator to draw an unbiased, uniformly random value ''rand' ''. +In contrast to BIP340 signing, the values ''k1'' and ''k2'' '''must not be derived deterministically''' from the session parameters because otherwise active adversaries can [https://medium.com/blockstream/musig-dn-schnorr-multisignatures-with-verifiably-deterministic-nonces-27424b5df9d6#e3b6 trick the victim into reusing a nonce]. + +The optional arguments to ''NonceGen'' enable a defense-in-depth mechanism that may prevent secret key exposure if ''rand' '' is accidentally not drawn uniformly at random. +If the value ''rand' '' was identical in two ''NonceGen'' invocations, but any other argument was different, the ''secnonce'' would still be guaranteed to be different as well (with overwhelming probability), and thus accidentally using the same ''secnonce'' for ''Sign'' in both sessions would be avoided. +Therefore, it is recommended to provide the optional arguments ''sk'', ''aggpk'', and ''m'' if these session parameters are already determined during nonce generation. +The auxiliary input ''extra_in'' can contain additional contextual data that has a chance of changing between ''NonceGen'' runs, +e.g., a supposedly unique session id (taken from the application), a session counter wide enough not to repeat in practice, any nonces by other signers (if already known), or the serialization of a data structure containing multiple of the above. +However, the protection provided by the optional arguments should only be viewed as a last resort. +In most conceivable scenarios, the assumption that the arguments are different between two executions of ''NonceGen'' is relatively strong, particularly when facing an active adversary. + +In some applications, it is beneficial to generate and send a ''pubnonce'' before the other signers, their individual public keys, or the message to sign is known. +In this case, only the available arguments are provided to the ''NonceGen'' algorithm. +After this preprocessing phase, the ''Sign'' algorithm can be run immediately when the message and set of signers is determined. +This way, the final signature is created quicker and with fewer round trips. +However, applications that use this method presumably store the nonces for a longer time and must therefore be even more careful not to reuse them. +Moreover, this method is not compatible with the defense-in-depth mechanism described in the previous paragraph. + +Instead of every signer broadcasting their ''pubnonce'' to every other signer, the signers can send their ''pubnonce'' to a single aggregator node that runs ''NonceAgg'' and sends the ''aggnonce'' back to the signers. +This technique reduces the overall communication. +A malicious aggregator can force the signing session to fail to produce a valid Schnorr signature but cannot negatively affect the unforgeability of the scheme. + +In general, MuSig2 signers are stateful in the sense that they first generate ''secnonce'' and then need to store it until they receive the other signers' ''pubnonces'' or the ''aggnonce''. +However, it is possible for one of the signers to be stateless. +This signer waits until it receives the ''pubnonce'' of all the other signers and until session parameters such as a message to sign, individual public keys, and tweaks are determined. +Then, the signer can run ''NonceGen'', ''NonceAgg'' and ''Sign'' in sequence and send out its ''pubnonce'' along with its partial signature. +Stateless signers may want to consider signing deterministically (see [[#modifications-to-nonce-generation|Modifications to Nonce Generation]]) to remove the reliance on the random number generator in the ''NonceGen'' algorithm. + +=== Identifying Disruptive Signers === + +The signing protocol makes it possible to identify malicious signers who send invalid contributions to a signing session in order to make the signing session abort and prevent the honest signers from obtaining a valid signature. +This property is called "identifiable aborts" and ensures that honest parties can assign blame to malicious signers who cause an abort in the signing protocol. + +Aborts are identifiable for an honest party if the following conditions hold in a signing session: +* The contributions received from all signers have not been tampered with (e.g., because they were sent over authenticated connections). +* Nonce aggregation is performed honestly (e.g., because the honest signer performs nonce aggregation on its own or because the aggregator is trusted). +* The partial signatures received from all signers are verified using the algorithm ''PartialSigVerify''. + +If these conditions hold and an honest party (signer or aggregator) runs an algorithm that fails due to invalid protocol contributions from malicious signers, then the algorithm run by the honest party will output the index of exactly one malicious signer. +Additionally, if the honest parties agree on the contributions sent by all signers in the signing session, all the honest parties who run the aborting algorithm will identify the same malicious signer. + +==== Further Remarks ==== + +Some of the algorithms specified below may also assign blame to a malicious aggregator. +While this is possible for some particular misbehavior of the aggregator, it is not guaranteed that a malicious aggregator can be identified. +More specifically, a malicious aggregator (whose existence violates the second condition above) can always make signing abort and wrongly hold honest signers accountable for the abort (e.g., by claiming to have received an invalid contribution from a particular honest signer). + +The only purpose of the algorithm ''PartialSigVerify'' is to ensure identifiable aborts, and it is not necessary to use it when identifiable aborts are not desired. +In particular, partial signatures are ''not'' signatures. +An adversary can forge a partial signature, i.e., create a partial signature without knowing the secret key for the claimed individual public key.Assume an adversary wants to forge a partial signature for individual public key ''P''. It joins the signing session pretending to be two different signers, one with individual public key ''P'' and one with another individual public key. The adversary can then set the second signer's nonce such that it will be able to produce a partial signature for ''P'' but not for the other claimed signer. An explanation of the individual steps required to create a partial signature forgery can be found in [https://gist.github.com/AdamISZ/ca974ed67889cedc738c4a1f65ff620b a write up by Adam Gibson]. +However, if ''PartialSigVerify'' succeeds for all partial signatures then ''PartialSigAgg'' will return a valid Schnorr signature.Given a list of individual public keys, it is an open question whether a BIP-340 signature valid under the corresponding aggregate public key is a proof of knowledge of all secret keys of the individual public keys. + +=== Tweaking the Aggregate Public Key === + +The aggregate public key can be ''tweaked'', which modifies the key as defined in the [[#tweaking-definition|Tweaking Definition]] subsection. +In order to apply a tweak, the KeyAgg Context output by ''KeyAgg'' is provided to the ''ApplyTweak'' algorithm with the ''is_xonly_t'' argument set to false for plain tweaking and true for X-only tweaking. +The resulting KeyAgg Context can be used to apply another tweak with ''ApplyTweak'' or obtain the aggregate public key with ''GetXonlyPubkey'' or ''GetPlainPubkey''. + +In addition to individual public keys, the ''KeyAgg'' algorithm accepts tweaks, which modify the aggregate public key as defined in the [[#tweaking-definition|Tweaking Definition]] subsection. +For example, if ''KeyAgg'' is run with ''v = 2'', ''is_xonly_t1 = false'', ''is_xonly_t2 = true'', then the aggregate key is first plain tweaked with ''tweak1'' and then X-only tweaked with ''tweak2''. + +The purpose of supporting tweaking is to ensure compatibility with existing uses of tweaking, i.e., that the result of signing is a valid signature for the tweaked public key. +The MuSig2 algorithms take arbitrary tweaks as input but accepting arbitrary tweaks may negatively affect the security of the scheme.It is an open question whether allowing arbitrary tweaks from an adversary affects the unforgeability of MuSig2. +Instead, signers should obtain the tweaks according to other specifications. +This typically involves deriving the tweaks from a hash of the aggregate public key and some other information. +Depending on the specific scheme that is used for tweaking, either the plain or the X-only aggregate public key is required. +For example, to do [https://github.com/bitcoin/bips/blob/master/bip-0032.mediawiki BIP32] derivation, you call ''GetPlainPubkey'' to be able to compute the tweak, whereas [https://github.com/bitcoin/bips/blob/master/bip-0341.mediawiki BIP341] TapTweaks require X-only public keys that are obtained with ''GetXonlyPubkey''. + +The tweak mode provided to ''ApplyTweak'' depends on the application: +Plain tweaking can be used to derive child public keys from an aggregate public key using [https://github.com/bitcoin/bips/blob/master/bip-0032.mediawiki BIP32]. +On the other hand, X-only tweaking is required for Taproot tweaking per [https://github.com/bitcoin/bips/blob/master/bip-0341.mediawiki BIP341]. +A Taproot-tweaked public key commits to a ''script path'', allowing users to create transaction outputs that are spendable either with a MuSig2 multi-signature or by providing inputs that satisfy the script path. +Script path spends require a control block that contains a parity bit for the tweaked X-only public key. +The bit can be obtained with ''GetPlainPubkey(keyagg_ctx)[0] & 1''. + +== Algorithms == + +The following specification of the algorithms has been written with a focus on clarity. +As a result, the specified algorithms are not always optimal in terms of computation and space. +In particular, some values are recomputed but can be cached in actual implementations (see [[#signing-flow|Signing Flow]]). + +=== Notation === + +The following conventions are used, with constants as defined for [https://www.secg.org/sec2-v2.pdf secp256k1]. We note that adapting this proposal to other elliptic curves is not straightforward and can result in an insecure scheme. +* Lowercase variables represent integers or byte arrays. +** The constant ''p'' refers to the field size, ''0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEFFFFFC2F''. +** The constant ''n'' refers to the curve order, ''0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEBAAEDCE6AF48A03BBFD25E8CD0364141''. +* Uppercase variables refer to points on the curve with equation ''y2 = x3 + 7'' over the integers modulo ''p''. +** ''is_infinite(P)'' returns whether ''P'' is the point at infinity. +** ''x(P)'' and ''y(P)'' are integers in the range ''0..p-1'' and refer to the X and Y coordinates of a point ''P'' (assuming it is not infinity). +** The constant ''G'' refers to the base point, for which ''x(G) = 0x79BE667EF9DCBBAC55A06295CE870B07029BFCDB2DCE28D959F2815B16F81798'' and ''y(G) = 0x483ADA7726A3C4655DA4FBFC0E1108A8FD17B448A68554199C47D08FFB10D4B8''. +** Addition of points refers to the usual [https://en.wikipedia.org/wiki/Elliptic_curve#The_group_law elliptic curve group operation]. +** [https://en.wikipedia.org/wiki/Elliptic_curve_point_multiplication Multiplication (⋅) of an integer and a point] refers to the repeated application of the group operation. +* Functions and operations: +** ''||'' refers to byte array concatenation. +** The function ''x[i:j]'', where ''x'' is a byte array and ''i, j ≥ 0'', returns a ''(j - i)''-byte array with a copy of the ''i''-th byte (inclusive) to the ''j''-th byte (exclusive) of ''x''. +** The function ''bytes(n, x)'', where ''x'' is an integer, returns the n-byte encoding of ''x'', most significant byte first. +** The constant ''empty_bytestring'' refers to the empty byte array. It holds that ''len(empty_bytestring) = 0''. +** The function ''xbytes(P)'', where ''P'' is a point for which ''not is_infinite(P)'', returns ''bytes(32, x(P))''. +** The function ''len(x)'' where ''x'' is a byte array returns the length of the array. +** The function ''has_even_y(P)'', where ''P'' is a point for which ''not is_infinite(P)'', returns ''y(P) mod 2 == 0''. +** The function ''with_even_y(P)'', where ''P'' is a point, returns ''P'' if ''is_infinite(P)'' or ''has_even_y(P)''. Otherwise, ''with_even_y(P)'' returns ''-P''. +** The function ''cbytes(P)'', where ''P'' is a point for which ''not is_infinite(P)'', returns ''a || xbytes(P)'' where ''a'' is a byte that is ''2'' if ''has_even_y(P)'' and ''3'' otherwise. +** The function ''cbytes_ext(P)'', where ''P'' is a point, returns ''bytes(33, 0)'' if ''is_infinite(P)''. Otherwise, it returns ''cbytes(P)''. +** The function ''int(x)'', where ''x'' is a 32-byte array, returns the 256-bit unsigned integer whose most significant byte first encoding is ''x''. +** The function ''lift_x(x)'', where ''x'' is an integer in range ''0..2256-1'', returns the point ''P'' for which ''x(P) = x'' + Given a candidate X coordinate ''x'' in the range ''0..p-1'', there exist either exactly two or exactly zero valid Y coordinates. If no valid Y coordinate exists, then ''x'' is not a valid X coordinate either, i.e., no point ''P'' exists for which ''x(P) = x''. The valid Y coordinates for a given candidate ''x'' are the square roots of ''c = x3 + 7 mod p'' and they can be computed as ''y = ±c(p+1)/4 mod p'' (see [https://en.wikipedia.org/wiki/Quadratic_residue#Prime_or_prime_power_modulus Quadratic residue]) if they exist, which can be checked by squaring and comparing with ''c''. and ''has_even_y(P)'', or fails if ''x'' is greater than ''p-1'' or no such point exists. The function ''lift_x(x)'' is equivalent to the following pseudocode: +*** Fail if ''x > p-1''. +*** Let ''c = x3 + 7 mod p''. +*** Let ''y' = c(p+1)/4 mod p''. +*** Fail if ''c ≠ y'2 mod p''. +*** Let ''y = y' '' if ''y' mod 2 = 0'', otherwise let ''y = p - y' ''. +*** Return the unique point ''P'' such that ''x(P) = x'' and ''y(P) = y''. +** The function ''cpoint(x)'', where ''x'' is a 33-byte array (compressed serialization), sets ''P = lift_x(int(x[1:33]))'' and fails if that fails. If ''x[0] = 2'' it returns ''P'' and if ''x[0] = 3'' it returns ''-P''. Otherwise, it fails. +** The function ''cpoint_ext(x)'', where ''x'' is a 33-byte array (compressed serialization), returns the point at infinity if ''x = bytes(33, 0)''. Otherwise, it returns ''cpoint(x)'' and fails if that fails. +** The function ''hashtag(x)'' where ''tag'' is a UTF-8 encoded tag name and ''x'' is a byte array returns the 32-byte hash ''SHA256(SHA256(tag) || SHA256(tag) || x)''. +* Other: +** Tuples are written by listing the elements within parentheses and separated by commas. For example, ''(2, 3, 1)'' is a tuple. + +=== Key Generation and Aggregation === + +==== Key Generation of an Individual Signer ==== + +
+Algorithm ''IndividualPubkey(sk)'':The ''IndividualPubkey'' algorithm matches the key generation procedure traditionally used for ECDSA in Bitcoin +* Inputs: +** The secret key ''sk'': a 32-byte array, freshly generated uniformly at random +* Let ''d' = int(sk)''. +* Fail if ''d' = 0'' or ''d' ≥ n''. +* Return ''cbytes(d'⋅G)''. +
+ +==== KeyAgg Context ==== + +The KeyAgg Context is a data structure consisting of the following elements: +* The point ''Q'' representing the potentially tweaked aggregate public key: an elliptic curve point +* The accumulated tweak ''tacc'': an integer with ''0 ≤ tacc < n'' +* The value ''gacc'' : 1 or -1 mod n + +We write "Let ''(Q, gacc, tacc) = keyagg_ctx''" to assign names to the elements of a KeyAgg Context. + +
+Algorithm ''GetXonlyPubkey(keyagg_ctx)'': +* Let ''(Q, _, _) = keyagg_ctx'' +* Return ''xbytes(Q)'' +
+ +
+Algorithm ''GetPlainPubkey(keyagg_ctx)'': +* Let ''(Q, _, _) = keyagg_ctx'' +* Return ''cbytes(Q)'' +
+ +==== Key Sorting ==== + +
+Algorithm ''KeySort(pk1..u)'': +* Inputs: +** The number ''u'' of individual public keys with ''0 < u < 2^32'' +** The individual public keys ''pk1..u'': ''u'' 33-byte arrays +* Return ''pk1..u'' sorted in lexicographical order. +
+ +==== Key Aggregation ==== + +
+Algorithm ''KeyAgg(pk1..u)'': +* Inputs: +** The number ''u'' of individual public keys with ''0 < u < 2^32'' +** The individual public keys ''pk1..u'': ''u'' 33-byte arrays +* Let ''pk2 = GetSecondKey(pk1..u)'' +* For ''i = 1 .. u'': +** Let ''Pi = cpoint(pki)''; fail if that fails and blame signer ''i'' for invalid individual public key. +** Let ''ai = KeyAggCoeffInternal(pk1..u, pki, pk2)''. +* Let ''Q = a1⋅P1 + a2⋅P2 + ... + au⋅Pu'' +* Fail if ''is_infinite(Q)''. +* Let ''gacc = 1'' +* Let ''tacc = 0'' +* Return ''keyagg_ctx = (Q, gacc, tacc)''. +
+ +
+Internal Algorithm ''HashKeys(pk1..u)'': +* Return ''hashKeyAgg list(pk1 || pk2 || ... || pku)'' +
+ +
+Internal Algorithm ''GetSecondKey(pk1..u)'': +* For ''j = 1 .. u'': +** If ''pkj ≠ pk1'': +*** Return ''pkj'' +* Return ''bytes(33, 0)'' +
+ +
+Internal Algorithm ''KeyAggCoeff(pk1..u, pk')'': +* Let ''pk2 = GetSecondKey(pk1..u)'': +* Return ''KeyAggCoeffInternal(pk1..u, pk', pk2)'' +
+ +
+Internal Algorithm ''KeyAggCoeffInternal(pk1..u, pk', pk2)'': +* Let ''L = HashKeys(pk1..u)'' +* If ''pk' = pk2'': +** Return 1 +* Return ''int(hashKeyAgg coefficient(L || pk')) mod n''The key aggregation coefficient is computed by hashing the individual public key instead of its index, which requires one more invocation of the SHA-256 compression function. However, it results in significantly simpler implementations because signers do not need to translate between public key indices before and after sorting. +
+ +==== Applying Tweaks ==== + +
+Algorithm ''ApplyTweak(keyagg_ctx, tweak, is_xonly_t)'': +* Inputs: +** The ''keyagg_ctx'': a [[#keyagg-context|KeyAgg Context]] data structure +** The ''tweak'': a 32-byte array +** The tweak mode ''is_xonly_t'': a boolean +* Let ''(Q, gacc, tacc) = keyagg_ctx'' +* If ''is_xonly_t'' and ''not has_even_y(Q)'': +** Let ''g = -1 mod n'' +* Else: +** Let ''g = 1'' +* Let ''t = int(tweak)''; fail if ''t ≥ n'' +* Let ''Q' = g⋅Q + t⋅G'' +** Fail if ''is_infinite(Q')'' +* Let ''gacc' = g⋅gacc mod n'' +* Let ''tacc' = t + g⋅tacc mod n'' +* Return ''keyagg_ctx' = (Q', gacc', tacc')'' +
+ +=== Nonce Generation === + +
+Algorithm ''NonceGen(sk, pk, aggpk, m, extra_in)'': +* Inputs: +** The secret signing key ''sk'': a 32-byte array (optional argument) +** The individual public key ''pk'': a 33-byte array (see [[#modifications-to-nonce-generation|Modifications to Nonce Generation]] for the reason that this argument is mandatory) +** The x-only aggregate public key ''aggpk'': a 32-byte array (optional argument) +** The message ''m'': a byte array (optional argument)In theory, the allowed message size is restricted because SHA256 accepts byte strings only up to size of 2^61-1 bytes (and because of the 8-byte length encoding). +** The auxiliary input ''extra_in'': a byte array with ''0 ≤ len(extra_in) ≤ 232-1'' (optional argument) +* Let ''rand' '' be a 32-byte array freshly drawn uniformly at random +* If the optional argument ''sk'' is present: +** Let ''rand'' be the byte-wise xor of ''sk'' and ''hashMuSig/aux(rand')''The random data is hashed (with a unique tag) as a precaution against situations where the randomness may be correlated with the secret signing key itself. It is xored with the secret key (rather than combined with it in a hash) to reduce the number of operations exposed to the actual secret key. +* Else: +** Let ''rand = rand' '' +* If the optional argument ''aggpk'' is not present: +** Let ''aggpk = empty_bytestring'' +* If the optional argument ''m'' is not present: +** Let ''m_prefixed = bytes(1, 0)'' +* Else: +** Let ''m_prefixed = bytes(1, 1) || bytes(8, len(m)) || m'' +* If the optional argument ''extra_in'' is not present: +** Let ''extra_in = empty_bytestring'' +* Let ''ki = int(hashMuSig/nonce(rand || bytes(1, len(pk)) || pk || bytes(1, len(aggpk)) || aggpk || m_prefixed || bytes(4, len(extra_in)) || extra_in || bytes(1, i - 1))) mod n'' for ''i = 1,2'' +* Fail if ''k1 = 0'' or ''k2 = 0'' +* Let ''R⁎,1 = k1⋅G, R⁎,2 = k2⋅G'' +* Let ''pubnonce = cbytes(R⁎,1) || cbytes(R⁎,2)'' +* Let ''secnonce = bytes(32, k1) || bytes(32, k2) || pk''The algorithms as specified here assume that the ''secnonce'' is stored as a 97-byte array using the serialization ''secnonce = bytes(32, k1) || bytes(32, k2) || pk''. The same format is used in the reference implementation and in the test vectors. However, since the ''secnonce'' is (obviously) not meant to be sent over the wire, compatibility between implementations is not a concern, and this method of storing the ''secnonce'' is merely a suggestion.
+The ''secnonce'' is effectively a local data structure of the signer which comprises the value triple ''(k1, k2, pk)'', and implementations may choose any suitable method to carry it from ''NonceGen'' (first communication round) to ''Sign'' (second communication round). In particular, implementations may choose to hide the ''secnonce'' in internal state without exposing it in an API explicitly, e.g., in an effort to prevent callers from reusing a ''secnonce'' accidentally.
+* Return ''(secnonce, pubnonce)'' +
+ +=== Nonce Aggregation === + +
+Algorithm ''NonceAgg(pubnonce1..u)'': +* Inputs: +** The number ''u'' of ''pubnonces'' with ''0 < u < 2^32'' +** The public nonces ''pubnonce1..u'': ''u'' 66-byte arrays +* For ''j = 1 .. 2'': +** For ''i = 1 .. u'': +*** Let ''Ri,j = cpoint(pubnoncei[(j-1)*33:j*33])''; fail if that fails and blame signer ''i'' for invalid ''pubnonce''. +** Let ''Rj = R1,j + R2,j + ... + Ru,j'' +* Return ''aggnonce = cbytes_ext(R1) || cbytes_ext(R2)'' +
+ +=== Session Context === + +The Session Context is a data structure consisting of the following elements: +* The aggregate public nonce ''aggnonce'': a 66-byte array +* The number ''u'' of individual public keys with ''0 < u < 2^32'' +* The individual public keys ''pk1..u'': ''u'' 33-byte arrays +* The number ''v'' of tweaks with ''0 ≤ v < 2^32'' +* The tweaks ''tweak1..v'': ''v'' 32-byte arrays +* The tweak modes ''is_xonly_t1..v'' : ''v'' booleans +* The message ''m'': a byte array + +We write "Let ''(aggnonce, u, pk1..u, v, tweak1..v, is_xonly_t1..v, m) = session_ctx''" to assign names to the elements of a Session Context. + +
+Algorithm ''GetSessionValues(session_ctx)'': +* Let ''(aggnonce, u, pk1..u, v, tweak1..v, is_xonly_t1..v, m) = session_ctx'' +* Let ''keyagg_ctx0 = KeyAgg(pk1..u)''; fail if that fails +* For ''i = 1 .. v'': +** Let ''keyagg_ctxi = ApplyTweak(keyagg_ctxi-1, tweaki, is_xonly_ti)''; fail if that fails +* Let ''(Q, gacc, tacc) = keyagg_ctxv'' +* Let ''b = int(hashMuSig/noncecoef(aggnonce || xbytes(Q) || m)) mod n'' +* Let ''R1 = cpoint_ext(aggnonce[0:33]), R2 = cpoint_ext(aggnonce[33:66])''; fail if that fails and blame nonce aggregator for invalid ''aggnonce''. +* Let ''R' = R1 + b⋅R2'' +* If ''is_infinite(R'): +** Let final nonce ''R = G'' (see [[#dealing-with-infinity-in-nonce-aggregation|Dealing with Infinity in Nonce Aggregation]]) +* Else: +** Let final nonce ''R = R' '' +* Let ''e = int(hashBIP0340/challenge(xbytes(R) || xbytes(Q) || m)) mod n'' +* Return ''(Q, gacc, tacc, b, R, e)'' +
+ +
+Algorithm ''GetSessionKeyAggCoeff(session_ctx, P)'': +* Let ''(_, u, pk1..u, _, _, _, _) = session_ctx'' +* Let ''pk = cbytes(P)'' +* Fail if ''pk'' not in ''pk1..u'' +* Return ''KeyAggCoeff(pk1..u, pk)'' +
+ +=== Signing === + +
+Algorithm ''Sign(secnonce, sk, session_ctx)'': +* Inputs: +** The secret nonce ''secnonce'' that has never been used as input to ''Sign'' before: a 97-byte array +** The secret key ''sk'': a 32-byte array +** The ''session_ctx'': a [[#session-context|Session Context]] data structure +* Let ''(Q, gacc, _, b, R, e) = GetSessionValues(session_ctx)''; fail if that fails +* Let ''k1' = int(secnonce[0:32]), k2' = int(secnonce[32:64])'' +* Fail if ''ki' = 0'' or ''ki' ≥ n'' for ''i = 1..2'' +* Let ''k1 = k1', k2 = k2' '' if ''has_even_y(R)'', otherwise let ''k1 = n - k1', k2 = n - k2' '' +* Let ''d' = int(sk)'' +* Fail if ''d' = 0'' or ''d' ≥ n'' +* Let ''P = d'⋅G'' +* Let ''pk = cbytes(P)'' +* Fail if ''pk ≠ secnonce[64:97]'' +* Let ''a = GetSessionKeyAggCoeff(session_ctx, P)''; fail if that failsFailing ''Sign'' when ''GetSessionKeyAggCoeff(session_ctx, P)'' fails is not necessary for unforgeability. It merely indicates to the caller that the scheme is not being used correctly. +* Let ''g = 1'' if ''has_even_y(Q)'', otherwise let ''g = -1 mod n'' +*
Let ''d = g⋅gacc⋅d' mod n'' (See [[negation-of-the-secret-key-when-signing|Negation Of The Secret Key When Signing]]) +* Let ''s = (k1 + b⋅k2 + e⋅a⋅d) mod n'' +* Let ''psig = bytes(32, s)'' +* Let ''pubnonce = cbytes(k1'⋅G) || cbytes(k2'⋅G)'' +* If ''PartialSigVerifyInternal(psig, pubnonce, pk, session_ctx)'' (see below) returns failure, failVerifying the signature before leaving the signer prevents random or adversarially provoked computation errors. This prevents publishing invalid signatures which may leak information about the secret key. It is recommended but can be omitted if the computation cost is prohibitive. +* Return partial signature ''psig'' +
+ +=== Partial Signature Verification === + +
+Algorithm ''PartialSigVerify(psig, pubnonce1..u, pk1..u, tweak1..v, is_xonly_t1..v, m, i)'': +* Inputs: +** The partial signature ''psig'': a 32-byte array +** The number ''u'' of public nonces and individual public keys with ''0 < u < 2^32'' +** The public nonces ''pubnonce1..u'': ''u'' 66-byte arrays +** The individual public keys ''pk1..u'': ''u'' 33-byte arrays +** The number ''v'' of tweaks with ''0 ≤ v < 2^32'' +** The tweaks ''tweak1..v'': ''v'' 32-byte arrays +** The tweak modes ''is_xonly_t1..v'' : ''v'' booleans +** The message ''m'': a byte array +** The index of the signer ''i'' in the of public nonces and individual public keys with ''0 < i ≤ u'' +* Let ''aggnonce = NonceAgg(pubnonce1..u)''; fail if that fails +* Let ''session_ctx = (aggnonce, u, pk1..u, v, tweak1..v, is_xonly_t1..v, m)'' +* Run ''PartialSigVerifyInternal(psig, pubnoncei, pki, session_ctx)'' +* Return success iff no failure occurred before reaching this point. +
+ +
+Internal Algorithm ''PartialSigVerifyInternal(psig, pubnonce, pk, session_ctx)'': +* Let ''(Q, gacc, _, b, R, e) = GetSessionValues(session_ctx)''; fail if that fails +* Let ''s = int(psig)''; fail if ''s ≥ n'' +* Let ''R⁎,1 = cpoint(pubnonce[0:33]), R⁎,2 = cpoint(pubnonce[33:66])'' +* Let ''Re' = R⁎,1 + b⋅R⁎,2'' +* Let effective nonce ''Re = Re' '' if ''has_even_y(R)'', otherwise let ''Re = -Re' '' +* Let ''P = cpoint(pk)''; fail if that fails +* Let ''a = GetSessionKeyAggCoeff(session_ctx, P)''''GetSessionKeyAggCoeff(session_ctx, P)'' cannot fail when called from ''PartialSigVerifyInternal''. +* Let ''g = 1'' if ''has_even_y(Q)'', otherwise let ''g = -1 mod n'' +*
Let ''g' = g⋅gacc mod n'' (See [[#negation-of-the-individual-public-key-when-partially-verifying|Negation Of The Individual Public Key When Partially Verifying]]) +* Fail if ''s⋅G ≠ Re + e⋅a⋅g'⋅P'' +* Return success iff no failure occurred before reaching this point. +
+ +=== Partial Signature Aggregation === + +
+Algorithm ''PartialSigAgg(psig1..u, session_ctx)'': +* Inputs: +** The number ''u'' of signatures with ''0 < u < 2^32'' +** The partial signatures ''psig1..u'': ''u'' 32-byte arrays +** The ''session_ctx'': a [[#session-context|Session Context]] data structure +* Let ''(Q, _, tacc, _, _, R, e) = GetSessionValues(session_ctx)''; fail if that fails +* For ''i = 1 .. u'': +** Let ''si = int(psigi)''; fail if ''si ≥ n'' and blame signer ''i'' for invalid partial signature. +* Let ''g = 1'' if ''has_even_y(Q)'', otherwise let ''g = -1 mod n'' +* Let ''s = s1 + ... + su + e⋅g⋅tacc mod n'' +* Return ''sig = ''xbytes(R) || bytes(32, s)'' +
+ +=== Test Vectors and Reference Code === + +We provide a naive, highly inefficient, and non-constant time [[bip-0327/reference.py|pure Python 3 reference implementation of the key aggregation, partial signing, and partial signature verification algorithms]]. + +Standalone JSON test vectors are also available in the [[bip-0327|same directory]], to facilitate porting the test vectors into other implementations. + +The reference implementation is for demonstration purposes only and not to be used in production environments. + +== Remarks on Security and Correctness == + +=== Signing with Tweaked Individual Keys === + +The scheme in this proposal has been designed to be secure +even if signers tweak their individual secret keys with tweaks known to the adversary (e.g., as in BIP32 unhardened derivation) +before providing the corresponding individual public keys as input to key aggregation. +In particular, the scheme as specified above requires each signer to provide a final individual public key ''pk'' already to ''NonceGen'', +which writes it into the ''secnonce'' array +so that it can be checked against ''IndividualPubkey(sk)'' in the ''Sign'' algorithm. +The purpose of this check in ''Sign'' is to ensure that ''pk'', +and thus the secret key ''sk'' that will be provided to ''Sign'', +is determined before the signer sends out the ''pubnonce''. + +If the check in ''Sign'' was omitted, +and a signer supported signing with at least two different secret keys ''sk1'' and ''sk2'' +which have been obtained via tweaking another secret key with tweaks known to the adversary, +then the adversary could, after having seen the ''pubnonce'', +influence whether ''sk1'' or ''sk2'' is provided to ''Sign''. +This degree of freedom may allow the adversary to perform a generalized birthday attack and thereby forge a signature +(see [https://lists.linuxfoundation.org/pipermail/bitcoin-dev/2022-October/021000.html bitcoin-dev mailing list post] and [https://github.com/jonasnick/musig2-tweaking writeup] for details). + +Checking ''pk'' against ''InvidualPubkey(sk)'' is a simple way to ensure +that the secret key provided to ''Sign'' is fully determined already when ''NonceGen'' is invoked. +This removes the adversary's ability to influence the secret key after having seen the ''pubnonce'' +and thus rules out the attack.Ensuring that the secret key provided to ''Sign'' is fully determined already when ''NonceGen'' is invoked is a simple policy to rule out the attack, +but more flexible polices are conceivable. +In fact, if the signer uses nothing but the message to be signed and the list of the individual public keys of all signers to decide which secret key to use, +then it is not a problem that the adversary can influence this decision after having seen the ''pubnonce''.
+More formally, consider modified algorithms ''NonceGen' '' and ''Sign' '', where ''NonceGen' '' does not take the individual public key of the signer as input and does not store it in pubnonce, and Sign' does not check read the individual public key from pubnonce and does not check it against the secret key taken as input. +Then it suffices that for each invocation of ''NonceGen' '' with output ''(secnonce, pubnonce)'', +a function ''fsk'' is determined before sending out ''pubnonce'', +where ''fsk'' maps a pair consisting of a list of individual public keys and a message to a secret key, +such that the secret key ''sk'' and the session context ''session_ctx = (_, _, pk1..u, _, _, _, m)'' +provided to the corresponding invocation of ''Sign'(secnonce, sk, session_ctx)'', +adhere to the condition ''fsk(pk1..u, m) = sk''.
+However, this requirement is complex and hard to enforce in implementations. +The algorithms ''NonceGen'' and ''Sign'' specified in this BIP are effectively restricted to constant functions ''fsk(_, _) = sk''. +In other words, their usage ensure that the secret key ''sk'' of the signers is determined entirely when invoking ''NonceGen'', +which is enforced easily by letting ''NonceGen'' take the corresponding individual public key ''pk'' as input and checking ''pk'' against ''IndividualPubKey(sk)'' in ''Sign''.
+Note that the scheme as given in the [https://eprint.iacr.org/2020/1261 MuSig2 paper] does not perform the check in ''Sign''. +However, the security model in the paper does not cover tweaking at all and assumes a single fixed secret key. + +=== Modifications to Nonce Generation === + +Implementers must avoid modifying the ''NonceGen'' algorithm without being fully aware of the implications. +We provide two modifications to ''NonceGen'' that are secure when applied correctly and may be useful in special circumstances, summarized in the following table. + +{| class="wikitable" style="margin:auto" +! !! needs secure randomness !! needs secure counter !! needs to keep state securely !! needs aggregate nonce of all other signers (only possible for one signer) +|- +! NonceGen || ✓ ||   || ✓ ||   +|- +! CounterNonceGen ||   || ✓ || ✓ ||   +|- +! DeterministicSign ||   ||   ||   || ✓ +|} + +First, on systems where obtaining uniformly random values is much harder than maintaining a global atomic counter, it can be beneficial to modify ''NonceGen''. +The resulting algorithm ''CounterNonceGen'' does not draw ''rand' '' uniformly at random but instead sets ''rand' '' to the value of an atomic counter that is incremented whenever it is read. +With this modification, the secret signing key ''sk'' of the signer generating the nonce is '''not''' an optional argument and must be provided to ''NonceGen''. +The security of the resulting scheme then depends on the requirement that reading the counter must never yield the same counter value in two ''NonceGen'' invocations with the same ''sk''. + +Second, if there is a unique signer who is supposed to send the ''pubnonce'' last, it is possible to modify nonce generation for this single signer to not require high-quality randomness. +Such a nonce generation algorithm ''DeterministicSign'' is specified below. +Note that the only optional argument is ''rand'', which can be omitted if randomness is entirely unavailable. +''DeterministicSign'' requires the argument ''aggothernonce'' which should be set to the output of ''NonceAgg'' run on the ''pubnonce'' value of '''all''' other signers (but can be provided by an untrusted party). +Hence, using ''DeterministicSign'' is only possible for the last signer to generate a nonce and makes the signer stateless, similar to the stateless signer described in the [[#nonce-generation|Nonce Generation]] section. + +==== Deterministic and Stateless Signing for a Single Signer ==== + +
+Algorithm ''DeterministicSign(sk, aggothernonce, pk1..u, tweak1..v, is_xonly_t1..v, m, rand)'': +* Inputs: +** The secret signing key ''sk'': a 32-byte array +** The aggregate public nonce ''aggothernonce'' (see [[#modifications-to-nonce-generation|above]]): a 66-byte array +** The number ''u'' of individual public keys with ''0 < u < 2^32'' +** The individual public keys ''pk1..u'': ''u'' 32-byte arrays +** The number ''v'' of tweaks with ''0 ≤ v < 2^32'' +** The tweaks ''tweak1..v'': ''v'' 32-byte arrays +** The tweak methods ''is_xonly_t1..v'': ''v'' booleans +** The message ''m'': a byte array +** The auxiliary randomness ''rand'': a 32-byte array (optional argument) +* If the optional argument ''rand'' is present: +** Let ''sk' '' be the byte-wise xor of ''sk'' and ''hashMuSig/aux(rand)'' +* Else: +** Let ''sk' = sk'' +* Let ''keyagg_ctx0 = KeyAgg(pk1..u)''; fail if that fails +* For ''i = 1 .. v'': +** Let ''keyagg_ctxi = ApplyTweak(keyagg_ctxi-1, tweaki, is_xonly_ti)''; fail if that fails +* Let ''aggpk = GetPubkey(keyagg_ctxv)'' +* Let ''ki = int(hashMuSig/deterministic/nonce(sk' || aggothernonce || aggpk || bytes(8, len(m)) || m || bytes(1, i - 1))) mod n'' for ''i = 1,2'' +* Fail if ''k1 = 0'' or ''k2 = 0'' +* Let ''R⁎,1 = k1⋅G, R⁎,2 = k2⋅G'' +* Let ''pubnonce = cbytes(R⁎,2) || cbytes(R⁎,2)'' +* Let ''d = int(sk)'' +* Fail if ''d = 0'' or ''d ≥ n'' +* Let ''pk = cbytes(d⋅G)'' +* Let ''secnonce = bytes(32, k1) || bytes(32, k2) || pk'' +* Let ''aggnonce = NonceAgg((pubnonce, aggothernonce))''; fail if that fails and blame nonce aggregator for invalid ''aggothernonce''. +* Let ''session_ctx = (aggnonce, u, pk1..u, v, tweak1..v, is_xonly_t1..v, m)'' +* Return ''(pubnonce, Sign(secnonce, sk, session_ctx))'' +
+ +=== Tweaking Definition === + +Two modes of tweaking the aggregate public key are supported. They correspond to the following algorithms: + +
+Algorithm ''ApplyPlainTweak(P, t)'': +* Inputs: +** ''P'': a point +** The tweak ''t'': an integer with ''0 ≤ t < n '' +* Return ''P + t⋅G'' +
+ +
+Algorithm ''ApplyXonlyTweak(P, t)'': +* Return ''with_even_y(P) + t⋅G'' +
+ +=== Negation Of The Secret Key When Signing === + +In order to produce a partial signature for an X-only aggregate public key that is an aggregate of ''u'' individual public keys and tweaked ''v'' times (X-only or plain), the ''[[#Sign negation|Sign]]'' algorithm may need to negate the secret key during the signing process. + + +The following elliptic curve points arise as intermediate steps when creating a signature: +• ''Pi'' as computed in ''KeyAgg'' is the point corresponding to the ''i''-th signer's individual public key. Defining ''di' '' to be the ''i''-th signer's secret key as an integer, i.e., the ''d' '' value as computed in the ''Sign'' algorithm of the ''i''-th signer, we have + ''Pi = di'⋅G ''. +• ''Q0'' is the aggregate of the individual public keys. It is identical to value ''Q'' computed in ''KeyAgg'' and therefore defined as + ''Q0 = a1⋅P1 + a2⋅P2 + ... + au⋅Pu''. +• ''Qi'' is the tweaked aggregate public key after the ''i''-th execution of ''ApplyTweak'' for ''1 ≤ i ≤ v''. It holds that + ''Qi = f(i-1) + ti⋅G'' for ''i = 1, ..., v'' where + ''f(i-1) := with_even_y(Qi-1)'' if ''is_xonly_ti'' and + ''f(i-1) := Qi-1'' otherwise. +• ''with_even_y(Qv)'' is the final result of the key aggregation and tweaking operations. It corresponds to the output of ''GetXonlyPubkey'' applied on the final KeyAgg Context. + + +The signer's goal is to produce a partial signature corresponding to the final result of key aggregation and tweaking, i.e., the X-only public key ''with_even_y(Qv)''. + + +For ''1 ≤ i ≤ v'', we denote the value ''g'' computed in the ''i''-th execution of ''ApplyTweak'' by ''gi-1''. Therefore, ''gi-1'' is ''-1 mod n'' if and only if ''is_xonly_ti'' is true and ''Qi-1'' has an odd Y coordinate. In other words, ''gi-1'' indicates whether ''Qi-1'' needed to be negated to apply an X-only tweak: + ''f(i-1) = gi-1⋅Qi-1'' for ''1 ≤ i ≤ v''. + +Furthermore, the ''Sign'' and ''PartialSigVerify'' algorithms set value ''g'' depending on whether ''Qv'' needed to be negated to produce the (X-only) final output. For consistency, this value ''g'' is referred to as ''gv'' in this section. + ''with_even_y(Qv) = gv⋅Qv''. + + + +So, the (X-only) final public key is + ''with_even_y(Qv) + = gv⋅Qv + = gv⋅(f(v-1) + tv⋅G) + = gv⋅(gv-1⋅(f(v-2) + tv-1⋅G) + tv⋅G) + = gv⋅gv-1⋅f(v-2) + gv⋅(tv + gv-1⋅tv-1)⋅G + = gv⋅gv-1⋅f(v-2) + (sumi=v-1..v ti⋅prodj=i..v gj)⋅G + = gv⋅gv-1⋅...⋅g1⋅f(0) + (sumi=1..v ti⋅prodj=i..v gj)⋅G + = gv⋅...⋅g0⋅Q0 + gv⋅taccv⋅G'' + where ''tacci'' is computed by ''KeyAgg'' and ''ApplyTweak'' as follows: + ''tacc0 = 0 + tacci = ti + gi-1⋅tacci-1 for i=1..v mod n'' + for which it holds that ''gv⋅taccv = sumi=1..v ti⋅prodj=i..v gj''. + + + +''KeyAgg'' and ''ApplyTweak'' compute + ''gacc0 = 1 + gacci = gi-1⋅gacci-1 for i=1..v mod n'' +So we can rewrite above equation for the final public key as + ''with_even_y(Qv) = gv⋅gaccv⋅Q0 + gv⋅taccv⋅G''. + + + +Then we have + ''with_even_y(Qv) - gv⋅taccv⋅G + = gv⋅gaccv⋅Q0 + = gv⋅gaccv⋅(a1⋅P1 + ... + au⋅Pu) + = gv⋅gaccv⋅(a1⋅d1'⋅G + ... + au⋅du'⋅G) + = sumi=1..u(gv⋅gaccv⋅ai⋅di')*G''. + + +Intuitively, ''gacci'' tracks accumulated sign flipping and ''tacci'' tracks the accumulated tweak value after applying the first ''i'' individual tweaks. Additionally, ''gv'' indicates whether ''Qv'' needed to be negated to produce the final X-only result. Thus, signer ''i'' multiplies its secret key ''di' '' with ''gv⋅gaccv'' in the ''[[#Sign negation|Sign]]'' algorithm. + +==== Negation Of The Individual Public Key When Partially Verifying ==== + + +As explained in [[#negation-of-the-secret-key-when-signing|Negation Of The Secret Key When Signing]] the signer uses a possibly negated secret key + ''d = gv⋅gaccv⋅d' mod n'' +when producing a partial signature to ensure that the aggregate signature will correspond to an aggregate public key with even Y coordinate. + + + +The ''[[#SigVerify negation|PartialSigVerifyInternal]]'' algorithm is supposed to check + ''s⋅G = Re + e⋅a⋅d⋅G''. + + + +The verifier doesn't have access to ''d⋅G'' but can construct it using the individual public key ''pk'' as follows: +''d⋅G + = gv⋅gaccv⋅d'⋅G + = gv⋅gaccv⋅cpoint(pk)'' +Note that the aggregate public key and list of tweaks are inputs to partial signature verification, so the verifier can also construct ''gv'' and ''gaccv''. + + +=== Dealing with Infinity in Nonce Aggregation === + +If the nonce aggregator provides ''aggnonce = bytes(33,0) || bytes(33,0)'', either the nonce aggregator is dishonest or there is at least one dishonest signer (except with negligible probability). +If signing aborted in this case, it would be impossible to determine who is dishonest. +Therefore, signing continues so that the culprit is revealed when collecting and verifying partial signatures. + +However, the final nonce ''R'' of a BIP340 Schnorr signature cannot be the point at infinity. +If we would nonetheless allow the final nonce to be the point at infinity, then the scheme would lose the following property: +if ''PartialSigVerify'' succeeds for all partial signatures, then ''PartialSigAgg'' will return a valid Schnorr signature. +Since this is a valuable feature, we modify MuSig2* (which is defined in the appendix of the [https://eprint.iacr.org/2020/1261 MuSig2 paper]) to avoid producing an invalid Schnorr signature while still allowing detection of the dishonest signer: In ''GetSessionValues'', if the final nonce ''R'' would be the point at infinity, set it to the generator instead (an arbitrary choice). + +This modification to ''GetSessionValues'' does not affect the unforgeability of the scheme. +Given a successful adversary against the unforgeability game (EUF-CMA) for the modified scheme, a reduction can win the unforgeability game for the original scheme by simulating the modification towards the adversary: +When the adversary provides ''aggnonce' = bytes(33, 0) || bytes(33, 0)'', the reduction sets ''aggnonce = cbytes_ext(G) || bytes(33, 0)''. +For any other ''aggnonce' '', the reduction sets ''aggnonce = aggnonce' ''. +(The case that the adversary provides an ''aggnonce' ≠ bytes(33, 0) || bytes(33, 0) '' but nevertheless ''R' '' in ''GetSessionValues'' is the point at infinity happens only with negligible probability.) + +=== Choosing the Size of the Nonce === + +The [https://eprint.iacr.org/2020/1261 MuSig2 paper] contains two security proofs that apply to different variants of the scheme. +The first proof relies on the random oracle model (ROM) and applies to a scheme variant where each signer's nonce consists of four elliptic curve points. +The second proof requires a stronger model, namely the combination of the ROM and the algebraic group model (AGM), +and applies to an optimized scheme variant where the signers' nonces consist of only two points. +This proposal uses the latter, optimized scheme variant. +Relying on the stronger model is a legitimate choice for the following reasons: + +First, an approach widely taken is interpreting a Forking Lemma proof in the ROM merely as design justification and ignoring the loss of security due to the Forking Lemma. +If one believes in this approach, then the ROM may not be the optimal model in the first place because some parts of the concrete security bound are arbitrarily ignored. +One may just as well move to the ROM+AGM model, which produces bounds close to the best-known attacks, e.g., for Schnorr signatures. + +Second, as of this writing, there is no instance of a serious cryptographic scheme with a security proof in the AGM that is not secure in practice. +There are, however, insecure toy schemes with AGM security proofs, but those explicitly violate the requirements of the AGM. +[https://eprint.iacr.org/2022/226.pdf Broken AGM proofs of toy schemes] provide group elements to the adversary without declaring them as group element inputs. +In contrast, in MuSig2, all group elements that arise in the scheme are known to the adversary and declared as group element inputs. +A scheme very similar to MuSig2 and with two-point nonces was independently proven secure in the ROM and AGM by [https://eprint.iacr.org/2020/1245 Alper and Burdges]. + +== Backwards Compatibility == + +This document proposes a standard for the MuSig2 multi-signature scheme that is compatible with [https://github.com/bitcoin/bips/blob/master/bip-0340.mediawiki BIP340]. +MuSig2 is ''not'' compatible with ECDSA signatures traditionally used in Bitcoin. + +== Change Log == + +To help implementers understand updates to this document, we attach a version number that resembles ''semantic versioning'' (MAJOR.MINOR.PATCH). +The MAJOR version is incremented if changes to the BIP are introduced that are incompatible with prior versions. +An exception to this rule is MAJOR version zero (0.y.z) which is for development and does not need to be incremented if backwards incompatible changes are introduced. +The MINOR version is incremented whenever the inputs or the output of an algorithm changes in a backward-compatible way or new backward-compatible functionality is added. +The PATCH version is incremented for other changes that are noteworthy (bug fixes, test vectors, important clarifications, etc.). + +* '''1.0.0''' (2023-03-26): +** Number 327 was assigned to this BIP. +* '''1.0.0-rc.4''' (2023-03-02): +** Add expected value of ''pubnonce'' to ''NonceGen'' test vectors. +* '''1.0.0-rc.3''' (2023-02-28): +** Improve ''NonceGen'' test vectors by not using an all-zero hex string as ''rand_'' values. This change addresses potential issues in some implementations that interpret this as a special value indicating uninitialized memory or a broken random number generator and therefore return an error. +** Fix invalid length of a ''pubnonce'' in the ''PartialSigVerify'' test vectors. +** Improve ''KeySort'' test vector. +** Add explicit ''IndividualPubkey'' algorithm. +** Rename KeyGen Context to KeyAgg Context. +* '''1.0.0-rc.2''' (2022-10-28): +** Fix vulnerability that can occur in certain unusual scenarios (see [https://lists.linuxfoundation.org/pipermail/bitcoin-dev/2022-October/021000.html bitcoin-dev mailing list]: Add mandatory ''pk'' argument to ''NonceGen'', append ''pk'' to ''secnonce'' and check in ''Sign'' that the ''pk'' in ''secnonce'' matches. Update test vectors. +** Make sure that signer's key is in list of individual public keys by adding failure case to ''GetSessionKeyAggCoeff'' and add test vectors. +* '''1.0.0-rc.1''' (2022-10-03): Submit draft BIP to the BIPs repository +* '''0.8.6''' (2022-09-15): Clarify that implementations do not need to support every feature and add a test vector for signing with a tweaked key +* '''0.8.5''' (2022-09-05): Rename some functions to improve clarity. +* '''0.8.4''' (2022-09-02): Make naming of nonce variants ''R'' in specifications of the algorithms and reference code easier to read and more consistent. +* '''0.8.3''' (2022-09-01): Overwrite ''secnonce'' in ''sign'' reference implementation to help prevent accidental reuse and add test vector for invalid ''secnonce''. +* '''0.8.2''' (2022-08-30): Fix ''KeySort'' input length and add test vectors +* '''0.8.1''' (2022-08-26): Add ''DeterministicSign'' algorithm +* '''0.8.0''' (2022-08-26): Switch from X-only to plain public key for individual public keys. This requires updating a large portion of the test vectors. +* '''0.7.2''' (2022-08-17): Add ''NonceGen'' and ''Sign/PartialSigVerify'' test vectors for messages longer than 32 bytes. +* '''0.7.1''' (2022-08-10): Extract test vectors into separate JSON file. +* '''0.7.0''' (2022-07-31): Change ''NonceGen'' such that output when message is not present is different from when message is present but has length 0. +* '''0.6.0''' (2022-07-31): Allow variable length messages, change serialization of the message in the ''NonceGen'' hash function, and add test vectors +* '''0.5.2''' (2022-06-26): Fix ''aggpk'' in ''NonceGen'' test vectors. +* '''0.5.1''' (2022-06-22): Rename "ordinary" tweaking to "plain" tweaking. +* '''0.5.0''' (2022-06-21): Separate ApplyTweak from KeyAgg and introduce KeyGen Context. +* '''0.4.0''' (2022-06-20): Allow the output of NonceAgg to be infinity and add test vectors +* '''0.3.2''' (2022-06-02): Add a lot of test vectors and improve handling of invalid contributions in reference code. +* '''0.3.1''' (2022-05-24): Add ''NonceGen'' test vectors +* '''0.3.0''' (2022-05-24): Hash ''i - 1'' instead of ''i'' in ''NonceGen'' +* '''0.2.0''' (2022-05-19): Change order of arguments in ''NonceGen'' hash function +* '''0.1.0''' (2022-05-19): Publication of draft BIP on the bitcoin-dev mailing list + +== Footnotes == + + + +== Acknowledgements == + +We thank Brandon Black, Riccardo Casatta, Lloyd Fournier, Russell O'Connor, and Pieter Wuille for their contributions to this document. diff --git a/bip-0327/gen_vectors_helper.py b/bip-0327/gen_vectors_helper.py new file mode 100644 index 0000000000..a70bb6f30a --- /dev/null +++ b/bip-0327/gen_vectors_helper.py @@ -0,0 +1,184 @@ +from reference import * + +def gen_key_agg_vectors(): + print("key_agg_vectors.json: Intermediate tweaking result is point at infinity") + sk = bytes.fromhex("7FB9E0E687ADA1EEBF7ECFE2F21E73EBDB51A7D450948DFE8D76D7F2D1007671") + pk = individual_pk(sk) + keygen_ctx = key_agg([pk]) + aggpoint, _, _ = keygen_ctx + aggsk = key_agg_coeff([pk], pk)*int_from_bytes(sk) % n + t = n - aggsk + assert point_add(point_mul(G, t), aggpoint) == None + is_xonly = False + tweak = bytes_from_int(t) + assert_raises(ValueError, lambda: apply_tweak(keygen_ctx, tweak, is_xonly), lambda e: True) + print(" pubkey:", pk.hex().upper()) + print(" tweak: ", tweak.hex().upper()) + +def check_sign_verify_vectors(): + with open(os.path.join(sys.path[0], 'vectors', 'sign_verify_vectors.json')) as f: + test_data = json.load(f) + X = fromhex_all(test_data["pubkeys"]) + pnonce = fromhex_all(test_data["pnonces"]) + aggnonces = fromhex_all(test_data["aggnonces"]) + msgs = fromhex_all(test_data["msgs"]) + + valid_test_cases = test_data["valid_test_cases"] + for (i, test_case) in enumerate(valid_test_cases): + pubkeys = [X[i] for i in test_case["key_indices"]] + pubnonces = [pnonce[i] for i in test_case["nonce_indices"]] + aggnonce = aggnonces[test_case["aggnonce_index"]] + assert nonce_agg(pubnonces) == aggnonce + msg = msgs[test_case["msg_index"]] + signer_index = test_case["signer_index"] + expected = bytes.fromhex(test_case["expected"]) + + session_ctx = SessionContext(aggnonce, pubkeys, [], [], msg) + (Q, _, _, _, R, _) = get_session_values(session_ctx) + # Make sure the vectors include tests for both variants of Q and R + if i == 0: + assert has_even_y(Q) and not has_even_y(R) + if i == 1: + assert not has_even_y(Q) and has_even_y(R) + if i == 2: + assert has_even_y(Q) and has_even_y(R) + +def check_tweak_vectors(): + with open(os.path.join(sys.path[0], 'vectors', 'tweak_vectors.json')) as f: + test_data = json.load(f) + + X = fromhex_all(test_data["pubkeys"]) + pnonce = fromhex_all(test_data["pnonces"]) + tweak = fromhex_all(test_data["tweaks"]) + valid_test_cases = test_data["valid_test_cases"] + + for (i, test_case) in enumerate(valid_test_cases): + pubkeys = [X[i] for i in test_case["key_indices"]] + tweaks = [tweak[i] for i in test_case["tweak_indices"]] + is_xonly = test_case["is_xonly"] + + _, gacc, _ = key_agg_and_tweak(pubkeys, tweaks, is_xonly) + # Make sure the vectors include tests for gacc = 1 and -1 + if i == 0: + assert gacc == n - 1 + if i == 1: + assert gacc == 1 + +def sig_agg_vectors(): + print("sig_agg_vectors.json:") + sk = fromhex_all([ + "7FB9E0E687ADA1EEBF7ECFE2F21E73EBDB51A7D450948DFE8D76D7F2D1007671", + "3874D22DE7A7290C49CE7F1DC17D1A8CD8918E1F799055139D57FC0988D04D10", + "D0EA1B84481ED1BCFAA39D6775F97BDC9BF8D7C02FD0C009D6D85BAE5EC7B87A", + "FC2BF9E056B273AF0A8AABB815E541A3552C142AC10D4FE584F01D2CAB84F577"]) + pubkeys = list(map(lambda secret: individual_pk(secret), sk)) + indices32 = [i.to_bytes(32, 'big') for i in range(6)] + secnonces, pnonces = zip(*[nonce_gen_internal(r, None, pubkeys[0], None, None, None) for r in indices32]) + tweaks = fromhex_all([ + "B511DA492182A91B0FFB9A98020D55F260AE86D7ECBD0399C7383D59A5F2AF7C", + "A815FE049EE3C5AAB66310477FBC8BCCCAC2F3395F59F921C364ACD78A2F48DC", + "75448A87274B056468B977BE06EB1E9F657577B7320B0A3376EA51FD420D18A8"]) + msg = bytes.fromhex("599C67EA410D005B9DA90817CF03ED3B1C868E4DA4EDF00A5880B0082C237869") + + psigs = [None] * 9 + + valid_test_cases = [ + { + "aggnonce": None, + "nonce_indices": [0, 1], + "key_indices": [0, 1], + "tweak_indices": [], + "is_xonly": [], + "psig_indices": [0, 1], + }, { + "aggnonce": None, + "nonce_indices": [0, 2], + "key_indices": [0, 2], + "tweak_indices": [], + "is_xonly": [], + "psig_indices": [2, 3], + }, { + "aggnonce": None, + "nonce_indices": [0, 3], + "key_indices": [0, 2], + "tweak_indices": [0], + "is_xonly": [False], + "psig_indices": [4, 5], + }, { + "aggnonce": None, + "nonce_indices": [0, 4], + "key_indices": [0, 3], + "tweak_indices": [0, 1, 2], + "is_xonly": [True, False, True], + "psig_indices": [6, 7], + }, + ] + for (i, test_case) in enumerate(valid_test_cases): + is_xonly = test_case["is_xonly"] + nonce_indices = test_case["nonce_indices"] + key_indices = test_case["key_indices"] + psig_indices = test_case["psig_indices"] + vec_pnonces = [pnonces[i] for i in nonce_indices] + vec_pubkeys = [pubkeys[i] for i in key_indices] + vec_tweaks = [tweaks[i] for i in test_case["tweak_indices"]] + + aggnonce = nonce_agg(vec_pnonces) + test_case["aggnonce"] = aggnonce.hex().upper() + session_ctx = SessionContext(aggnonce, vec_pubkeys, vec_tweaks, is_xonly, msg) + + for j in range(len(key_indices)): + # WARNING: An actual implementation should _not_ copy the secnonce. + # Reusing the secnonce, as we do here for testing purposes, can leak the + # secret key. + secnonce_tmp = bytearray(secnonces[nonce_indices[j]][:64] + pubkeys[key_indices[j]]) + psigs[psig_indices[j]] = sign(secnonce_tmp, sk[key_indices[j]], session_ctx) + sig = partial_sig_agg([psigs[i] for i in psig_indices], session_ctx) + keygen_ctx = key_agg_and_tweak(vec_pubkeys, vec_tweaks, is_xonly) + # To maximize coverage of the sig_agg algorithm, we want one public key + # point with an even and one with an odd Y coordinate. + if i == 0: + assert(has_even_y(keygen_ctx[0])) + if i == 1: + assert(not has_even_y(keygen_ctx[0])) + aggpk = get_xonly_pk(keygen_ctx) + assert schnorr_verify(msg, aggpk, sig) + test_case["expected"] = sig.hex().upper() + + error_test_case = { + "aggnonce": None, + "nonce_indices": [0, 4], + "key_indices": [0, 3], + "tweak_indices": [0, 1, 2], + "is_xonly": [True, False, True], + "psig_indices": [7, 8], + "error": { + "type": "invalid_contribution", + "signer": 1 + }, + "comment": "Partial signature is invalid because it exceeds group size" + } + + psigs[8] = bytes.fromhex("FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEBAAEDCE6AF48A03BBFD25E8CD0364141") + + vec_pnonces = [pnonces[i] for i in error_test_case["nonce_indices"]] + aggnonce = nonce_agg(vec_pnonces) + error_test_case["aggnonce"] = aggnonce.hex().upper() + + def tohex_all(l): + return list(map(lambda e: e.hex().upper(), l)) + + print(json.dumps({ + "pubkeys": tohex_all(pubkeys), + "pnonces": tohex_all(pnonces), + "tweaks": tohex_all(tweaks), + "psigs": tohex_all(psigs), + "msg": msg.hex().upper(), + "valid_test_cases": valid_test_cases, + "error_test_cases": [error_test_case] + }, indent=4)) + +gen_key_agg_vectors() +check_sign_verify_vectors() +check_tweak_vectors() +print() +sig_agg_vectors() diff --git a/bip-0327/reference.py b/bip-0327/reference.py new file mode 100644 index 0000000000..edf6e76b0f --- /dev/null +++ b/bip-0327/reference.py @@ -0,0 +1,880 @@ +# BIP327 reference implementation +# +# WARNING: This implementation is for demonstration purposes only and _not_ to +# be used in production environments. The code is vulnerable to timing attacks, +# for example. + +from typing import Any, List, Optional, Tuple, NewType, NamedTuple +import hashlib +import secrets +import time + +# +# The following helper functions were copied from the BIP-340 reference implementation: +# https://github.com/bitcoin/bips/blob/master/bip-0340/reference.py +# + +p = 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEFFFFFC2F +n = 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEBAAEDCE6AF48A03BBFD25E8CD0364141 + +# Points are tuples of X and Y coordinates and the point at infinity is +# represented by the None keyword. +G = (0x79BE667EF9DCBBAC55A06295CE870B07029BFCDB2DCE28D959F2815B16F81798, 0x483ADA7726A3C4655DA4FBFC0E1108A8FD17B448A68554199C47D08FFB10D4B8) + +Point = Tuple[int, int] + +# This implementation can be sped up by storing the midstate after hashing +# tag_hash instead of rehashing it all the time. +def tagged_hash(tag: str, msg: bytes) -> bytes: + tag_hash = hashlib.sha256(tag.encode()).digest() + return hashlib.sha256(tag_hash + tag_hash + msg).digest() + +def is_infinite(P: Optional[Point]) -> bool: + return P is None + +def x(P: Point) -> int: + assert not is_infinite(P) + return P[0] + +def y(P: Point) -> int: + assert not is_infinite(P) + return P[1] + +def point_add(P1: Optional[Point], P2: Optional[Point]) -> Optional[Point]: + if P1 is None: + return P2 + if P2 is None: + return P1 + if (x(P1) == x(P2)) and (y(P1) != y(P2)): + return None + if P1 == P2: + lam = (3 * x(P1) * x(P1) * pow(2 * y(P1), p - 2, p)) % p + else: + lam = ((y(P2) - y(P1)) * pow(x(P2) - x(P1), p - 2, p)) % p + x3 = (lam * lam - x(P1) - x(P2)) % p + return (x3, (lam * (x(P1) - x3) - y(P1)) % p) + +def point_mul(P: Optional[Point], n: int) -> Optional[Point]: + R = None + for i in range(256): + if (n >> i) & 1: + R = point_add(R, P) + P = point_add(P, P) + return R + +def bytes_from_int(x: int) -> bytes: + return x.to_bytes(32, byteorder="big") + +def lift_x(b: bytes) -> Optional[Point]: + x = int_from_bytes(b) + if x >= p: + return None + y_sq = (pow(x, 3, p) + 7) % p + y = pow(y_sq, (p + 1) // 4, p) + if pow(y, 2, p) != y_sq: + return None + return (x, y if y & 1 == 0 else p-y) + +def int_from_bytes(b: bytes) -> int: + return int.from_bytes(b, byteorder="big") + +def has_even_y(P: Point) -> bool: + assert not is_infinite(P) + return y(P) % 2 == 0 + +def schnorr_verify(msg: bytes, pubkey: bytes, sig: bytes) -> bool: + if len(msg) != 32: + raise ValueError('The message must be a 32-byte array.') + if len(pubkey) != 32: + raise ValueError('The public key must be a 32-byte array.') + if len(sig) != 64: + raise ValueError('The signature must be a 64-byte array.') + P = lift_x(pubkey) + r = int_from_bytes(sig[0:32]) + s = int_from_bytes(sig[32:64]) + if (P is None) or (r >= p) or (s >= n): + return False + e = int_from_bytes(tagged_hash("BIP0340/challenge", sig[0:32] + pubkey + msg)) % n + R = point_add(point_mul(G, s), point_mul(P, n - e)) + if (R is None) or (not has_even_y(R)) or (x(R) != r): + return False + return True + +# +# End of helper functions copied from BIP-340 reference implementation. +# + +PlainPk = NewType('PlainPk', bytes) +XonlyPk = NewType('XonlyPk', bytes) + +# There are two types of exceptions that can be raised by this implementation: +# - ValueError for indicating that an input doesn't conform to some function +# precondition (e.g. an input array is the wrong length, a serialized +# representation doesn't have the correct format). +# - InvalidContributionError for indicating that a signer (or the +# aggregator) is misbehaving in the protocol. +# +# Assertions are used to (1) satisfy the type-checking system, and (2) check for +# inconvenient events that can't happen except with negligible probability (e.g. +# output of a hash function is 0) and can't be manually triggered by any +# signer. + +# This exception is raised if a party (signer or nonce aggregator) sends invalid +# values. Actual implementations should not crash when receiving invalid +# contributions. Instead, they should hold the offending party accountable. +class InvalidContributionError(Exception): + def __init__(self, signer, contrib): + self.signer = signer + # contrib is one of "pubkey", "pubnonce", "aggnonce", or "psig". + self.contrib = contrib + +infinity = None + +def xbytes(P: Point) -> bytes: + return bytes_from_int(x(P)) + +def cbytes(P: Point) -> bytes: + a = b'\x02' if has_even_y(P) else b'\x03' + return a + xbytes(P) + +def cbytes_ext(P: Optional[Point]) -> bytes: + if is_infinite(P): + return (0).to_bytes(33, byteorder='big') + assert P is not None + return cbytes(P) + +def point_negate(P: Optional[Point]) -> Optional[Point]: + if P is None: + return P + return (x(P), p - y(P)) + +def cpoint(x: bytes) -> Point: + if len(x) != 33: + raise ValueError('x is not a valid compressed point.') + P = lift_x(x[1:33]) + if P is None: + raise ValueError('x is not a valid compressed point.') + if x[0] == 2: + return P + elif x[0] == 3: + P = point_negate(P) + assert P is not None + return P + else: + raise ValueError('x is not a valid compressed point.') + +def cpoint_ext(x: bytes) -> Optional[Point]: + if x == (0).to_bytes(33, 'big'): + return None + else: + return cpoint(x) + +# Return the plain public key corresponding to a given secret key +def individual_pk(seckey: bytes) -> PlainPk: + d0 = int_from_bytes(seckey) + if not (1 <= d0 <= n - 1): + raise ValueError('The secret key must be an integer in the range 1..n-1.') + P = point_mul(G, d0) + assert P is not None + return PlainPk(cbytes(P)) + +def key_sort(pubkeys: List[PlainPk]) -> List[PlainPk]: + pubkeys.sort() + return pubkeys + +KeyAggContext = NamedTuple('KeyAggContext', [('Q', Point), + ('gacc', int), + ('tacc', int)]) + +def get_xonly_pk(keyagg_ctx: KeyAggContext) -> XonlyPk: + Q, _, _ = keyagg_ctx + return XonlyPk(xbytes(Q)) + +def key_agg(pubkeys: List[PlainPk]) -> KeyAggContext: + pk2 = get_second_key(pubkeys) + u = len(pubkeys) + Q = infinity + for i in range(u): + try: + P_i = cpoint(pubkeys[i]) + except ValueError: + raise InvalidContributionError(i, "pubkey") + a_i = key_agg_coeff_internal(pubkeys, pubkeys[i], pk2) + Q = point_add(Q, point_mul(P_i, a_i)) + # Q is not the point at infinity except with negligible probability. + assert(Q is not None) + gacc = 1 + tacc = 0 + return KeyAggContext(Q, gacc, tacc) + +def hash_keys(pubkeys: List[PlainPk]) -> bytes: + return tagged_hash('KeyAgg list', b''.join(pubkeys)) + +def get_second_key(pubkeys: List[PlainPk]) -> PlainPk: + u = len(pubkeys) + for j in range(1, u): + if pubkeys[j] != pubkeys[0]: + return pubkeys[j] + return PlainPk(b'\x00'*33) + +def key_agg_coeff(pubkeys: List[PlainPk], pk_: PlainPk) -> int: + pk2 = get_second_key(pubkeys) + return key_agg_coeff_internal(pubkeys, pk_, pk2) + +def key_agg_coeff_internal(pubkeys: List[PlainPk], pk_: PlainPk, pk2: PlainPk) -> int: + L = hash_keys(pubkeys) + if pk_ == pk2: + return 1 + return int_from_bytes(tagged_hash('KeyAgg coefficient', L + pk_)) % n + +def apply_tweak(keyagg_ctx: KeyAggContext, tweak: bytes, is_xonly: bool) -> KeyAggContext: + if len(tweak) != 32: + raise ValueError('The tweak must be a 32-byte array.') + Q, gacc, tacc = keyagg_ctx + if is_xonly and not has_even_y(Q): + g = n - 1 + else: + g = 1 + t = int_from_bytes(tweak) + if t >= n: + raise ValueError('The tweak must be less than n.') + Q_ = point_add(point_mul(Q, g), point_mul(G, t)) + if Q_ is None: + raise ValueError('The result of tweaking cannot be infinity.') + gacc_ = g * gacc % n + tacc_ = (t + g * tacc) % n + return KeyAggContext(Q_, gacc_, tacc_) + +def bytes_xor(a: bytes, b: bytes) -> bytes: + return bytes(x ^ y for x, y in zip(a, b)) + +def nonce_hash(rand: bytes, pk: PlainPk, aggpk: XonlyPk, i: int, msg_prefixed: bytes, extra_in: bytes) -> int: + buf = b'' + buf += rand + buf += len(pk).to_bytes(1, 'big') + buf += pk + buf += len(aggpk).to_bytes(1, 'big') + buf += aggpk + buf += msg_prefixed + buf += len(extra_in).to_bytes(4, 'big') + buf += extra_in + buf += i.to_bytes(1, 'big') + return int_from_bytes(tagged_hash('MuSig/nonce', buf)) + +def nonce_gen_internal(rand_: bytes, sk: Optional[bytes], pk: PlainPk, aggpk: Optional[XonlyPk], msg: Optional[bytes], extra_in: Optional[bytes]) -> Tuple[bytearray, bytes]: + if sk is not None: + rand = bytes_xor(sk, tagged_hash('MuSig/aux', rand_)) + else: + rand = rand_ + if aggpk is None: + aggpk = XonlyPk(b'') + if msg is None: + msg_prefixed = b'\x00' + else: + msg_prefixed = b'\x01' + msg_prefixed += len(msg).to_bytes(8, 'big') + msg_prefixed += msg + if extra_in is None: + extra_in = b'' + k_1 = nonce_hash(rand, pk, aggpk, 0, msg_prefixed, extra_in) % n + k_2 = nonce_hash(rand, pk, aggpk, 1, msg_prefixed, extra_in) % n + # k_1 == 0 or k_2 == 0 cannot occur except with negligible probability. + assert k_1 != 0 + assert k_2 != 0 + R_s1 = point_mul(G, k_1) + R_s2 = point_mul(G, k_2) + assert R_s1 is not None + assert R_s2 is not None + pubnonce = cbytes(R_s1) + cbytes(R_s2) + secnonce = bytearray(bytes_from_int(k_1) + bytes_from_int(k_2) + pk) + return secnonce, pubnonce + +def nonce_gen(sk: Optional[bytes], pk: PlainPk, aggpk: Optional[XonlyPk], msg: Optional[bytes], extra_in: Optional[bytes]) -> Tuple[bytearray, bytes]: + if sk is not None and len(sk) != 32: + raise ValueError('The optional byte array sk must have length 32.') + if aggpk is not None and len(aggpk) != 32: + raise ValueError('The optional byte array aggpk must have length 32.') + rand_ = secrets.token_bytes(32) + return nonce_gen_internal(rand_, sk, pk, aggpk, msg, extra_in) + +def nonce_agg(pubnonces: List[bytes]) -> bytes: + u = len(pubnonces) + aggnonce = b'' + for j in (1, 2): + R_j = infinity + for i in range(u): + try: + R_ij = cpoint(pubnonces[i][(j-1)*33:j*33]) + except ValueError: + raise InvalidContributionError(i, "pubnonce") + R_j = point_add(R_j, R_ij) + aggnonce += cbytes_ext(R_j) + return aggnonce + +SessionContext = NamedTuple('SessionContext', [('aggnonce', bytes), + ('pubkeys', List[PlainPk]), + ('tweaks', List[bytes]), + ('is_xonly', List[bool]), + ('msg', bytes)]) + +def key_agg_and_tweak(pubkeys: List[PlainPk], tweaks: List[bytes], is_xonly: List[bool]): + if len(tweaks) != len(is_xonly): + raise ValueError('The `tweaks` and `is_xonly` arrays must have the same length.') + keyagg_ctx = key_agg(pubkeys) + v = len(tweaks) + for i in range(v): + keyagg_ctx = apply_tweak(keyagg_ctx, tweaks[i], is_xonly[i]) + return keyagg_ctx + +def get_session_values(session_ctx: SessionContext) -> Tuple[Point, int, int, int, Point, int]: + (aggnonce, pubkeys, tweaks, is_xonly, msg) = session_ctx + Q, gacc, tacc = key_agg_and_tweak(pubkeys, tweaks, is_xonly) + b = int_from_bytes(tagged_hash('MuSig/noncecoef', aggnonce + xbytes(Q) + msg)) % n + try: + R_1 = cpoint_ext(aggnonce[0:33]) + R_2 = cpoint_ext(aggnonce[33:66]) + except ValueError: + # Nonce aggregator sent invalid nonces + raise InvalidContributionError(None, "aggnonce") + R_ = point_add(R_1, point_mul(R_2, b)) + R = R_ if not is_infinite(R_) else G + assert R is not None + e = int_from_bytes(tagged_hash('BIP0340/challenge', xbytes(R) + xbytes(Q) + msg)) % n + return (Q, gacc, tacc, b, R, e) + +def get_session_key_agg_coeff(session_ctx: SessionContext, P: Point) -> int: + (_, pubkeys, _, _, _) = session_ctx + pk = PlainPk(cbytes(P)) + if pk not in pubkeys: + raise ValueError('The signer\'s pubkey must be included in the list of pubkeys.') + return key_agg_coeff(pubkeys, pk) + +def sign(secnonce: bytearray, sk: bytes, session_ctx: SessionContext) -> bytes: + (Q, gacc, _, b, R, e) = get_session_values(session_ctx) + k_1_ = int_from_bytes(secnonce[0:32]) + k_2_ = int_from_bytes(secnonce[32:64]) + # Overwrite the secnonce argument with zeros such that subsequent calls of + # sign with the same secnonce raise a ValueError. + secnonce[:64] = bytearray(b'\x00'*64) + if not 0 < k_1_ < n: + raise ValueError('first secnonce value is out of range.') + if not 0 < k_2_ < n: + raise ValueError('second secnonce value is out of range.') + k_1 = k_1_ if has_even_y(R) else n - k_1_ + k_2 = k_2_ if has_even_y(R) else n - k_2_ + d_ = int_from_bytes(sk) + if not 0 < d_ < n: + raise ValueError('secret key value is out of range.') + P = point_mul(G, d_) + assert P is not None + pk = cbytes(P) + if not pk == secnonce[64:97]: + raise ValueError('Public key does not match nonce_gen argument') + a = get_session_key_agg_coeff(session_ctx, P) + g = 1 if has_even_y(Q) else n - 1 + d = g * gacc * d_ % n + s = (k_1 + b * k_2 + e * a * d) % n + psig = bytes_from_int(s) + R_s1 = point_mul(G, k_1_) + R_s2 = point_mul(G, k_2_) + assert R_s1 is not None + assert R_s2 is not None + pubnonce = cbytes(R_s1) + cbytes(R_s2) + # Optional correctness check. The result of signing should pass signature verification. + assert partial_sig_verify_internal(psig, pubnonce, pk, session_ctx) + return psig + +def det_nonce_hash(sk_: bytes, aggothernonce: bytes, aggpk: bytes, msg: bytes, i: int) -> int: + buf = b'' + buf += sk_ + buf += aggothernonce + buf += aggpk + buf += len(msg).to_bytes(8, 'big') + buf += msg + buf += i.to_bytes(1, 'big') + return int_from_bytes(tagged_hash('MuSig/deterministic/nonce', buf)) + +def deterministic_sign(sk: bytes, aggothernonce: bytes, pubkeys: List[PlainPk], tweaks: List[bytes], is_xonly: List[bool], msg: bytes, rand: Optional[bytes]) -> Tuple[bytes, bytes]: + if rand is not None: + sk_ = bytes_xor(sk, tagged_hash('MuSig/aux', rand)) + else: + sk_ = sk + aggpk = get_xonly_pk(key_agg_and_tweak(pubkeys, tweaks, is_xonly)) + + k_1 = det_nonce_hash(sk_, aggothernonce, aggpk, msg, 0) % n + k_2 = det_nonce_hash(sk_, aggothernonce, aggpk, msg, 1) % n + # k_1 == 0 or k_2 == 0 cannot occur except with negligible probability. + assert k_1 != 0 + assert k_2 != 0 + + R_s1 = point_mul(G, k_1) + R_s2 = point_mul(G, k_2) + assert R_s1 is not None + assert R_s2 is not None + pubnonce = cbytes(R_s1) + cbytes(R_s2) + secnonce = bytearray(bytes_from_int(k_1) + bytes_from_int(k_2) + individual_pk(sk)) + try: + aggnonce = nonce_agg([pubnonce, aggothernonce]) + except Exception: + raise InvalidContributionError(None, "aggothernonce") + session_ctx = SessionContext(aggnonce, pubkeys, tweaks, is_xonly, msg) + psig = sign(secnonce, sk, session_ctx) + return (pubnonce, psig) + +def partial_sig_verify(psig: bytes, pubnonces: List[bytes], pubkeys: List[PlainPk], tweaks: List[bytes], is_xonly: List[bool], msg: bytes, i: int) -> bool: + if len(pubnonces) != len(pubkeys): + raise ValueError('The `pubnonces` and `pubkeys` arrays must have the same length.') + if len(tweaks) != len(is_xonly): + raise ValueError('The `tweaks` and `is_xonly` arrays must have the same length.') + aggnonce = nonce_agg(pubnonces) + session_ctx = SessionContext(aggnonce, pubkeys, tweaks, is_xonly, msg) + return partial_sig_verify_internal(psig, pubnonces[i], pubkeys[i], session_ctx) + +def partial_sig_verify_internal(psig: bytes, pubnonce: bytes, pk: bytes, session_ctx: SessionContext) -> bool: + (Q, gacc, _, b, R, e) = get_session_values(session_ctx) + s = int_from_bytes(psig) + if s >= n: + return False + R_s1 = cpoint(pubnonce[0:33]) + R_s2 = cpoint(pubnonce[33:66]) + Re_s_ = point_add(R_s1, point_mul(R_s2, b)) + Re_s = Re_s_ if has_even_y(R) else point_negate(Re_s_) + P = cpoint(pk) + if P is None: + return False + a = get_session_key_agg_coeff(session_ctx, P) + g = 1 if has_even_y(Q) else n - 1 + g_ = g * gacc % n + return point_mul(G, s) == point_add(Re_s, point_mul(P, e * a * g_ % n)) + +def partial_sig_agg(psigs: List[bytes], session_ctx: SessionContext) -> bytes: + (Q, _, tacc, _, R, e) = get_session_values(session_ctx) + s = 0 + u = len(psigs) + for i in range(u): + s_i = int_from_bytes(psigs[i]) + if s_i >= n: + raise InvalidContributionError(i, "psig") + s = (s + s_i) % n + g = 1 if has_even_y(Q) else n - 1 + s = (s + e * g * tacc) % n + return xbytes(R) + bytes_from_int(s) +# +# The following code is only used for testing. +# + +import json +import os +import sys + +def fromhex_all(l): + return [bytes.fromhex(l_i) for l_i in l] + +# Check that calling `try_fn` raises a `exception`. If `exception` is raised, +# examine it with `except_fn`. +def assert_raises(exception, try_fn, except_fn): + raised = False + try: + try_fn() + except exception as e: + raised = True + assert(except_fn(e)) + except BaseException: + raise AssertionError("Wrong exception raised in a test.") + if not raised: + raise AssertionError("Exception was _not_ raised in a test where it was required.") + +def get_error_details(test_case): + error = test_case["error"] + if error["type"] == "invalid_contribution": + exception = InvalidContributionError + if "contrib" in error: + except_fn = lambda e: e.signer == error["signer"] and e.contrib == error["contrib"] + else: + except_fn = lambda e: e.signer == error["signer"] + elif error["type"] == "value": + exception = ValueError + except_fn = lambda e: str(e) == error["message"] + else: + raise RuntimeError(f"Invalid error type: {error['type']}") + return exception, except_fn + +def test_key_sort_vectors() -> None: + with open(os.path.join(sys.path[0], 'vectors', 'key_sort_vectors.json')) as f: + test_data = json.load(f) + + X = fromhex_all(test_data["pubkeys"]) + X_sorted = fromhex_all(test_data["sorted_pubkeys"]) + + assert key_sort(X) == X_sorted + +def test_key_agg_vectors() -> None: + with open(os.path.join(sys.path[0], 'vectors', 'key_agg_vectors.json')) as f: + test_data = json.load(f) + + X = fromhex_all(test_data["pubkeys"]) + T = fromhex_all(test_data["tweaks"]) + valid_test_cases = test_data["valid_test_cases"] + error_test_cases = test_data["error_test_cases"] + + for test_case in valid_test_cases: + pubkeys = [X[i] for i in test_case["key_indices"]] + expected = bytes.fromhex(test_case["expected"]) + + assert get_xonly_pk(key_agg(pubkeys)) == expected + + for i, test_case in enumerate(error_test_cases): + exception, except_fn = get_error_details(test_case) + + pubkeys = [X[i] for i in test_case["key_indices"]] + tweaks = [T[i] for i in test_case["tweak_indices"]] + is_xonly = test_case["is_xonly"] + + assert_raises(exception, lambda: key_agg_and_tweak(pubkeys, tweaks, is_xonly), except_fn) + +def test_nonce_gen_vectors() -> None: + with open(os.path.join(sys.path[0], 'vectors', 'nonce_gen_vectors.json')) as f: + test_data = json.load(f) + + for test_case in test_data["test_cases"]: + def get_value(key) -> bytes: + return bytes.fromhex(test_case[key]) + + def get_value_maybe(key) -> Optional[bytes]: + if test_case[key] is not None: + return get_value(key) + else: + return None + + rand_ = get_value("rand_") + sk = get_value_maybe("sk") + pk = PlainPk(get_value("pk")) + aggpk = get_value_maybe("aggpk") + if aggpk is not None: + aggpk = XonlyPk(aggpk) + msg = get_value_maybe("msg") + extra_in = get_value_maybe("extra_in") + expected_secnonce = get_value("expected_secnonce") + expected_pubnonce = get_value("expected_pubnonce") + + assert nonce_gen_internal(rand_, sk, pk, aggpk, msg, extra_in) == (expected_secnonce, expected_pubnonce) + +def test_nonce_agg_vectors() -> None: + with open(os.path.join(sys.path[0], 'vectors', 'nonce_agg_vectors.json')) as f: + test_data = json.load(f) + + pnonce = fromhex_all(test_data["pnonces"]) + valid_test_cases = test_data["valid_test_cases"] + error_test_cases = test_data["error_test_cases"] + + for test_case in valid_test_cases: + pubnonces = [pnonce[i] for i in test_case["pnonce_indices"]] + expected = bytes.fromhex(test_case["expected"]) + assert nonce_agg(pubnonces) == expected + + for i, test_case in enumerate(error_test_cases): + exception, except_fn = get_error_details(test_case) + pubnonces = [pnonce[i] for i in test_case["pnonce_indices"]] + assert_raises(exception, lambda: nonce_agg(pubnonces), except_fn) + +def test_sign_verify_vectors() -> None: + with open(os.path.join(sys.path[0], 'vectors', 'sign_verify_vectors.json')) as f: + test_data = json.load(f) + + sk = bytes.fromhex(test_data["sk"]) + X = fromhex_all(test_data["pubkeys"]) + # The public key corresponding to sk is at index 0 + assert X[0] == individual_pk(sk) + + secnonces = fromhex_all(test_data["secnonces"]) + pnonce = fromhex_all(test_data["pnonces"]) + # The public nonce corresponding to secnonces[0] is at index 0 + k_1 = int_from_bytes(secnonces[0][0:32]) + k_2 = int_from_bytes(secnonces[0][32:64]) + R_s1 = point_mul(G, k_1) + R_s2 = point_mul(G, k_2) + assert R_s1 is not None and R_s2 is not None + assert pnonce[0] == cbytes(R_s1) + cbytes(R_s2) + + aggnonces = fromhex_all(test_data["aggnonces"]) + # The aggregate of the first three elements of pnonce is at index 0 + assert(aggnonces[0] == nonce_agg([pnonce[0], pnonce[1], pnonce[2]])) + + msgs = fromhex_all(test_data["msgs"]) + + valid_test_cases = test_data["valid_test_cases"] + sign_error_test_cases = test_data["sign_error_test_cases"] + verify_fail_test_cases = test_data["verify_fail_test_cases"] + verify_error_test_cases = test_data["verify_error_test_cases"] + + for test_case in valid_test_cases: + pubkeys = [X[i] for i in test_case["key_indices"]] + pubnonces = [pnonce[i] for i in test_case["nonce_indices"]] + aggnonce = aggnonces[test_case["aggnonce_index"]] + # Make sure that pubnonces and aggnonce in the test vector are + # consistent + assert nonce_agg(pubnonces) == aggnonce + msg = msgs[test_case["msg_index"]] + signer_index = test_case["signer_index"] + expected = bytes.fromhex(test_case["expected"]) + + session_ctx = SessionContext(aggnonce, pubkeys, [], [], msg) + # WARNING: An actual implementation should _not_ copy the secnonce. + # Reusing the secnonce, as we do here for testing purposes, can leak the + # secret key. + secnonce_tmp = bytearray(secnonces[0]) + assert sign(secnonce_tmp, sk, session_ctx) == expected + assert partial_sig_verify(expected, pubnonces, pubkeys, [], [], msg, signer_index) + + for i, test_case in enumerate(sign_error_test_cases): + exception, except_fn = get_error_details(test_case) + + pubkeys = [X[i] for i in test_case["key_indices"]] + aggnonce = aggnonces[test_case["aggnonce_index"]] + msg = msgs[test_case["msg_index"]] + secnonce = bytearray(secnonces[test_case["secnonce_index"]]) + + session_ctx = SessionContext(aggnonce, pubkeys, [], [], msg) + assert_raises(exception, lambda: sign(secnonce, sk, session_ctx), except_fn) + + for test_case in verify_fail_test_cases: + sig = bytes.fromhex(test_case["sig"]) + pubkeys = [X[i] for i in test_case["key_indices"]] + pubnonces = [pnonce[i] for i in test_case["nonce_indices"]] + msg = msgs[test_case["msg_index"]] + signer_index = test_case["signer_index"] + + assert not partial_sig_verify(sig, pubnonces, pubkeys, [], [], msg, signer_index) + + for i, test_case in enumerate(verify_error_test_cases): + exception, except_fn = get_error_details(test_case) + + sig = bytes.fromhex(test_case["sig"]) + pubkeys = [X[i] for i in test_case["key_indices"]] + pubnonces = [pnonce[i] for i in test_case["nonce_indices"]] + msg = msgs[test_case["msg_index"]] + signer_index = test_case["signer_index"] + + assert_raises(exception, lambda: partial_sig_verify(sig, pubnonces, pubkeys, [], [], msg, signer_index), except_fn) + +def test_tweak_vectors() -> None: + with open(os.path.join(sys.path[0], 'vectors', 'tweak_vectors.json')) as f: + test_data = json.load(f) + + sk = bytes.fromhex(test_data["sk"]) + X = fromhex_all(test_data["pubkeys"]) + # The public key corresponding to sk is at index 0 + assert X[0] == individual_pk(sk) + + secnonce = bytearray(bytes.fromhex(test_data["secnonce"])) + pnonce = fromhex_all(test_data["pnonces"]) + # The public nonce corresponding to secnonce is at index 0 + k_1 = int_from_bytes(secnonce[0:32]) + k_2 = int_from_bytes(secnonce[32:64]) + R_s1 = point_mul(G, k_1) + R_s2 = point_mul(G, k_2) + assert R_s1 is not None and R_s2 is not None + assert pnonce[0] == cbytes(R_s1) + cbytes(R_s2) + + aggnonce = bytes.fromhex(test_data["aggnonce"]) + # The aggnonce is the aggregate of the first three elements of pnonce + assert(aggnonce == nonce_agg([pnonce[0], pnonce[1], pnonce[2]])) + + tweak = fromhex_all(test_data["tweaks"]) + msg = bytes.fromhex(test_data["msg"]) + + valid_test_cases = test_data["valid_test_cases"] + error_test_cases = test_data["error_test_cases"] + + for test_case in valid_test_cases: + pubkeys = [X[i] for i in test_case["key_indices"]] + pubnonces = [pnonce[i] for i in test_case["nonce_indices"]] + tweaks = [tweak[i] for i in test_case["tweak_indices"]] + is_xonly = test_case["is_xonly"] + signer_index = test_case["signer_index"] + expected = bytes.fromhex(test_case["expected"]) + + session_ctx = SessionContext(aggnonce, pubkeys, tweaks, is_xonly, msg) + secnonce_tmp = bytearray(secnonce) + # WARNING: An actual implementation should _not_ copy the secnonce. + # Reusing the secnonce, as we do here for testing purposes, can leak the + # secret key. + assert sign(secnonce_tmp, sk, session_ctx) == expected + assert partial_sig_verify(expected, pubnonces, pubkeys, tweaks, is_xonly, msg, signer_index) + + for i, test_case in enumerate(error_test_cases): + exception, except_fn = get_error_details(test_case) + + pubkeys = [X[i] for i in test_case["key_indices"]] + pubnonces = [pnonce[i] for i in test_case["nonce_indices"]] + tweaks = [tweak[i] for i in test_case["tweak_indices"]] + is_xonly = test_case["is_xonly"] + signer_index = test_case["signer_index"] + + session_ctx = SessionContext(aggnonce, pubkeys, tweaks, is_xonly, msg) + assert_raises(exception, lambda: sign(secnonce, sk, session_ctx), except_fn) + +def test_det_sign_vectors() -> None: + with open(os.path.join(sys.path[0], 'vectors', 'det_sign_vectors.json')) as f: + test_data = json.load(f) + + sk = bytes.fromhex(test_data["sk"]) + X = fromhex_all(test_data["pubkeys"]) + # The public key corresponding to sk is at index 0 + assert X[0] == individual_pk(sk) + + msgs = fromhex_all(test_data["msgs"]) + + valid_test_cases = test_data["valid_test_cases"] + error_test_cases = test_data["error_test_cases"] + + for test_case in valid_test_cases: + pubkeys = [X[i] for i in test_case["key_indices"]] + aggothernonce = bytes.fromhex(test_case["aggothernonce"]) + tweaks = fromhex_all(test_case["tweaks"]) + is_xonly = test_case["is_xonly"] + msg = msgs[test_case["msg_index"]] + signer_index = test_case["signer_index"] + rand = bytes.fromhex(test_case["rand"]) if test_case["rand"] is not None else None + expected = fromhex_all(test_case["expected"]) + + pubnonce, psig = deterministic_sign(sk, aggothernonce, pubkeys, tweaks, is_xonly, msg, rand) + assert pubnonce == expected[0] + assert psig == expected[1] + + pubnonces = [aggothernonce, pubnonce] + aggnonce = nonce_agg(pubnonces) + session_ctx = SessionContext(aggnonce, pubkeys, tweaks, is_xonly, msg) + assert partial_sig_verify_internal(psig, pubnonce, pubkeys[signer_index], session_ctx) + + for i, test_case in enumerate(error_test_cases): + exception, except_fn = get_error_details(test_case) + + pubkeys = [X[i] for i in test_case["key_indices"]] + aggothernonce = bytes.fromhex(test_case["aggothernonce"]) + tweaks = fromhex_all(test_case["tweaks"]) + is_xonly = test_case["is_xonly"] + msg = msgs[test_case["msg_index"]] + signer_index = test_case["signer_index"] + rand = bytes.fromhex(test_case["rand"]) if test_case["rand"] is not None else None + + try_fn = lambda: deterministic_sign(sk, aggothernonce, pubkeys, tweaks, is_xonly, msg, rand) + assert_raises(exception, try_fn, except_fn) + +def test_sig_agg_vectors() -> None: + with open(os.path.join(sys.path[0], 'vectors', 'sig_agg_vectors.json')) as f: + test_data = json.load(f) + + X = fromhex_all(test_data["pubkeys"]) + + # These nonces are only required if the tested API takes the individual + # nonces and not the aggregate nonce. + pnonce = fromhex_all(test_data["pnonces"]) + + tweak = fromhex_all(test_data["tweaks"]) + psig = fromhex_all(test_data["psigs"]) + + msg = bytes.fromhex(test_data["msg"]) + + valid_test_cases = test_data["valid_test_cases"] + error_test_cases = test_data["error_test_cases"] + + for test_case in valid_test_cases: + pubnonces = [pnonce[i] for i in test_case["nonce_indices"]] + aggnonce = bytes.fromhex(test_case["aggnonce"]) + assert aggnonce == nonce_agg(pubnonces) + + pubkeys = [X[i] for i in test_case["key_indices"]] + tweaks = [tweak[i] for i in test_case["tweak_indices"]] + is_xonly = test_case["is_xonly"] + psigs = [psig[i] for i in test_case["psig_indices"]] + expected = bytes.fromhex(test_case["expected"]) + + session_ctx = SessionContext(aggnonce, pubkeys, tweaks, is_xonly, msg) + sig = partial_sig_agg(psigs, session_ctx) + assert sig == expected + aggpk = get_xonly_pk(key_agg_and_tweak(pubkeys, tweaks, is_xonly)) + assert schnorr_verify(msg, aggpk, sig) + + for i, test_case in enumerate(error_test_cases): + exception, except_fn = get_error_details(test_case) + + pubnonces = [pnonce[i] for i in test_case["nonce_indices"]] + aggnonce = nonce_agg(pubnonces) + + pubkeys = [X[i] for i in test_case["key_indices"]] + tweaks = [tweak[i] for i in test_case["tweak_indices"]] + is_xonly = test_case["is_xonly"] + psigs = [psig[i] for i in test_case["psig_indices"]] + + session_ctx = SessionContext(aggnonce, pubkeys, tweaks, is_xonly, msg) + assert_raises(exception, lambda: partial_sig_agg(psigs, session_ctx), except_fn) + +def test_sign_and_verify_random(iters: int) -> None: + for i in range(iters): + sk_1 = secrets.token_bytes(32) + sk_2 = secrets.token_bytes(32) + pk_1 = individual_pk(sk_1) + pk_2 = individual_pk(sk_2) + pubkeys = [pk_1, pk_2] + + # In this example, the message and aggregate pubkey are known + # before nonce generation, so they can be passed into the nonce + # generation function as a defense-in-depth measure to protect + # against nonce reuse. + # + # If these values are not known when nonce_gen is called, empty + # byte arrays can be passed in for the corresponding arguments + # instead. + msg = secrets.token_bytes(32) + v = secrets.randbelow(4) + tweaks = [secrets.token_bytes(32) for _ in range(v)] + is_xonly = [secrets.choice([False, True]) for _ in range(v)] + aggpk = get_xonly_pk(key_agg_and_tweak(pubkeys, tweaks, is_xonly)) + + # Use a non-repeating counter for extra_in + secnonce_1, pubnonce_1 = nonce_gen(sk_1, pk_1, aggpk, msg, i.to_bytes(4, 'big')) + + # On even iterations use regular signing algorithm for signer 2, + # otherwise use deterministic signing algorithm + if i % 2 == 0: + # Use a clock for extra_in + t = time.clock_gettime_ns(time.CLOCK_MONOTONIC) + secnonce_2, pubnonce_2 = nonce_gen(sk_2, pk_2, aggpk, msg, t.to_bytes(8, 'big')) + else: + aggothernonce = nonce_agg([pubnonce_1]) + rand = secrets.token_bytes(32) + pubnonce_2, psig_2 = deterministic_sign(sk_2, aggothernonce, pubkeys, tweaks, is_xonly, msg, rand) + + pubnonces = [pubnonce_1, pubnonce_2] + aggnonce = nonce_agg(pubnonces) + + session_ctx = SessionContext(aggnonce, pubkeys, tweaks, is_xonly, msg) + psig_1 = sign(secnonce_1, sk_1, session_ctx) + assert partial_sig_verify(psig_1, pubnonces, pubkeys, tweaks, is_xonly, msg, 0) + # An exception is thrown if secnonce_1 is accidentally reused + assert_raises(ValueError, lambda: sign(secnonce_1, sk_1, session_ctx), lambda e: True) + + # Wrong signer index + assert not partial_sig_verify(psig_1, pubnonces, pubkeys, tweaks, is_xonly, msg, 1) + + # Wrong message + assert not partial_sig_verify(psig_1, pubnonces, pubkeys, tweaks, is_xonly, secrets.token_bytes(32), 0) + + if i % 2 == 0: + psig_2 = sign(secnonce_2, sk_2, session_ctx) + assert partial_sig_verify(psig_2, pubnonces, pubkeys, tweaks, is_xonly, msg, 1) + + sig = partial_sig_agg([psig_1, psig_2], session_ctx) + assert schnorr_verify(msg, aggpk, sig) + +if __name__ == '__main__': + test_key_sort_vectors() + test_key_agg_vectors() + test_nonce_gen_vectors() + test_nonce_agg_vectors() + test_sign_verify_vectors() + test_tweak_vectors() + test_det_sign_vectors() + test_sig_agg_vectors() + test_sign_and_verify_random(6) diff --git a/bip-0327/tests.sh b/bip-0327/tests.sh new file mode 100755 index 0000000000..b363f40bbd --- /dev/null +++ b/bip-0327/tests.sh @@ -0,0 +1,8 @@ +#!/bin/sh + +set -e + +cd "$(dirname "$0")" +mypy --no-error-summary reference.py +python3 reference.py +python3 gen_vectors_helper.py > /dev/null diff --git a/bip-0327/vectors/det_sign_vectors.json b/bip-0327/vectors/det_sign_vectors.json new file mode 100644 index 0000000000..261669ccd0 --- /dev/null +++ b/bip-0327/vectors/det_sign_vectors.json @@ -0,0 +1,144 @@ +{ + "sk": "7FB9E0E687ADA1EEBF7ECFE2F21E73EBDB51A7D450948DFE8D76D7F2D1007671", + "pubkeys": [ + "03935F972DA013F80AE011890FA89B67A27B7BE6CCB24D3274D18B2D4067F261A9", + "02F9308A019258C31049344F85F89D5229B531C845836F99B08601F113BCE036F9", + "02DFF1D77F2A671C5F36183726DB2341BE58FEAE1DA2DECED843240F7B502BA659", + "020000000000000000000000000000000000000000000000000000000000000007" + ], + "msgs": [ + "F95466D086770E689964664219266FE5ED215C92AE20BAB5C9D79ADDDDF3C0CF", + "2626262626262626262626262626262626262626262626262626262626262626262626262626" + ], + "valid_test_cases": [ + { + "rand": "0000000000000000000000000000000000000000000000000000000000000000", + "aggothernonce": "0337C87821AFD50A8644D820A8F3E02E499C931865C2360FB43D0A0D20DAFE07EA0287BF891D2A6DEAEBADC909352AA9405D1428C15F4B75F04DAE642A95C2548480", + "key_indices": [0, 1, 2], + "tweaks": [], + "is_xonly": [], + "msg_index": 0, + "signer_index": 0, + "expected": [ + "03D96275257C2FCCBB6EEB77BDDF51D3C88C26EE1626C6CDA8999B9D34F4BA13A60309BE2BF883C6ABE907FA822D9CA166D51A3DCC28910C57528F6983FC378B7843", + "41EA65093F71D084785B20DC26A887CD941C9597860A21660CBDB9CC2113CAD3" + ] + }, + { + "rand": null, + "aggothernonce": "0337C87821AFD50A8644D820A8F3E02E499C931865C2360FB43D0A0D20DAFE07EA0287BF891D2A6DEAEBADC909352AA9405D1428C15F4B75F04DAE642A95C2548480", + "key_indices": [1, 0, 2], + "tweaks": [], + "is_xonly": [], + "msg_index": 0, + "signer_index": 1, + "expected": [ + "028FBCCF5BB73A7B61B270BAD15C0F9475D577DD85C2157C9D38BEF1EC922B48770253BE3638C87369BC287E446B7F2C8CA5BEB9FFBD1EA082C62913982A65FC214D", + "AEAA31262637BFA88D5606679018A0FEEEC341F3107D1199857F6C81DE61B8DD" + ] + }, + { + "rand": "FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF", + "aggothernonce": "0279BE667EF9DCBBAC55A06295CE870B07029BFCDB2DCE28D959F2815B16F817980279BE667EF9DCBBAC55A06295CE870B07029BFCDB2DCE28D959F2815B16F81798", + "key_indices": [1, 2, 0], + "tweaks": [], + "is_xonly": [], + "msg_index": 1, + "signer_index": 2, + "expected": [ + "024FA8D774F0C8743FAA77AFB4D08EE5A013C2E8EEAD8A6F08A77DDD2D28266DB803050905E8C994477F3F2981861A2E3791EF558626E645FBF5AA131C5D6447C2C2", + "FEE28A56B8556B7632E42A84122C51A4861B1F2DEC7E81B632195E56A52E3E13" + ], + "comment": "Message longer than 32 bytes" + }, + { + "rand": "0000000000000000000000000000000000000000000000000000000000000000", + "aggothernonce": "032DE2662628C90B03F5E720284EB52FF7D71F4284F627B68A853D78C78E1FFE9303E4C5524E83FFE1493B9077CF1CA6BEB2090C93D930321071AD40B2F44E599046", + "key_indices": [0, 1, 2], + "tweaks": ["E8F791FF9225A2AF0102AFFF4A9A723D9612A682A25EBE79802B263CDFCD83BB"], + "is_xonly": [true], + "msg_index": 0, + "signer_index": 0, + "expected": [ + "031E07C0D11A0134E55DB1FC16095ADCBD564236194374AA882BFB3C78273BF673039D0336E8CA6288C00BFC1F8B594563529C98661172B9BC1BE85C23A4CE1F616B", + "7B1246C5889E59CB0375FA395CC86AC42D5D7D59FD8EAB4FDF1DCAB2B2F006EA" + ], + "comment": "Tweaked public key" + } + ], + "error_test_cases": [ + { + "rand": "0000000000000000000000000000000000000000000000000000000000000000", + "aggothernonce": "0337C87821AFD50A8644D820A8F3E02E499C931865C2360FB43D0A0D20DAFE07EA0287BF891D2A6DEAEBADC909352AA9405D1428C15F4B75F04DAE642A95C2548480", + "key_indices": [1, 0, 3], + "tweaks": [], + "is_xonly": [], + "msg_index": 0, + "signer_index": 1, + "error": { + "type": "invalid_contribution", + "signer": 2, + "contrib": "pubkey" + }, + "comment": "Signer 2 provided an invalid public key" + }, + { + "rand": "0000000000000000000000000000000000000000000000000000000000000000", + "aggothernonce": "0337C87821AFD50A8644D820A8F3E02E499C931865C2360FB43D0A0D20DAFE07EA0287BF891D2A6DEAEBADC909352AA9405D1428C15F4B75F04DAE642A95C2548480", + "key_indices": [1, 2], + "tweaks": [], + "is_xonly": [], + "msg_index": 0, + "signer_index": 1, + "error": { + "type": "value", + "message": "The signer's pubkey must be included in the list of pubkeys." + }, + "comment": "The signers pubkey is not in the list of pubkeys" + }, + { + "rand": "0000000000000000000000000000000000000000000000000000000000000000", + "aggothernonce": "0437C87821AFD50A8644D820A8F3E02E499C931865C2360FB43D0A0D20DAFE07EA0287BF891D2A6DEAEBADC909352AA9405D1428C15F4B75F04DAE642A95C2548480", + "key_indices": [1, 2, 0], + "tweaks": [], + "is_xonly": [], + "msg_index": 0, + "signer_index": 2, + "error": { + "type": "invalid_contribution", + "signer": null, + "contrib": "aggothernonce" + }, + "comment": "aggothernonce is invalid due wrong tag, 0x04, in the first half" + }, + { + "rand": "0000000000000000000000000000000000000000000000000000000000000000", + "aggothernonce": "0000000000000000000000000000000000000000000000000000000000000000000287BF891D2A6DEAEBADC909352AA9405D1428C15F4B75F04DAE642A95C2548480", + "key_indices": [1, 2, 0], + "tweaks": [], + "is_xonly": [], + "msg_index": 0, + "signer_index": 2, + "error": { + "type": "invalid_contribution", + "signer": null, + "contrib": "aggothernonce" + }, + "comment": "aggothernonce is invalid because first half corresponds to point at infinity" + }, + { + "rand": "0000000000000000000000000000000000000000000000000000000000000000", + "aggothernonce": "0337C87821AFD50A8644D820A8F3E02E499C931865C2360FB43D0A0D20DAFE07EA0287BF891D2A6DEAEBADC909352AA9405D1428C15F4B75F04DAE642A95C2548480", + "key_indices": [1, 2, 0], + "tweaks": ["FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEBAAEDCE6AF48A03BBFD25E8CD0364141"], + "is_xonly": [false], + "msg_index": 0, + "signer_index": 2, + "error": { + "type": "value", + "message": "The tweak must be less than n." + }, + "comment": "Tweak is invalid because it exceeds group size" + } + ] +} diff --git a/bip-0327/vectors/key_agg_vectors.json b/bip-0327/vectors/key_agg_vectors.json new file mode 100644 index 0000000000..b2e623de60 --- /dev/null +++ b/bip-0327/vectors/key_agg_vectors.json @@ -0,0 +1,88 @@ +{ + "pubkeys": [ + "02F9308A019258C31049344F85F89D5229B531C845836F99B08601F113BCE036F9", + "03DFF1D77F2A671C5F36183726DB2341BE58FEAE1DA2DECED843240F7B502BA659", + "023590A94E768F8E1815C2F24B4D80A8E3149316C3518CE7B7AD338368D038CA66", + "020000000000000000000000000000000000000000000000000000000000000005", + "02FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEFFFFFC30", + "04F9308A019258C31049344F85F89D5229B531C845836F99B08601F113BCE036F9", + "03935F972DA013F80AE011890FA89B67A27B7BE6CCB24D3274D18B2D4067F261A9" + ], + "tweaks": [ + "FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEBAAEDCE6AF48A03BBFD25E8CD0364141", + "252E4BD67410A76CDF933D30EAA1608214037F1B105A013ECCD3C5C184A6110B" + ], + "valid_test_cases": [ + { + "key_indices": [0, 1, 2], + "expected": "90539EEDE565F5D054F32CC0C220126889ED1E5D193BAF15AEF344FE59D4610C" + }, + { + "key_indices": [2, 1, 0], + "expected": "6204DE8B083426DC6EAF9502D27024D53FC826BF7D2012148A0575435DF54B2B" + }, + { + "key_indices": [0, 0, 0], + "expected": "B436E3BAD62B8CD409969A224731C193D051162D8C5AE8B109306127DA3AA935" + }, + { + "key_indices": [0, 0, 1, 1], + "expected": "69BC22BFA5D106306E48A20679DE1D7389386124D07571D0D872686028C26A3E" + } + ], + "error_test_cases": [ + { + "key_indices": [0, 3], + "tweak_indices": [], + "is_xonly": [], + "error": { + "type": "invalid_contribution", + "signer": 1, + "contrib": "pubkey" + }, + "comment": "Invalid public key" + }, + { + "key_indices": [0, 4], + "tweak_indices": [], + "is_xonly": [], + "error": { + "type": "invalid_contribution", + "signer": 1, + "contrib": "pubkey" + }, + "comment": "Public key exceeds field size" + }, + { + "key_indices": [5, 0], + "tweak_indices": [], + "is_xonly": [], + "error": { + "type": "invalid_contribution", + "signer": 0, + "contrib": "pubkey" + }, + "comment": "First byte of public key is not 2 or 3" + }, + { + "key_indices": [0, 1], + "tweak_indices": [0], + "is_xonly": [true], + "error": { + "type": "value", + "message": "The tweak must be less than n." + }, + "comment": "Tweak is out of range" + }, + { + "key_indices": [6], + "tweak_indices": [1], + "is_xonly": [false], + "error": { + "type": "value", + "message": "The result of tweaking cannot be infinity." + }, + "comment": "Intermediate tweaking result is point at infinity" + } + ] +} diff --git a/bip-0327/vectors/key_sort_vectors.json b/bip-0327/vectors/key_sort_vectors.json new file mode 100644 index 0000000000..de088a746e --- /dev/null +++ b/bip-0327/vectors/key_sort_vectors.json @@ -0,0 +1,18 @@ +{ + "pubkeys": [ + "02DD308AFEC5777E13121FA72B9CC1B7CC0139715309B086C960E18FD969774EB8", + "02F9308A019258C31049344F85F89D5229B531C845836F99B08601F113BCE036F9", + "03DFF1D77F2A671C5F36183726DB2341BE58FEAE1DA2DECED843240F7B502BA659", + "023590A94E768F8E1815C2F24B4D80A8E3149316C3518CE7B7AD338368D038CA66", + "02DD308AFEC5777E13121FA72B9CC1B7CC0139715309B086C960E18FD969774EFF", + "02DD308AFEC5777E13121FA72B9CC1B7CC0139715309B086C960E18FD969774EB8" + ], + "sorted_pubkeys": [ + "023590A94E768F8E1815C2F24B4D80A8E3149316C3518CE7B7AD338368D038CA66", + "02DD308AFEC5777E13121FA72B9CC1B7CC0139715309B086C960E18FD969774EB8", + "02DD308AFEC5777E13121FA72B9CC1B7CC0139715309B086C960E18FD969774EB8", + "02DD308AFEC5777E13121FA72B9CC1B7CC0139715309B086C960E18FD969774EFF", + "02F9308A019258C31049344F85F89D5229B531C845836F99B08601F113BCE036F9", + "03DFF1D77F2A671C5F36183726DB2341BE58FEAE1DA2DECED843240F7B502BA659" + ] +} diff --git a/bip-0327/vectors/nonce_agg_vectors.json b/bip-0327/vectors/nonce_agg_vectors.json new file mode 100644 index 0000000000..1c04b8818f --- /dev/null +++ b/bip-0327/vectors/nonce_agg_vectors.json @@ -0,0 +1,51 @@ +{ + "pnonces": [ + "020151C80F435648DF67A22B749CD798CE54E0321D034B92B709B567D60A42E66603BA47FBC1834437B3212E89A84D8425E7BF12E0245D98262268EBDCB385D50641", + "03FF406FFD8ADB9CD29877E4985014F66A59F6CD01C0E88CAA8E5F3166B1F676A60248C264CDD57D3C24D79990B0F865674EB62A0F9018277A95011B41BFC193B833", + "020151C80F435648DF67A22B749CD798CE54E0321D034B92B709B567D60A42E6660279BE667EF9DCBBAC55A06295CE870B07029BFCDB2DCE28D959F2815B16F81798", + "03FF406FFD8ADB9CD29877E4985014F66A59F6CD01C0E88CAA8E5F3166B1F676A60379BE667EF9DCBBAC55A06295CE870B07029BFCDB2DCE28D959F2815B16F81798", + "04FF406FFD8ADB9CD29877E4985014F66A59F6CD01C0E88CAA8E5F3166B1F676A60248C264CDD57D3C24D79990B0F865674EB62A0F9018277A95011B41BFC193B833", + "03FF406FFD8ADB9CD29877E4985014F66A59F6CD01C0E88CAA8E5F3166B1F676A60248C264CDD57D3C24D79990B0F865674EB62A0F9018277A95011B41BFC193B831", + "03FF406FFD8ADB9CD29877E4985014F66A59F6CD01C0E88CAA8E5F3166B1F676A602FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEFFFFFC30" + ], + "valid_test_cases": [ + { + "pnonce_indices": [0, 1], + "expected": "035FE1873B4F2967F52FEA4A06AD5A8ECCBE9D0FD73068012C894E2E87CCB5804B024725377345BDE0E9C33AF3C43C0A29A9249F2F2956FA8CFEB55C8573D0262DC8" + }, + { + "pnonce_indices": [2, 3], + "expected": "035FE1873B4F2967F52FEA4A06AD5A8ECCBE9D0FD73068012C894E2E87CCB5804B000000000000000000000000000000000000000000000000000000000000000000", + "comment": "Sum of second points encoded in the nonces is point at infinity which is serialized as 33 zero bytes" + } + ], + "error_test_cases": [ + { + "pnonce_indices": [0, 4], + "error": { + "type": "invalid_contribution", + "signer": 1, + "contrib": "pubnonce" + }, + "comment": "Public nonce from signer 1 is invalid due wrong tag, 0x04, in the first half" + }, + { + "pnonce_indices": [5, 1], + "error": { + "type": "invalid_contribution", + "signer": 0, + "contrib": "pubnonce" + }, + "comment": "Public nonce from signer 0 is invalid because the second half does not correspond to an X coordinate" + }, + { + "pnonce_indices": [6, 1], + "error": { + "type": "invalid_contribution", + "signer": 0, + "contrib": "pubnonce" + }, + "comment": "Public nonce from signer 0 is invalid because second half exceeds field size" + } + ] +} diff --git a/bip-0327/vectors/nonce_gen_vectors.json b/bip-0327/vectors/nonce_gen_vectors.json new file mode 100644 index 0000000000..ced946f3ef --- /dev/null +++ b/bip-0327/vectors/nonce_gen_vectors.json @@ -0,0 +1,44 @@ +{ + "test_cases": [ + { + "rand_": "0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F", + "sk": "0202020202020202020202020202020202020202020202020202020202020202", + "pk": "024D4B6CD1361032CA9BD2AEB9D900AA4D45D9EAD80AC9423374C451A7254D0766", + "aggpk": "0707070707070707070707070707070707070707070707070707070707070707", + "msg": "0101010101010101010101010101010101010101010101010101010101010101", + "extra_in": "0808080808080808080808080808080808080808080808080808080808080808", + "expected_secnonce": "B114E502BEAA4E301DD08A50264172C84E41650E6CB726B410C0694D59EFFB6495B5CAF28D045B973D63E3C99A44B807BDE375FD6CB39E46DC4A511708D0E9D2024D4B6CD1361032CA9BD2AEB9D900AA4D45D9EAD80AC9423374C451A7254D0766", + "expected_pubnonce": "02F7BE7089E8376EB355272368766B17E88E7DB72047D05E56AA881EA52B3B35DF02C29C8046FDD0DED4C7E55869137200FBDBFE2EB654267B6D7013602CAED3115A" + }, + { + "rand_": "0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F", + "sk": "0202020202020202020202020202020202020202020202020202020202020202", + "pk": "024D4B6CD1361032CA9BD2AEB9D900AA4D45D9EAD80AC9423374C451A7254D0766", + "aggpk": "0707070707070707070707070707070707070707070707070707070707070707", + "msg": "", + "extra_in": "0808080808080808080808080808080808080808080808080808080808080808", + "expected_secnonce": "E862B068500320088138468D47E0E6F147E01B6024244AE45EAC40ACE5929B9F0789E051170B9E705D0B9EB49049A323BBBBB206D8E05C19F46C6228742AA7A9024D4B6CD1361032CA9BD2AEB9D900AA4D45D9EAD80AC9423374C451A7254D0766", + "expected_pubnonce": "023034FA5E2679F01EE66E12225882A7A48CC66719B1B9D3B6C4DBD743EFEDA2C503F3FD6F01EB3A8E9CB315D73F1F3D287CAFBB44AB321153C6287F407600205109" + }, + { + "rand_": "0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F", + "sk": "0202020202020202020202020202020202020202020202020202020202020202", + "pk": "024D4B6CD1361032CA9BD2AEB9D900AA4D45D9EAD80AC9423374C451A7254D0766", + "aggpk": "0707070707070707070707070707070707070707070707070707070707070707", + "msg": "2626262626262626262626262626262626262626262626262626262626262626262626262626", + "extra_in": "0808080808080808080808080808080808080808080808080808080808080808", + "expected_secnonce": "3221975ACBDEA6820EABF02A02B7F27D3A8EF68EE42787B88CBEFD9AA06AF3632EE85B1A61D8EF31126D4663A00DD96E9D1D4959E72D70FE5EBB6E7696EBA66F024D4B6CD1361032CA9BD2AEB9D900AA4D45D9EAD80AC9423374C451A7254D0766", + "expected_pubnonce": "02E5BBC21C69270F59BD634FCBFA281BE9D76601295345112C58954625BF23793A021307511C79F95D38ACACFF1B4DA98228B77E65AA216AD075E9673286EFB4EAF3" + }, + { + "rand_": "0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F", + "sk": null, + "pk": "02F9308A019258C31049344F85F89D5229B531C845836F99B08601F113BCE036F9", + "aggpk": null, + "msg": null, + "extra_in": null, + "expected_secnonce": "89BDD787D0284E5E4D5FC572E49E316BAB7E21E3B1830DE37DFE80156FA41A6D0B17AE8D024C53679699A6FD7944D9C4A366B514BAF43088E0708B1023DD289702F9308A019258C31049344F85F89D5229B531C845836F99B08601F113BCE036F9", + "expected_pubnonce": "02C96E7CB1E8AA5DAC64D872947914198F607D90ECDE5200DE52978AD5DED63C000299EC5117C2D29EDEE8A2092587C3909BE694D5CFF0667D6C02EA4059F7CD9786" + } + ] +} diff --git a/bip-0327/vectors/sig_agg_vectors.json b/bip-0327/vectors/sig_agg_vectors.json new file mode 100644 index 0000000000..04a7bc6b50 --- /dev/null +++ b/bip-0327/vectors/sig_agg_vectors.json @@ -0,0 +1,151 @@ +{ + "pubkeys": [ + "03935F972DA013F80AE011890FA89B67A27B7BE6CCB24D3274D18B2D4067F261A9", + "02D2DC6F5DF7C56ACF38C7FA0AE7A759AE30E19B37359DFDE015872324C7EF6E05", + "03C7FB101D97FF930ACD0C6760852EF64E69083DE0B06AC6335724754BB4B0522C", + "02352433B21E7E05D3B452B81CAE566E06D2E003ECE16D1074AABA4289E0E3D581" + ], + "pnonces": [ + "036E5EE6E28824029FEA3E8A9DDD2C8483F5AF98F7177C3AF3CB6F47CAF8D94AE902DBA67E4A1F3680826172DA15AFB1A8CA85C7C5CC88900905C8DC8C328511B53E", + "03E4F798DA48A76EEC1C9CC5AB7A880FFBA201A5F064E627EC9CB0031D1D58FC5103E06180315C5A522B7EC7C08B69DCD721C313C940819296D0A7AB8E8795AC1F00", + "02C0068FD25523A31578B8077F24F78F5BD5F2422AFF47C1FADA0F36B3CEB6C7D202098A55D1736AA5FCC21CF0729CCE852575C06C081125144763C2C4C4A05C09B6", + "031F5C87DCFBFCF330DEE4311D85E8F1DEA01D87A6F1C14CDFC7E4F1D8C441CFA40277BF176E9F747C34F81B0D9F072B1B404A86F402C2D86CF9EA9E9C69876EA3B9", + "023F7042046E0397822C4144A17F8B63D78748696A46C3B9F0A901D296EC3406C302022B0B464292CF9751D699F10980AC764E6F671EFCA15069BBE62B0D1C62522A", + "02D97DDA5988461DF58C5897444F116A7C74E5711BF77A9446E27806563F3B6C47020CBAD9C363A7737F99FA06B6BE093CEAFF5397316C5AC46915C43767AE867C00" + ], + "tweaks": [ + "B511DA492182A91B0FFB9A98020D55F260AE86D7ECBD0399C7383D59A5F2AF7C", + "A815FE049EE3C5AAB66310477FBC8BCCCAC2F3395F59F921C364ACD78A2F48DC", + "75448A87274B056468B977BE06EB1E9F657577B7320B0A3376EA51FD420D18A8" + ], + "psigs": [ + "B15D2CD3C3D22B04DAE438CE653F6B4ECF042F42CFDED7C41B64AAF9B4AF53FB", + "6193D6AC61B354E9105BBDC8937A3454A6D705B6D57322A5A472A02CE99FCB64", + "9A87D3B79EC67228CB97878B76049B15DBD05B8158D17B5B9114D3C226887505", + "66F82EA90923689B855D36C6B7E032FB9970301481B99E01CDB4D6AC7C347A15", + "4F5AEE41510848A6447DCD1BBC78457EF69024944C87F40250D3EF2C25D33EFE", + "DDEF427BBB847CC027BEFF4EDB01038148917832253EBC355FC33F4A8E2FCCE4", + "97B890A26C981DA8102D3BC294159D171D72810FDF7C6A691DEF02F0F7AF3FDC", + "53FA9E08BA5243CBCB0D797C5EE83BC6728E539EB76C2D0BF0F971EE4E909971", + "FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEBAAEDCE6AF48A03BBFD25E8CD0364141" + ], + "msg": "599C67EA410D005B9DA90817CF03ED3B1C868E4DA4EDF00A5880B0082C237869", + "valid_test_cases": [ + { + "aggnonce": "0341432722C5CD0268D829C702CF0D1CBCE57033EED201FD335191385227C3210C03D377F2D258B64AADC0E16F26462323D701D286046A2EA93365656AFD9875982B", + "nonce_indices": [ + 0, + 1 + ], + "key_indices": [ + 0, + 1 + ], + "tweak_indices": [], + "is_xonly": [], + "psig_indices": [ + 0, + 1 + ], + "expected": "041DA22223CE65C92C9A0D6C2CAC828AAF1EEE56304FEC371DDF91EBB2B9EF0912F1038025857FEDEB3FF696F8B99FA4BB2C5812F6095A2E0004EC99CE18DE1E" + }, + { + "aggnonce": "0224AFD36C902084058B51B5D36676BBA4DC97C775873768E58822F87FE437D792028CB15929099EEE2F5DAE404CD39357591BA32E9AF4E162B8D3E7CB5EFE31CB20", + "nonce_indices": [ + 0, + 2 + ], + "key_indices": [ + 0, + 2 + ], + "tweak_indices": [], + "is_xonly": [], + "psig_indices": [ + 2, + 3 + ], + "expected": "1069B67EC3D2F3C7C08291ACCB17A9C9B8F2819A52EB5DF8726E17E7D6B52E9F01800260A7E9DAC450F4BE522DE4CE12BA91AEAF2B4279219EF74BE1D286ADD9" + }, + { + "aggnonce": "0208C5C438C710F4F96A61E9FF3C37758814B8C3AE12BFEA0ED2C87FF6954FF186020B1816EA104B4FCA2D304D733E0E19CEAD51303FF6420BFD222335CAA402916D", + "nonce_indices": [ + 0, + 3 + ], + "key_indices": [ + 0, + 2 + ], + "tweak_indices": [ + 0 + ], + "is_xonly": [ + false + ], + "psig_indices": [ + 4, + 5 + ], + "expected": "5C558E1DCADE86DA0B2F02626A512E30A22CF5255CAEA7EE32C38E9A71A0E9148BA6C0E6EC7683B64220F0298696F1B878CD47B107B81F7188812D593971E0CC" + }, + { + "aggnonce": "02B5AD07AFCD99B6D92CB433FBD2A28FDEB98EAE2EB09B6014EF0F8197CD58403302E8616910F9293CF692C49F351DB86B25E352901F0E237BAFDA11F1C1CEF29FFD", + "nonce_indices": [ + 0, + 4 + ], + "key_indices": [ + 0, + 3 + ], + "tweak_indices": [ + 0, + 1, + 2 + ], + "is_xonly": [ + true, + false, + true + ], + "psig_indices": [ + 6, + 7 + ], + "expected": "839B08820B681DBA8DAF4CC7B104E8F2638F9388F8D7A555DC17B6E6971D7426CE07BF6AB01F1DB50E4E33719295F4094572B79868E440FB3DEFD3FAC1DB589E" + } + ], + "error_test_cases": [ + { + "aggnonce": "02B5AD07AFCD99B6D92CB433FBD2A28FDEB98EAE2EB09B6014EF0F8197CD58403302E8616910F9293CF692C49F351DB86B25E352901F0E237BAFDA11F1C1CEF29FFD", + "nonce_indices": [ + 0, + 4 + ], + "key_indices": [ + 0, + 3 + ], + "tweak_indices": [ + 0, + 1, + 2 + ], + "is_xonly": [ + true, + false, + true + ], + "psig_indices": [ + 7, + 8 + ], + "error": { + "type": "invalid_contribution", + "signer": 1 + }, + "comment": "Partial signature is invalid because it exceeds group size" + } + ] +} diff --git a/bip-0327/vectors/sign_verify_vectors.json b/bip-0327/vectors/sign_verify_vectors.json new file mode 100644 index 0000000000..b467640ce3 --- /dev/null +++ b/bip-0327/vectors/sign_verify_vectors.json @@ -0,0 +1,212 @@ +{ + "sk": "7FB9E0E687ADA1EEBF7ECFE2F21E73EBDB51A7D450948DFE8D76D7F2D1007671", + "pubkeys": [ + "03935F972DA013F80AE011890FA89B67A27B7BE6CCB24D3274D18B2D4067F261A9", + "02F9308A019258C31049344F85F89D5229B531C845836F99B08601F113BCE036F9", + "02DFF1D77F2A671C5F36183726DB2341BE58FEAE1DA2DECED843240F7B502BA661", + "020000000000000000000000000000000000000000000000000000000000000007" + ], + "secnonces": [ + "508B81A611F100A6B2B6B29656590898AF488BCF2E1F55CF22E5CFB84421FE61FA27FD49B1D50085B481285E1CA205D55C82CC1B31FF5CD54A489829355901F703935F972DA013F80AE011890FA89B67A27B7BE6CCB24D3274D18B2D4067F261A9", + "0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000003935F972DA013F80AE011890FA89B67A27B7BE6CCB24D3274D18B2D4067F261A9" + ], + "pnonces": [ + "0337C87821AFD50A8644D820A8F3E02E499C931865C2360FB43D0A0D20DAFE07EA0287BF891D2A6DEAEBADC909352AA9405D1428C15F4B75F04DAE642A95C2548480", + "0279BE667EF9DCBBAC55A06295CE870B07029BFCDB2DCE28D959F2815B16F817980279BE667EF9DCBBAC55A06295CE870B07029BFCDB2DCE28D959F2815B16F81798", + "032DE2662628C90B03F5E720284EB52FF7D71F4284F627B68A853D78C78E1FFE9303E4C5524E83FFE1493B9077CF1CA6BEB2090C93D930321071AD40B2F44E599046", + "0237C87821AFD50A8644D820A8F3E02E499C931865C2360FB43D0A0D20DAFE07EA0387BF891D2A6DEAEBADC909352AA9405D1428C15F4B75F04DAE642A95C2548480", + "0200000000000000000000000000000000000000000000000000000000000000090287BF891D2A6DEAEBADC909352AA9405D1428C15F4B75F04DAE642A95C2548480" + ], + "aggnonces": [ + "028465FCF0BBDBCF443AABCCE533D42B4B5A10966AC09A49655E8C42DAAB8FCD61037496A3CC86926D452CAFCFD55D25972CA1675D549310DE296BFF42F72EEEA8C9", + "000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000", + "048465FCF0BBDBCF443AABCCE533D42B4B5A10966AC09A49655E8C42DAAB8FCD61037496A3CC86926D452CAFCFD55D25972CA1675D549310DE296BFF42F72EEEA8C9", + "028465FCF0BBDBCF443AABCCE533D42B4B5A10966AC09A49655E8C42DAAB8FCD61020000000000000000000000000000000000000000000000000000000000000009", + "028465FCF0BBDBCF443AABCCE533D42B4B5A10966AC09A49655E8C42DAAB8FCD6102FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEFFFFFC30" + ], + "msgs": [ + "F95466D086770E689964664219266FE5ED215C92AE20BAB5C9D79ADDDDF3C0CF", + "", + "2626262626262626262626262626262626262626262626262626262626262626262626262626" + ], + "valid_test_cases": [ + { + "key_indices": [0, 1, 2], + "nonce_indices": [0, 1, 2], + "aggnonce_index": 0, + "msg_index": 0, + "signer_index": 0, + "expected": "012ABBCB52B3016AC03AD82395A1A415C48B93DEF78718E62A7A90052FE224FB" + }, + { + "key_indices": [1, 0, 2], + "nonce_indices": [1, 0, 2], + "aggnonce_index": 0, + "msg_index": 0, + "signer_index": 1, + "expected": "9FF2F7AAA856150CC8819254218D3ADEEB0535269051897724F9DB3789513A52" + }, + { + "key_indices": [1, 2, 0], + "nonce_indices": [1, 2, 0], + "aggnonce_index": 0, + "msg_index": 0, + "signer_index": 2, + "expected": "FA23C359F6FAC4E7796BB93BC9F0532A95468C539BA20FF86D7C76ED92227900" + }, + { + "key_indices": [0, 1], + "nonce_indices": [0, 3], + "aggnonce_index": 1, + "msg_index": 0, + "signer_index": 0, + "expected": "AE386064B26105404798F75DE2EB9AF5EDA5387B064B83D049CB7C5E08879531", + "comment": "Both halves of aggregate nonce correspond to point at infinity" + }, + { + "key_indices": [0, 1, 2], + "nonce_indices": [0, 1, 2], + "aggnonce_index": 0, + "msg_index": 1, + "signer_index": 0, + "expected": "D7D63FFD644CCDA4E62BC2BC0B1D02DD32A1DC3030E155195810231D1037D82D", + "comment": "Empty message" + }, + { + "key_indices": [0, 1, 2], + "nonce_indices": [0, 1, 2], + "aggnonce_index": 0, + "msg_index": 2, + "signer_index": 0, + "expected": "E184351828DA5094A97C79CABDAAA0BFB87608C32E8829A4DF5340A6F243B78C", + "comment": "38-byte message" + } + ], + "sign_error_test_cases": [ + { + "key_indices": [1, 2], + "aggnonce_index": 0, + "msg_index": 0, + "secnonce_index": 0, + "error": { + "type": "value", + "message": "The signer's pubkey must be included in the list of pubkeys." + }, + "comment": "The signers pubkey is not in the list of pubkeys. This test case is optional: it can be skipped by implementations that do not check that the signer's pubkey is included in the list of pubkeys." + }, + { + "key_indices": [1, 0, 3], + "aggnonce_index": 0, + "msg_index": 0, + "secnonce_index": 0, + "error": { + "type": "invalid_contribution", + "signer": 2, + "contrib": "pubkey" + }, + "comment": "Signer 2 provided an invalid public key" + }, + { + "key_indices": [1, 2, 0], + "aggnonce_index": 2, + "msg_index": 0, + "secnonce_index": 0, + "error": { + "type": "invalid_contribution", + "signer": null, + "contrib": "aggnonce" + }, + "comment": "Aggregate nonce is invalid due wrong tag, 0x04, in the first half" + }, + { + "key_indices": [1, 2, 0], + "aggnonce_index": 3, + "msg_index": 0, + "secnonce_index": 0, + "error": { + "type": "invalid_contribution", + "signer": null, + "contrib": "aggnonce" + }, + "comment": "Aggregate nonce is invalid because the second half does not correspond to an X coordinate" + }, + { + "key_indices": [1, 2, 0], + "aggnonce_index": 4, + "msg_index": 0, + "secnonce_index": 0, + "error": { + "type": "invalid_contribution", + "signer": null, + "contrib": "aggnonce" + }, + "comment": "Aggregate nonce is invalid because second half exceeds field size" + }, + { + "key_indices": [0, 1, 2], + "aggnonce_index": 0, + "msg_index": 0, + "signer_index": 0, + "secnonce_index": 1, + "error": { + "type": "value", + "message": "first secnonce value is out of range." + }, + "comment": "Secnonce is invalid which may indicate nonce reuse" + } + ], + "verify_fail_test_cases": [ + { + "sig": "97AC833ADCB1AFA42EBF9E0725616F3C9A0D5B614F6FE283CEAAA37A8FFAF406", + "key_indices": [0, 1, 2], + "nonce_indices": [0, 1, 2], + "msg_index": 0, + "signer_index": 0, + "comment": "Wrong signature (which is equal to the negation of valid signature)" + }, + { + "sig": "68537CC5234E505BD14061F8DA9E90C220A181855FD8BDB7F127BB12403B4D3B", + "key_indices": [0, 1, 2], + "nonce_indices": [0, 1, 2], + "msg_index": 0, + "signer_index": 1, + "comment": "Wrong signer" + }, + { + "sig": "FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEBAAEDCE6AF48A03BBFD25E8CD0364141", + "key_indices": [0, 1, 2], + "nonce_indices": [0, 1, 2], + "msg_index": 0, + "signer_index": 0, + "comment": "Signature exceeds group size" + } + ], + "verify_error_test_cases": [ + { + "sig": "68537CC5234E505BD14061F8DA9E90C220A181855FD8BDB7F127BB12403B4D3B", + "key_indices": [0, 1, 2], + "nonce_indices": [4, 1, 2], + "msg_index": 0, + "signer_index": 0, + "error": { + "type": "invalid_contribution", + "signer": 0, + "contrib": "pubnonce" + }, + "comment": "Invalid pubnonce" + }, + { + "sig": "68537CC5234E505BD14061F8DA9E90C220A181855FD8BDB7F127BB12403B4D3B", + "key_indices": [3, 1, 2], + "nonce_indices": [0, 1, 2], + "msg_index": 0, + "signer_index": 0, + "error": { + "type": "invalid_contribution", + "signer": 0, + "contrib": "pubkey" + }, + "comment": "Invalid pubkey" + } + ] +} diff --git a/bip-0327/vectors/tweak_vectors.json b/bip-0327/vectors/tweak_vectors.json new file mode 100644 index 0000000000..d0a7cfe832 --- /dev/null +++ b/bip-0327/vectors/tweak_vectors.json @@ -0,0 +1,84 @@ +{ + "sk": "7FB9E0E687ADA1EEBF7ECFE2F21E73EBDB51A7D450948DFE8D76D7F2D1007671", + "pubkeys": [ + "03935F972DA013F80AE011890FA89B67A27B7BE6CCB24D3274D18B2D4067F261A9", + "02F9308A019258C31049344F85F89D5229B531C845836F99B08601F113BCE036F9", + "02DFF1D77F2A671C5F36183726DB2341BE58FEAE1DA2DECED843240F7B502BA659" + ], + "secnonce": "508B81A611F100A6B2B6B29656590898AF488BCF2E1F55CF22E5CFB84421FE61FA27FD49B1D50085B481285E1CA205D55C82CC1B31FF5CD54A489829355901F703935F972DA013F80AE011890FA89B67A27B7BE6CCB24D3274D18B2D4067F261A9", + "pnonces": [ + "0337C87821AFD50A8644D820A8F3E02E499C931865C2360FB43D0A0D20DAFE07EA0287BF891D2A6DEAEBADC909352AA9405D1428C15F4B75F04DAE642A95C2548480", + "0279BE667EF9DCBBAC55A06295CE870B07029BFCDB2DCE28D959F2815B16F817980279BE667EF9DCBBAC55A06295CE870B07029BFCDB2DCE28D959F2815B16F81798", + "032DE2662628C90B03F5E720284EB52FF7D71F4284F627B68A853D78C78E1FFE9303E4C5524E83FFE1493B9077CF1CA6BEB2090C93D930321071AD40B2F44E599046" + ], + "aggnonce": "028465FCF0BBDBCF443AABCCE533D42B4B5A10966AC09A49655E8C42DAAB8FCD61037496A3CC86926D452CAFCFD55D25972CA1675D549310DE296BFF42F72EEEA8C9", + "tweaks": [ + "E8F791FF9225A2AF0102AFFF4A9A723D9612A682A25EBE79802B263CDFCD83BB", + "AE2EA797CC0FE72AC5B97B97F3C6957D7E4199A167A58EB08BCAFFDA70AC0455", + "F52ECBC565B3D8BEA2DFD5B75A4F457E54369809322E4120831626F290FA87E0", + "1969AD73CC177FA0B4FCED6DF1F7BF9907E665FDE9BA196A74FED0A3CF5AEF9D", + "FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEBAAEDCE6AF48A03BBFD25E8CD0364141" + ], + "msg": "F95466D086770E689964664219266FE5ED215C92AE20BAB5C9D79ADDDDF3C0CF", + "valid_test_cases": [ + { + "key_indices": [1, 2, 0], + "nonce_indices": [1, 2, 0], + "tweak_indices": [0], + "is_xonly": [true], + "signer_index": 2, + "expected": "E28A5C66E61E178C2BA19DB77B6CF9F7E2F0F56C17918CD13135E60CC848FE91", + "comment": "A single x-only tweak" + }, + { + "key_indices": [1, 2, 0], + "nonce_indices": [1, 2, 0], + "tweak_indices": [0], + "is_xonly": [false], + "signer_index": 2, + "expected": "38B0767798252F21BF5702C48028B095428320F73A4B14DB1E25DE58543D2D2D", + "comment": "A single plain tweak" + }, + { + "key_indices": [1, 2, 0], + "nonce_indices": [1, 2, 0], + "tweak_indices": [0, 1], + "is_xonly": [false, true], + "signer_index": 2, + "expected": "408A0A21C4A0F5DACAF9646AD6EB6FECD7F7A11F03ED1F48DFFF2185BC2C2408", + "comment": "A plain tweak followed by an x-only tweak" + }, + { + "key_indices": [1, 2, 0], + "nonce_indices": [1, 2, 0], + "tweak_indices": [0, 1, 2, 3], + "is_xonly": [false, false, true, true], + "signer_index": 2, + "expected": "45ABD206E61E3DF2EC9E264A6FEC8292141A633C28586388235541F9ADE75435", + "comment": "Four tweaks: plain, plain, x-only, x-only." + }, + { + "key_indices": [1, 2, 0], + "nonce_indices": [1, 2, 0], + "tweak_indices": [0, 1, 2, 3], + "is_xonly": [true, false, true, false], + "signer_index": 2, + "expected": "B255FDCAC27B40C7CE7848E2D3B7BF5EA0ED756DA81565AC804CCCA3E1D5D239", + "comment": "Four tweaks: x-only, plain, x-only, plain. If an implementation prohibits applying plain tweaks after x-only tweaks, it can skip this test vector or return an error." + } + ], + "error_test_cases": [ + { + "key_indices": [1, 2, 0], + "nonce_indices": [1, 2, 0], + "tweak_indices": [4], + "is_xonly": [false], + "signer_index": 2, + "error": { + "type": "value", + "message": "The tweak must be less than n." + }, + "comment": "Tweak is invalid because it exceeds group size" + } + ] +} From 47a25d15403bc50ba0c5b99382e0ebd9029fcc8d Mon Sep 17 00:00:00 2001 From: James O'Beirne Date: Wed, 22 Mar 2023 14:32:01 -0400 Subject: [PATCH 068/454] fixup! FLUification Adds AJ and Greg as co-authors --- .../batch-sweep.drawio.png | Bin bip-0345/opvault.drawio.png | Bin 0 -> 92563 bytes {bip-VAULT => bip-0345}/vaults-Basic.png | Bin bip-0345/vaults.drawio | 1113 +++++++++++++++++ bip-0345/withdrawal-comparison.drawio.png | Bin 0 -> 20720 bytes bip-VAULT/opvault-flow.drawio.png | Bin 51069 -> 0 bytes bip-VAULT/withdrawal-comparison.drawio.png | Bin 20724 -> 0 bytes bip-vaults.mediawiki | 692 ++++------ 8 files changed, 1387 insertions(+), 418 deletions(-) rename {bip-VAULT => bip-0345}/batch-sweep.drawio.png (100%) create mode 100644 bip-0345/opvault.drawio.png rename {bip-VAULT => bip-0345}/vaults-Basic.png (100%) create mode 100644 bip-0345/vaults.drawio create mode 100644 bip-0345/withdrawal-comparison.drawio.png delete mode 100644 bip-VAULT/opvault-flow.drawio.png delete mode 100644 bip-VAULT/withdrawal-comparison.drawio.png diff --git a/bip-VAULT/batch-sweep.drawio.png b/bip-0345/batch-sweep.drawio.png similarity index 100% rename from bip-VAULT/batch-sweep.drawio.png rename to bip-0345/batch-sweep.drawio.png diff --git a/bip-0345/opvault.drawio.png b/bip-0345/opvault.drawio.png new file mode 100644 index 0000000000000000000000000000000000000000..702189d156d0082416fcb1f8d33ca464558d766f GIT binary patch literal 92563 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 CzF+(R literal 0 HcmV?d00001 diff --git a/bip-VAULT/vaults-Basic.png b/bip-0345/vaults-Basic.png similarity index 100% rename from bip-VAULT/vaults-Basic.png rename to bip-0345/vaults-Basic.png diff --git a/bip-0345/vaults.drawio b/bip-0345/vaults.drawio new file mode 100644 index 0000000000..6f7fd4ebc2 --- /dev/null +++ b/bip-0345/vaults.drawio @@ -0,0 +1,1113 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/bip-0345/withdrawal-comparison.drawio.png b/bip-0345/withdrawal-comparison.drawio.png new file mode 100644 index 0000000000000000000000000000000000000000..8a76d20722d614c75ff804b5bdc487488bb79f66 GIT binary patch literal 20720 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

rN&aJp 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 diff --git a/bip-VAULT/withdrawal-comparison.drawio.png b/bip-VAULT/withdrawal-comparison.drawio.png deleted file mode 100644 index 320a57b044f9f3415e84d65d304541e055187744..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 20724 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 AtpET3 diff --git a/bip-vaults.mediawiki b/bip-vaults.mediawiki index d6da2bbf41..72f3f4fe57 100644 --- a/bip-vaults.mediawiki +++ b/bip-vaults.mediawiki @@ -1,25 +1,31 @@

-  BIP: xxxx
+  BIP: 345
   Layer: Consensus (soft fork)
   Title: OP_VAULT
   Author: James O'Beirne 
-  Comments-URI: https://github.com/bitcoin/bips/wiki/Comments:BIP-xxxx
+          Greg Sanders 
+          Anthony Towns 
+  Comments-URI: https://github.com/bitcoin/bips/wiki/Comments:BIP-0345
   Status: Draft
   Type: Standards Track
   Created: 2023-02-03
   License: BSD-3-Clause
   Post-History: 2023-01-09: https://lists.linuxfoundation.org/pipermail/bitcoin-dev/2023-January/021318.html [bitcoin-dev] OP_VAULT announcment
+                2023-03-01: https://lists.linuxfoundation.org/pipermail/bitcoin-dev/2023-March/021510.html [bitcoin-dev] BIP for OP_VAULT
 
== Introduction == This BIP proposes new tapscript opcodes, OP_VAULT and -OP_UNVAULT, that add consensus support for a specialized covenant. -These opcodes allow users to enforce a delay period before designated coins may -be spent to an arbitrary destination, with the exception of a prespecified -"recovery" path. At any time prior to final withdrawal, the coins can be spent to -the prespecified path. +OP_VAULT_RECOVER, that add consensus support for a specialized +covenant. These opcodes, in conjunction with +OP_CHECKTEMPLATEVERIFY +([https://github.com/bitcoin/bips/blob/master/bip-0119.mediawiki BIP-0119]), +allow users to enforce a delay period before designated coins may be spent to +an arbitrary destination, with the exception of a prespecified "recovery" path. +At any time prior to final withdrawal, the coins can be spent to the +prespecified path. === Motivation === @@ -80,7 +86,7 @@ timelocked coins for perpetuity or relying on a trusted third party. == Goals == -[[File:bip-VAULT/vaults-Basic.png|frame|center]] +[[File:bip-0345/vaults-Basic.png|frame|center]] Vaults in Bitcoin have been discussed formally since 2016 ([http://fc16.ifca.ai/bitcoin/papers/MES16.pdf MES16]) and informally since [https://web.archive.org/web/20160220215151/https://bitcointalk.org/index.php?topic=511881.0 2014]. The value of @@ -116,7 +122,7 @@ destinations, and fee management are all fixed. Funds must flow through a fixed intermediary to their final destination. Batch operations, which may be vital for successful recovery during fee spikes or short spend delay, are not possible. -[[File:bip-VAULT/withdrawal-comparison.drawio.png|frame|center]] +[[File:bip-0345/withdrawal-comparison.drawio.png|frame|center]] Having a "general" covenant mechanism that can encode arbitrary transactional state machines would allow us to solve these issues, but at the cost of complex @@ -149,74 +155,45 @@ This proposal is designed to be compatible with any future sighash modes (e.g. < == Design == -=== State machine === +In typical usage, a vault is created by encumbering coins under a +taptree [https://github.com/bitcoin/bips/blob/master/bip-0341.mediawiki (BIP-341)] +containing at least two leaves: one with an OP_VAULT-containing script that +facilitates the expected withdrawal process, and leaf another with +OP_VAULT_RECOVER which ensures the coins can be recovered +at any time prior to withdrawal finalization. -[[File:bip-VAULT/opvault-flow.drawio.png|frame|center]] +The rules of OP_VAULT ensure the timelocked, interruptible +withdrawal by allowing a spending transaction to replace the +OP_VAULT tapleaf with a prespecified script template, allowing for +some parameters to be set at spend (trigger) time. All other leaves in the +taptree must be unchanged, which preserves the recovery path as well as any +other spending conditions originally included in the vault. -The vault has a number of stages, some of them optional: - -* '''vault transaction''': encumbers some coins with an OP_VAULT script invocation. - -* '''trigger transaction''': spends one or more OP_VAULT inputs into an OP_UNVAULT output which carries forward the same recovery and delay parameters, along with a commitment to the proposed withdrawal target outputs. This publicly broadcasts the intent to withdraw to some specific set of outputs. This transaction may have an additional output which allocates some of the vault balance into a partial revault, which simply encumbers the revaulted portion of the value into the same scriptPubKey of the originating OP_VAULT output(s). - -* '''withdrawal transaction''': spends OP_UNVAULT trigger inputs into a compatible set of final withdrawal outputs per the target hash, after the trigger inputs have matured per the spend delay. The only authorization for this spend (aside from the relative timelock) is the content hash of the withdrawal outputs. - -* '''recovery transaction''': spends one or more OP_VAULT or OP_UNVAULT inputs, which can be done at any time prior to withdrawal confirmation, to the prespecified recovery path. This transaction can optionally require a witness satisfying a specified ''recovery authorization'' script, an optional scriptPubKey gating the initiation of recovery. The use of recovery authorization has certain trade-offs discussed later. - - -=== Parameters === - - - -The recovery parameters dictate both where funds can be swept to during a -recovery, and what kind of authorization (if any) is needed to initiate a -recovery. It is specified in the form - - -[] - - -The first component commits to the destination that vault funds can be swept to -at any point prior to the finalization of a withdrawal. - -The recovery scriptPubKey would usually correspond to a spending script that is -inconvenient to exercise but highly secure. - -The second component, the recovery authorization scriptPubKey, is optional. It -is a raw scriptPubKey that, if specified, must be satisfied to allow the input -to be recovered. The benefit of using this parameter will be discussed later. -If this component is not given, the de facto "authorization" is the reveal of -the preimage, i.e. the recovery path. +These tapleaf replacement rules, described more precisely below, ensure a +timelocked withdrawal, where the timelock is fixed by the original +OP_VAULT parameters, to a fixed set of outputs (via +OP_CHECKTEMPLATEVERIFY'''Why is OP_CHECKTEMPLATEVERIFY (BIP-119) relied upon for this proposal?''' During the withdrawal process, the proposed final destination for value being withdrawn must be committed to. OP_CTV is the simplest, safest way to commit the spend of some coins to a particular set of outputs. An earlier version of this proposal attempted to use a simpler, but similar method, of locking the spend of coins to a set of outputs, but this method introduced txid malleability.
Note that if some other method of locking spends to a particular set of outputs should be deployed, that method can be used in the OP_VAULT with no changes.
) which is chosen when the withdrawal +process is triggered. -Vaults which share the same recovery path can always be swept in batch operations, -which is an important practical aspect of managing large numbers of vaults. +While OP_CHECKTEMPLATEVERIFY is used in this proposal as the +preferred method to bind the proposed withdrawal to a particular set of final +outputs, OP_VAULT is composable with other (and future) opcodes to +facilitate other kinds of withdrawal processes. - +[[File:bip-0345/opvault.drawio.png|frame|center]] -The spend delay dictates the duration of blocks or time which must -elapse for the trigger OP_UNVAULT output to be claimable into the -withdrawal target outputs. Encoded as the least significant 23 bits of a -[https://github.com/bitcoin/bips/blob/master/bip-0068.mediawiki BIP-0068] style -relative locktime. -'''Trigger key''' +=== Transaction types === -The trigger key, committed to with , is used to -authorize the ''trigger transaction'' - an on-chain declaration to attempt a -withdrawal to a certain set of target outputs. +The vault has a number of stages, some of them optional: -This functions as the "normal" spending key, but if an attacker obtains access -to this key, the outcome is not catastrophic: any withdrawal attempt can be -interrupted (within the spend delay) and swept to the recovery path. +* '''vault transaction''': encumbers some coins into a Taproot structure that includes at least one OP_VAULT leaf and one OP_VAULT_RECOVER leaf. -The trigger key can be an arbitrary scriptPubKey so long as it represents a -valid witness program. OP_VAULT outputs which have the same -recovery params and spend delay can be spent into the same -OP_UNVAULT output for a batched withdrawal process. +* '''trigger transaction''': spends one or more OP_VAULT-tapleaf inputs into an output which is encumbered by a timelocked withdrawal to a fixed set of outputs, chosen at trigger time. This publicly broadcasts the intent to withdraw to some specific set of outputs.

The trigger transaction may have an additional output which allocates some of the vault balance into a partial "revault," which simply encumbers the revaulted portion of the value into the same scriptPubKey as the OP_VAULT-containing input(s) being spent. - +* '''withdrawal transaction''': spends the timelocked OP_CHECKTEMPLATEVERIFY trigger inputs into a compatible set of final withdrawal outputs per the CTV hash, after the trigger inputs have matured per the spend delay. Timelocked CTV transactions are the motivating usage of OP_VAULT, but any script template can be specified during the creation of the vault. -An arbitrary set of target withdrawal outputs that is specified as a parameter to OP_UNVAULT as a 32 byte tagged hash. The preimage is a list of destination output scriptPubKeys and amounts. If the trigger remains uncontested -- if it isn't swept to recovery before the spend delay elapses -- the vaulted funds may be spent into a compatible set of target outputs. +* '''recovery transaction''': spends one or more OP_VAULT_RECOVER-tapleaf inputs to the prespecified recovery path, which can be done at any point before the withdrawal transaction confirms. Each input can optionally require a witness satisfying a specified ''recovery authorization'' script, an optional script prefixing the OP_VAULT_RECOVER fragment. The use of recovery authorization has certain trade-offs discussed later. === Fee management === @@ -241,267 +218,144 @@ management mechanisms. == Specification == The tapscript opcodes OP_SUCCESS187 (0xbb) and -OP_SUCCESS188 (0xbc) are claimed to implement the -OP_VAULT and OP_UNVAULT rules, respectively. +OP_SUCCESS188 (0xbc) are constrained with new rules +to implement OP_VAULT and OP_VAULT_RECOVER, +respectively. === OP_VAULT evaluation === -==== Witness program ==== - When evaluating OP_VAULT (OP_SUCCESS187, 0xbb), the expected format of the stack, shown top to bottom, is: - - - + + +[ n leaf-update script data items ... ] + + where -* is a 32 byte tagged hash of the scriptPubKey used to authorize the spend of this output into an OP_UNVAULT trigger outputBecause the trigger scriptPubKey is committed to using a hash, witness version upgradeability for the trigger key is preserved. -** tagged_hash("VaultTriggerSPK", ), per BIP-0340. -** If this value is not 32 bytes, script execution when spending this output MUST fail and terminate immediately. +* is a data push of 0 or more bytes containing a script fragment. +** In conjunction with the leaf-update data items, it dictates the tapleaf script in the output taptree that will replace the one currently executing. -* is a CScriptNum-encoded number (up to 4 bytes) -** It is interpreted as the least significant 23 bits of a [https://github.com/bitcoin/bips/blob/master/bip-0068.mediawiki BIP-0068] relative timelock. +* is a CScriptNum-encoded number indicating how many leaf-update script items should be popped off the stack. ** If this value does not decode to a valid CScriptNum, script execution when spending this output MUST fail and terminate immediately. ** If this value is less than 0, script execution when spending this output MUST fail and terminate immediately. +** If fewer than + 2 items are on the stack, script execution when spending this output MUST fail and terminate immediately. -* is a variable length data push, consisting of two components: -*# a 32 byte tagged hash, the ''recovery sPK hash''Because the recovery scriptPubKey is committed to with a hash, witness version upgradeability is preserved., committing to the scriptPubKey which coins may be recovered to -*#* tagged_hash("VaultRecoverySPK", ) from the [https://github.com/bitcoin/bips/blob/master/bip-0340/reference.py BIP-0340 reference code]. -*# 0 or more bytes that optionally specify a scriptPubKey that needs to be satisfied to authorize the recovery transaction, referred to as . -** If is less than 32 bytes, script execution when spending this output MUST fail and terminate immediately. - -==== Witness stack ==== - -After the witness program is parsed, it must be determined whether this input -is being spent towards a recovery. +* The following stack items are popped off the stack and prefixed as push-data arguments to the to construct the expected tapleaf replacement script. +** If there are fewer than + 2 items on the stack, script execution when spending this output MUST fail and terminate immediately. -Witness stack shown top to bottom: - - - -[other potential witness stack items ...] - - -where - -* is an integer indicating which output, if any, is a recovery output. -** If this value cannot be decoded as a CScriptNum and cast to an integer, script execution MUST fail and terminate immediately. -** If this value is less than -1, script execution MUST fail and terminate immediately. -** If this value is greater than or equal to 0, this spend is a recovery transaction and this value denotes the recovery output that corresponds to this vault input. -* The parse of the other stack items depends on whether or not this is a recovery spend. - -==== OP_VAULT evaluation for recovery spend ==== +* is a CScriptNum-encoded number indicating the index of the output which, in conjunction with an optional revault output, carries forward the value of this input, and has an identical taptree aside from the currently executing leaf. +** If this value does not decode to a valid CScriptNum, script execution when spending this output MUST fail and terminate immediately. +** If this value is less than 0 or is greater than or equal to the number of outputs, script execution when spending this output MUST fail and terminate immediately. -* If the recovery output does not have an nValue greater than or equal to this input's amount, the script MUST fail and terminate immediately. -* (Deferred'''What is a deferred check and why does this proposal require them for correct script evaluation?''' A deferred check is a validation check that is executed only after all input scripts have been validated, and is based on aggregate information collected during each input's EvalScript run.

Currently, the validity of each input is (usually) checked concurrently across all inputs in a transaction. Because this proposal allows batching the spend of multiple vault inputs into a single recovery or withdrawal output, we need a mechanism to ensure that all expected values per output can be summed and then checked. This necessitates the introduction of an "aggregating" set of checks which can only be executed after each input's script is evaluated. Note that similar functionality would be required for batch input validation or cross-input signature aggregation.
) if the recovery output does not have an nValue equal to the sum of all OP_VAULT/OP_UNVAULT inputs with a corresponding recovery sPK hash, the transaction validation MUST fail.'''How do recovery transactions pay for fees?''' If the recovery is unauthorized, fees are attached either via CPFP with an ephemeral anchor or as inputs which are solely spent to fees (i.e. no change output). If the recovery is authorized, fees can be attached in any manner, e.g. unrelated inputs and outputs or CPFP via anchor. +* is a CScriptNum-encoded number optionally indicating the index of an output which, in conjunction with the trigger output, carries forward the value of this input, and has an identical scriptPubKey to the current input. +** If this value does not decode to a valid CScriptNum, script execution when spending this output MUST fail and terminate immediately. +** If this value is greater than or equal to the number of outputs, script execution when spending this output MUST fail and terminate immediately. -The stack may now have 0 or more elements. Any items on the stack will be used to verify the witness program, if any. +After the stack is parsed, the following validation checks are performed: -* If is not null: -** If VerifyWitnessProgram(, , ...) fails, the script MUST fail and terminate immediately. -** (This validates that the recovery has been authorized.) +* Let the output designated by be called ''triggerOut''. +* If the scriptPubKey of ''triggerOut'' is not a witness program of the same version as the currently executing script, script execution MUST fail and terminate immediately. +* Let the script constructed by taking the and prefixing it with minimally-encoded data pushes of the leaf-update script data items be called the ''leaf-update-script''. +** The leaf-update data items will be in the same order in the ''leaf-update-script'' as they appeared on the stack. +* If the scriptPubKey of ''triggerOut'' is not a taptree that is identical to that of the current input, but with the current leaf script substituted for ''leaf-update-script'', script execution when spending this output MUST fail and terminate immediately. +** Note: the parity bit of the resulting taproot is allowed to vary. +* Let the output designated by (if the index value is non-negative) be called ''revaultOut''. +* If the scriptPubKey of ''revaultOut'' is not equal to the scriptPubKey of the input being spent, script execution when spending this output MUST fail and terminate immediately. +* If the sum of the amounts of ''triggerOut'' and ''revaultOut'' (if any) are not greater than or equal to the value of this input, script execution when spending this output MUST fail and terminate immediately. +* (Deferred'''What is a deferred check and why does this proposal require them for correct script evaluation?''' A deferred check is a validation check that is executed only after all input scripts have been validated, and is based on aggregate information collected during each input's EvalScript run.

Currently, the validity of each input is (usually) checked concurrently across all inputs in a transaction. Because this proposal allows batching the spend of multiple vault inputs into a single recovery or withdrawal output, we need a mechanism to ensure that all expected values per output can be summed and then checked. This necessitates the introduction of an "aggregating" set of checks which can only be executed after each input's script is evaluated. Note that similar functionality would be required for batch input validation or cross-input signature aggregation.
) the nValue of ''triggerOut'', plus the nValue of ''revaultOut'' if one exists, must equal the sum of all vault inputs which cite it as their corresponding trigger output. If these values are not equal, the script MUST fail and terminate immediately. If none of the conditions fail, a single true value (0x01) is left on the stack. -==== OP_VAULT evaluation for withdrawal trigger ==== - -Else, if it has been determined that the spend is not within a recovery -transaction, it must be evaluated for eligibility as a withdrawal trigger -spend. - -===== Witness stack ===== - -There must be at least 4 items on the stack (shown top to bottom): - - - - - - [...] - - -If the witness stack consists of fewer than four items the script MUST fail and -terminate immediately. - -(Note: in practice, the witness stack will have included the other items necessary to reveal -a witness v1 (or greater) script-path spend, per [https://github.com/bitcoin/bips/blob/master/bip-0341.mediawiki#user-content-Constructing_and_spending_Taproot_outputs BIP-0341]. This is demonstrated in detail in [[#Transaction examples|the transaction examples section]].) - -The items on the stack must be validated as follows: - -* is a CScriptNum of up to 4 bytes. -** It indicates the vout index of this input's corresponding OP_UNVAULT output. -*** Validation rules for this output are described below. -** If this value does not decode as a valid CScriptNum value, the script MUST fail and terminate immediately. -** If this value does not correspond to a valid output in the spending transaction, the script MUST fail and terminate immediately. - -* is a 32 byte data push. -** It is the hash of the proposed withdrawal target output set, defined by target_outputs_hash(outputs) below. Note that this value is duplicated here.'''Why, when spending an OP_VAULT output into a trigger, does the target hash need to be duplicated on the witness stack?''' The target hash exists in the OP_UNVAULT output script, likely behind a taproot pubkey. Its presence is required on the witness stack also so that the expected taproot pubkey for the OP_UNVAULT output can be constructed for comparison. -** If this value is not 32 bytes, the script MUST fail and terminate immediately. - -* is a variable length data push. -** It must be the scriptPubKey that is the preimage to the specified in the spent OP_VAULT input. -** If this value does not tagged-hash to supplied by the OP_VAULT parameter, the script MUST fail and terminate immediately. -*** Verify tagged_hash("VaultTriggerSPK", ) == -** If this value does not correspond to a valid witness program, the script MUST fail and terminate immediately. - -* the remaining elements serve as the witness stack to satisfy the witness program. -** If VerifyWitnessProgram(, , ...) fails, the script MUST fail and terminate immediately. -** (This validates that the withdrawal trigger has been authorized.) - -===== Transaction outputs validation ===== - -Once the contents of the witness stack have been parsed and validated, the transaction outputs must be checked. - -First, we must check for a ''revault output'': an output in the trigger transaction whose -scriptPubKey exactly matches that of the OP_VAULT input being -spent. Its presence is optional. - -For each vault input citing a particular , the output -located at vout[] (the "trigger output") must: - -* have as its scriptPubKey a witness program with a single OP_UNVAULT tapscript, having the internal x-only key 0x0250929b74c1a04954b78b4b6035e97a5e078a5a0f28ec96d547bfee9ace803ac0, per the NUMS point mentioned in [https://github.com/bitcoin/bips/blob/master/bip-0341.mediawiki#constructing-and-spending-taproot-outputs BIP-0341].'''Why must the OP_UNVAULT taproot use a predefined NUMS point as its internal key?''' This ensures that an OP_UNVAULT trigger output is verifiable as expected. It also ensures that it is spendable only by the conditions of the vault. -** If the witness program has a version less than 1, the script MUST fail and terminate immediately. -** If the witness program has a version greater than 1, the script MUST succeed to enable upgradeability. -** If the witness program has a version of 1 and the scriptPubKey of the output does not match the expected scriptPubKey, as computed by creating a taproot output using the cited NUMS point and a single tapscript spend condition of the form
OP_UNVAULT,
the script MUST fail and terminate immediately. -** Witness versions greater than 1 are allowed for upgradeability. - -* If there does not exist a revault output in the transaction for this input: -** (deferred) the nValue of the trigger output must equal the sum of all vault inputs which cite it as their corresponding trigger output. -*** If these values are not equal, the script MUST fail and terminate immediately. -* else (if there does exist a revault output for this input): -** (deferred) the nValues of the trigger output and the revault output must sum to the sum of all vault inputs which both -*** cite this trigger output as the trigger-vout-idx and -*** have a scriptPubKey identical to the revault output's. -** If these values are not equal, the script MUST fail and terminate immediately. - -If none of the conditions above results in a failure of the script interpreter, the -stack will consist of a single true value (0x01). - -The above amount check can be expressed in Python as: - - - -spending_tx: CTransaction -vault_inputs: [CTxIn] = [inp for inp in spending_tx.vin if inp.is_OP_VAULT] - -"Where we'll accumulate the expected totals for each vault input." -vault_totals_for_outputs: dict[(int, int), int] = defaultdict(0) - -"Build the expected totals." -for vault_in in vault_inputs: - maybe_revault_idx = find_revault_for_vault(vault_in) - vault_total_for_outputs[(vault_in.trigger_vout_idx, maybe_revault_idx)] += vault_in.nValue - - -"Check the expected totals against outputs." -for (out_idx, maybe_revault_idx), expected_amount in vault_totals_for_outputs.items(): - total = spending_tx.vout[out_idx].nValue - - if maybe_revault_idx: - total += spending_tx.vout[maybe_revault_idx] - - if total != expected_amount: - FAIL_AND_TERMINATE_SCRIPT() - - -def find_revault_for_vault(vault_in) -> int: - """Find the index of a revault output for a particular vault input, if one exists.""" - for i, out in enumerate(spending_tx.vout): - if out.scriptPubKey == vault_in.scriptPubKey: - return i - return None - - -=== OP_UNVAULT evaluation === - -==== Witness program ==== +=== OP_VAULT_RECOVER evaluation === -When evaluating OP_UNVAULT (OP_SUCCESS188, -0xbc), the witness program is pushed onto the stack for the -following result (stack shown top to bottom): +When evaluating OP_VAULT_RECOVER (OP_SUCCESS188, +0xbb), the expected format of the stack, shown top to bottom, is: -OP_UNVAULT (*) being evaluated - - - + + where -* is validated exactly as described in [[#witness-program|the above OP_VAULT section]]. -* is validated exactly as described in [[#witness-program|the above OP_VAULT section]]. -* is a 32 byte data push. -** If it is not equal to 32 bytes, the script MUST fail and terminate immediately. - - -==== Check for recovery ==== - -A check is performed to determine if this input is being spent within the context of -a recovery transaction, exactly as in [[#check-for-recovery|the OP_VAULT evaluation described above]]. - - -==== OP_UNVAULT evaluation for recovery spend ==== - -This is identical to the [[#op_vault-evaluation-for-recovery-spend|OP_VAULT case described above]]. - - -==== OP_UNVAULT evaluation for withdrawal ==== - -When spending an OP_UNVAULT input into a withdrawal target, no witness stack is required. - -* is used to check whether the withdrawal of the input has matured. -** If the input's relative timelock check, as described in [https://github.com/bitcoin/bips/blob/master/bip-0112.mediawiki BIP-0112] (using this value as "the top item on the stack") fails, the script MUST fail and terminate immediately. -*** The same CheckSequence() code path is used as for [https://github.com/bitcoin/bips/blob/master/bip-0112.mediawiki BIP-0112]. - -* The transaction outputs are then checked to verify that the withdrawal outputs are as expected. -** If target_outputs_hash(spending_tx.vout) != per the algorithm defined below, the script MUST fail and terminate immediately. +* is a 32-byte data push. +** If this is not 32 bytes in length, script execution when spending this output MUST fail and terminate immediately. +* is a CScriptNum-encoded number indicating the index of the recovery output. +** If this value does not decode to a valid CScriptNum, script execution when spending this output MUST fail and terminate immediately. +** If this value is less than 0 or is greater than or equal to the number of outputs, script execution when spending this output MUST fail and terminate immediately. - -def target_outputs_hash(vout: [CTxOut]) -> bytes: - return hash256(b"".join(serialize_txout(out) for out in vout)) +After the stack is parsed, the following validation checks are performed: -def serialize_txout(txo: CTxOut) -> bytes: - spk: bytes = txo.scriptPubKey - return struct.pack(" +* Let the output at index be called ''recoveryOut''. +* If the scriptPubKey of ''recoveryOut'' does not have a tagged hash equal to (tagged_hash("VaultRecoverySPK", recoveryOut.scriptPubKey) == recovery-sPK-hash, where tagged_hash() is from the [https://github.com/bitcoin/bips/blob/master/bip-0340/reference.py BIP-0340 reference code]), script execution when spending this output MUST fail and terminate immediately. +* If ''recoveryOut'' does not have an nValue greater than or equal to this input's amount, the script MUST fail and terminate immediately. +* (Deferred) if ''recoveryOut'' does not have an nValue equal to the sum of all OP_VAULT_RECOVER-spent inputs with a corresponding recovery-sPK-hash, the transaction validation MUST fail.'''How do recovery transactions pay for fees?''' If the recovery is unauthorized, fees are attached either via CPFP with an ephemeral anchor or as inputs which are solely spent to fees (i.e. no change output). If the recovery is authorized, fees can be attached in any manner, e.g. unrelated inputs and outputs or CPFP via anchor. -If the above conditions do not fail, a single true value (0x01) is pushed to the stack. +If none of the conditions fail, a single true value (0x01) is left on the stack. == Policy changes == In order to prevent possible pinning attacks, recovery transactions must be replaceable. -* When validating an OP_VAULT/OP_UNVAULT input being spent towards a recovery, the script must FAIL (by policy, not consensus) and terminate immediately if both'''Why are recovery transactions required to be replaceable?''' In the case of unauthorized recoveries, an attacker may attempt to pin recovery transactions by broadcasting a "rebundled" version with a low fee rate. Vault owners must be able to overcome this with replacement. In the case of authorized recovery, if an attacker steals the recovery authorization key, the attacker may try to pin the recovery transaction during theft. Requiring replaceability ensures that the owner can always raise the fee rate of the recovery transaction, even if they are RBF rule #3 griefed in the process. +* When validating an OP_VAULT_RECOVER input being spent, the script must FAIL (by policy, not consensus) and terminate immediately if both'''Why are recovery transactions required to be replaceable?''' In the case of unauthorized recoveries, an attacker may attempt to pin recovery transactions by broadcasting a "rebundled" version with a low fee rate. Vault owners must be able to overcome this with replacement. In the case of authorized recovery, if an attacker steals the recovery authorization key, the attacker may try to pin the recovery transaction during theft. Requiring replaceability ensures that the owner can always raise the fee rate of the recovery transaction, even if they are RBF rule #3 griefed in the process. *# the input is not marked as opt-in replaceable by having an nSequence number less than 0xffffffff - 1, per [https://github.com/bitcoin/bips/blob/master/bip-0125.mediawiki BIP-0125], and *# the version of the recovery transaction has an nVersion other than 3. -In order to prevent pinning attacks in the case of unauthorized recovery, the output structure of unauthorized recovery -transaction is limited. +If the script containing OP_VAULT_RECOVER is 34 bytes or less34 bytes is the length of a recovery script that consists solely of OP_VAULT_RECOVER., let +it be called "unauthorized," because there is no script guarding the recovery +process. In order to prevent pinning attacks in the case of unauthorized +recovery - since the spend of the input (and the structure of the +transaction) is not authorized by a signed signature message - the output structure of +unauthorized recovery transaction is limited. -* If (as determined from ) is null, the recovery transaction MUST (by policy) abide by the following constraints: +* If the recovery is unauthorized, the recovery transaction MUST (by policy) abide by the following constraints: ** If the spending transaction has more than two outputs, the script MUST fail and terminate immediately. -** If the spending transaction has two outputs, and the output not the recovery output is not an ephemeral anchor, the script MUST fail and terminate immediately.'''Why can unauthorized recoveries only process a single recovery path?''' Because there is no signature required for unauthorized recoveries, if additional outputs were allowed, someone observing a recovery in the mempool would be able to rebundle and broadcast the recovery with a lower fee rate. +** If the spending transaction has two outputs, and the output which is not ''recoveryOut'' is not an [https://github.com/instagibbs/bips/blob/ephemeral_anchor/bip-ephemeralanchors.mediawiki ephemeral anchor], the script MUST fail and terminate immediately.'''Why can unauthorized recoveries only process a single recovery path?''' Because there is no signature required for unauthorized recoveries, if additional outputs were allowed, someone observing a recovery in the mempool would be able to rebundle and broadcast the recovery with a lower fee rate. == Implementation == -A sample implementation is available [https://github.com/jamesob/bitcoin/tree/2023-01-opvault here], with an associated [https://github.com/bitcoin/bitcoin/pull/26857 pull request]. +A sample implementation is available on bitcoin-inquisition [https://github.com/jamesob/bitcoin/tree/2023-01-opvault-inq here], with an associated [https://github.com/bitcoin-inquisition/bitcoin/pull/21 pull request]. + +== Applications == -== End use == +The specification above, perhaps surprisingly, does not cover how a relative timelocked withdrawal process with a fixed target is implemented. The tapleaf update semantics specified in OP_VAULT as well as the output-based authorization enabled by OP_VAULT_RECOVER can be used to implement a vault, but they are incomplete without two other pieces: -=== Creating an OP_VAULT output === +* a way to enforce relative timelocks, like OP_CHECKSEQUENCEVERIFY, and +* a way to enforce that proposed withdrawals are ultimately being spent to a precise set of outputs, like OP_CHECKTEMPLATEVERIFY. + +These two pieces are combined with the tapleaf update capabilities of +OP_VAULT to create a vault, described below. + +=== Creating a vault === In order to vault coins, they must be spent into a witness v1'''Can OP_VAULT be used with a future witness version (greater than 1)?''' Yes, however use of yet to be defined witness versions is discouraged, since such a usage makes the coins spendable by anyone. scriptPubKey -that contains a Tapscript spending condition of the form +that contains a taptree of the form - OP_VAULT +tr(, + leaves = { + recover: + OP_VAULT_RECOVER, + + trigger: + OP_CHECKSIGVERIFY (i) + 2 $leaf-update-script-body OP_VAULT, (ii) + + ... [ possibly other leaves ] + } +) +where +* $leaf-update-script-body is, for example, OP_CHECKSEQUENCEVERIFY OP_DROP OP_CHECKTEMPLATEVERIFY. +** This is one example of a trigger script, but ''any'' script fragment can be used, allowing the creation of different types of vaults. For example, you could use OP_CHECKSEQUENCEVERIFY OP_DROP OP_CHECKSIG to do a time-delayed transfer of the coins to another key. This also future-proofs OP_VAULT for future scripting capabilities. +* The script fragment in (i) is called the "trigger authorization," because it gates triggering the withdrawal. This can be done in whatever manner the wallet designer would like. +* The script fragment in (ii) is the incomplete OP_VAULT invocation - it will be completed once the rest of the parameters (the CTV target hash, trigger vout index, and revault vout index) are provided by the trigger transaction witness. Typically, the internal key for the vault taproot output will be specified so that it is controlled by the same descriptor as the recovery path, which @@ -510,24 +364,84 @@ output to the recovery path. This has the potential advantage of recovering the coin without ever revealing it was a vault. Otherwise, the internal key can be chosen to be an unspendable NUMS point to -force tapscript execution of the OP_VAULT specification. +force execution of the taptree contents. + +=== Triggering a withdrawal === + +To make use of the vault, and spend it towards some output, we construct a spend +of the above tr() output that simply replaces the "trigger" leaf with the +full leaf-update script (in this case, a timelocked CTV script): + + +Witness stack: + +- (-1 if none) +- +- +- +- [ "trigger" leaf script contents ] +- [ taproot control block prompting a script-path spend to "trigger" leaf ] + +Output scripts: + +[ + tr(, + leaves = { + recover: + OP_VAULT_RECOVER, <-- unchanged + + trigger: + + OP_CHECKSEQUENCEVERIFY OP_DROP OP_CHECKTEMPLATEVERIFY <-- changed per the + leaf-update + rules of OP_VAULT + ... [ possibly other leaves ] + } + ), + + [ optional revault output with the + same sPK as the original vault output ], +] + + +OP_VAULT has allowed the taptree to be transformed so that the trigger leaf +becomes a timelocked CTV script, which is what actually facilitates the announced +withdrawal. The withdrawal is interruptible by the recovery path because the +"recover" leaf is preserved exactly from the original taptree. + +Note that the CTV hash is specified at spend time using the witness stack, and +"locked in" via the OP_VAULT spend rules which assert its existence in the output. + +The vault funds can be recovered at any time prior to the spend of the +timelocked CTV script by way of a script-path spend using the "recover" leaf. === Recovery authorization === -When configuring a vault, the user must decide if they want to have the recovery process gated by the optional recovery authorization scriptPubKey. The choice is left to the user because it entails trade-offs. +When configuring a vault, the user must decide if they want to have the +recovery process gated by a script fragment prefixing the +OP_VAULT_RECOVER instruction in the "recover" leaf. Its use +entails trade-offs. ==== Unauthorized recovery ==== -Unauthorized recovery simplifies vault use in that recovery never requires additional information aside from the location of the vault outpoints and the recovery path - the "authorization" is simply the reveal of the recovery path. +Unauthorized recovery simplifies vault use in that recovery never requires additional information aside from the location of the vault outpoints and the recovery path - the "authorization" is simply the reveal of the recovery path, i.e. the preimage of . But because this reveal is the only authorization necessary to spend the vault coins to recovery, the user must expect to recover all such vaults at once, since an observer can replay this recovery (provided they know the outpoints). -Additionally, unauthorized recovery across multiple distinct recovery paths cannot be batched, and fee control is more constrained: because the output structure is limited for unauthorized recovery, fee management relies either on inputs which are completely spent to fees or the use of the optional ephemeral anchor and package relay. +Additionally, unauthorized recovery across multiple distinct recovery paths +cannot be done in the same transaction, and fee control is more constrained: +because the output structure is limited for unauthorized recovery, fee +management relies either on inputs which are completely spent to fees or the +use of the optional ephemeral anchor and package relay. + +These limitations are to avoid pinning attacks. ==== Authorized recovery ==== -With authorized recovery, the user must keep track of an additional piece of information: how to solve the recovery authorization scriptPubKey when recovery is required. If this key is lost, the user will be unable to initiate the recovery process for their coins. If an attacker obtains the recovery key, they may grief the user during the recovery process by constructing a low fee rate recovery transaction and broadcasting it (though they will not be able to pin because of the replaceability requirement on recovery transactions). +With authorized recovery, the user must keep track of an additional piece of information: how to solve the recovery authorization script fragment when recovery is required. + +If this key is lost, the user will be unable to initiate the recovery process for their coins. If an attacker obtains the recovery key, they may grief the user during the recovery process by constructing a low fee rate recovery transaction and broadcasting it (though they will not be able to pin because of the replaceability requirement on recovery transactions). However, authorized recovery configurations have significant benefits. Batched recoveries are possible for vaults with otherwise incompatible recovery parameters. Fee management is much more flexible, since authorized recovery transactions are "free form" and unrelated inputs and outputs can be added, potentially to handle fees. @@ -542,24 +456,36 @@ recovery path key itself. === Address reuse and recovery === When creating a vault, four factors affect the resulting P2TR address: -# The internal key (likely belonging to the recovery wallet) -# The recovery parameters -# The spend delay -# The trigger scriptPubKey - -Aside from the spend delay, the end user has the option of varying the other three parameters along descriptors in order to avoid reusing vault addresses without affecting key management. - -Worth noting is that when using unauthorized recovery, the reveal of the recovery scriptPubKey will allow any observer to initiate the recovery process for any vault with matching recovery params, provided they are able to locate the vault outpoints. As a result, it is recommended to expect that '''all outputs sharing an identical unauthorized should be recovered together'''. - -This situation can be avoided with a comparable key management model by varying the generation of each vault's recovery scriptPubKey along a single descriptor, but note that (when configured for unauthorized recovery), this will prevent batched recovery. - -==== Recommendation: vary the internal key ==== - -The recommended mode of use is to keep recovery parameters identical across vaults which should be recovered in batch, but vary the internal key for each vault output along a single descriptor so that no address reuse is necessary. +# The internal pubkey (likely belonging to the recovery wallet) +# The recovery leaf +# The trigger leaf +# Any other leaves that exist in the taptree + +The end user has the option of varying certain contents along descriptors in +order to avoid reusing vault addresses without affecting key management, e.g. +the trigger authorization pubkeys. + +Note that when using unauthorized recovery, the reveal of the +recovery scriptPubKey will allow any observer to initiate the recovery process +for any vault with matching recovery params, provided they are able to locate +the vault outpoints. As a result, it is recommended to expect that +'''all outputs sharing an identical unauthorized should be recovered together'''. + +This situation can be avoided with a comparable key management model by varying +the generation of each vault's recovery scriptPubKey along a single descriptor, +but note that this will prevent recovering multiple separate vaults into a single +recovery output. + +Varying the internal pubkey will prevent batching the trigger of multiple vault +inputs into a single trigger output; consequently it is recommended that users +instead vary some component of the trigger leaf script if address reuse is +undesirable. Users could vary the trigger pubkey along a descriptor, keeping +the recovery path and internal-pubkey the same, which both avoids reusing +addresses and allows batched trigger and recovery operations. ==== Recommendation: generate new recovery addresses for new trigger keys ==== -If using unauthorized recovery, it is recommended that you do not share literal recovery paths +If using unauthorized recovery, it is recommended that you do not share recovery scriptPubKeys across separate trigger keys. If one trigger key is compromised, that will necessitate the (unauthorized) recovery of all vaults with that trigger key, which will reveal the recovery path preimage. This means that an observer might be able to initiate recovery for vaults controlled by an uncompromised @@ -567,33 +493,36 @@ trigger key. ==== Fee management ==== -Fees can be managed in a variety of ways, but it's worth noting that both trigger and recovery transactions must preserve the total value of vault inputs, so vaulted values cannot be repurposed to pay for fees. This does not apply to the withdrawal transaction, which can allocate value arbitrarily. - -In the case of vaults that use recovery authorization, all transactions can "bring their own fees" in the form of unrelated inputs and outputs. These transactions are also free to specify ephemeral anchors, once the related relay policies are deployed. This means that vaults using recovery authorization have no dependence on the deploy of v3 relay policy. - -In the case of vaults that do not use recovery authorization, the recovery transaction relies on the use of either fully-spent fee inputs or an ephemeral anchor output. This means that vaults which do not use recovery authorization are essentially dependent on v3 transaction relay policy being deployed. +Fees can be managed in a variety of ways, but it's worth noting that both +trigger and recovery transactions must preserve the total value of vault +inputs, so vaulted values cannot be repurposed to pay for fees. This does not +apply to the withdrawal transaction, which can allocate value arbitrarily. -==== Mixing input types ==== - -OP_VAULT/OP_UNVAULT outputs can be spent -into a recovery transaction together. Script execution works identically for -both types of outputs. - -[[File:bip-VAULT/batch-sweep.drawio.png|frame|center]] +In the case of vaults that use recovery authorization, all transactions can +"bring their own fees" in the form of unrelated inputs and outputs. These +transactions are also free to specify ephemeral anchors, once the related relay +policies are deployed. This means that vaults using recovery authorization have +no dependence on the deploy of v3 relay policy. +For vaults using unauthorized recovery, the recovery +transaction relies on the use of either fully-spent fee inputs or an ephemeral +anchor output. This means that vaults which do not use recovery authorization +are essentially dependent on v3 transaction relay policy being deployed. === Batching === ==== During trigger ==== -OP_VAULT outputs with the same recovery-params and spend-delay can -be triggered into the same OP_UNVAULT output, creating a batched -withdrawal trigger. This is allowed regardless of the - values of each input, allowing the trigger keys -to differ. +OP_VAULT outputs with the same taptree, aside from slightly +different trigger leaves, can be batched together in the same withdrawal +process. Two "trigger" leaves are compatible if they have the same +OP_VAULT arguments. + +Note that this allows the trigger authorization -- the script prefixing the +OP_VAULT invocation -- to differ while still allowing batching. Trigger transactions can act on multiple incompatible OP_VAULT -input sets, provided each set has a suitable associated OP_UNVAULT +input sets, provided each set has a suitable associated ''triggerOut'' output. Since SIGHASH_DEFAULT can be used to sign the trigger @@ -602,141 +531,68 @@ facilitate fee management or the batch withdrawal of incompatible vaults. ==== During withdrawal ==== -During final withdrawal, multiple unrelated OP_UNVAULT outputs can -be used towards the same withdrawal transaction provided that they share -identical parameters. This facilitates -batched withdrawals. +During final withdrawal, multiple trigger outputs can be used towards the same +withdrawal transaction provided that they share identical + parameters. This facilitates batched +withdrawals. ==== During recovery ==== -OP_VAULT/OP_UNVAULT outputs with the same recovery -scriptPubKey hash can be recovered into the same output. +OP_VAULT_RECOVER outputs with the same +can be recovered into the same output. Recovery-incompatible vaults which have authorized recovery can be recovered in -the same transaction, so long as each set (grouped by recovery scriptPubKey -hash) has a suitable associated recovery output. This means that unrelated -recoveries controlled by the same owner can benefit from sharing common fee -management. +the same transaction, so long as each set (grouped by +) has an associated ''recoveryOut''. This allows +unrelated recoveries to share common fee management. === Watchtowers === -The value of vaults is contingent upon having monitoring in place that will alert the owner when unexpected spends are taking place. This can be done in a variety of ways, with varying degrees of automation and trust in the watchtower. +The value of vaults is contingent upon having monitoring in place that will +alert the owner when unexpected spends are taking place. This can be done in a +variety of ways, with varying degrees of automation and trust in the +watchtower. -In the maximum-trust case, the watchtower can be fully aware of all vaulted coins and has the means to initiate the recovery process if spends are not pre-reported to the watchtower. +In the maximum-trust case, the watchtower can be fully aware of all vaulted +coins and has the means to initiate the recovery process if spends are not +pre-reported to the watchtower. -In the minimum-trust case, the user can supply a probabilistic filter of which coins they wish to monitor; the watchtower would then alert the user if any coins matching the filter move, and the user would be responsible for ignoring false positives and handling recovery initiation. +In the minimum-trust case, the user can supply a probabilistic filter of which +coins they wish to monitor; the watchtower would then alert the user if any +coins matching the filter move, and the user would be responsible for ignoring +false positives and handling recovery initiation. === Script descriptors === Script descriptors for vault-related outputs will be covered in a subsequent BIP. - == Deployment == -TBD +Activation mechanism is to be determined. + +This BIP should be deployed concurrently with BIP-0119 to enable full use of vaults. == Backwards compatibility == -OP_VAULT and OP_UNVAULT replace, respectively, the witness v1-only opcodes OP_SUCCESS187 and OP_SUCCESS188 with -stricter verification semantics. Consequently, scripts using those opcodes which previously were valid will cease to be valid with this change. +OP_VAULT and OP_VAULT_RECOVER replace, respectively, +the witness v1-only opcodes OP_SUCCESS187 and OP_SUCCESS188 with stricter +verification semantics. Consequently, scripts using those opcodes which +previously were valid will cease to be valid with this change. -Stricter verification semantics for an OP_SUCCESSx opcode are a soft fork, so existing software will be fully functional without upgrade except for mining and block validation. +Stricter verification semantics for an OP_SUCCESSx opcode are a soft fork, so +existing software will be fully functional without upgrade except for mining +and block validation. Backwards compatibility considerations are very comparable to previous -deployments for OP_CHECKSEQUENCEVERIFY and OP_CHECKLOCKTIMEVERIFY (see [https://github.com/bitcoin/bips/blob/master/bip-0065.mediawiki BIP-0065] -and [https://github.com/bitcoin/bips/blob/master/bip-0112.mediawiki BIP-0112]). +deployments for OP_CHECKSEQUENCEVERIFY and OP_CHECKLOCKTIMEVERIFY (see +[https://github.com/bitcoin/bips/blob/master/bip-0065.mediawiki BIP-0065] and +[https://github.com/bitcoin/bips/blob/master/bip-0112.mediawiki BIP-0112]). == Rationale == -== Transaction examples == - - -=== Basic creation and withdrawal === - - - -Recovery Taproot: tr( - sPK = 5120cafd90c7026f0b6ab98df89490d02732881f2f4b5900856358dddff4679c2ffb, - internal_pubkey = c6047f9441ed7d6d3045406e95c07cd85c778e4b8cef3ca7abac09b95c709ee5) - -Trigger Taproot: tr( - sPK = 5120418c46636d9e1a683f58e35b42336e776fdcc3b2d4e39e7a0bf1ab0716e3c5fa, - internal_pubkey = f9308a019258c31049344f85f89d5229b531c845836f99b08601f113bce036f9) - -Spend delay: 10 - -Vault Taproot: tr( - sPK = 5120062eb40e358106ea4f39bcac8ce046e44b84e5c0cf8799bd3d08f9ffb4afeb7a, - internal_pubkey = c6047f9441ed7d6d3045406e95c07cd85c778e4b8cef3ca7abac09b95c709ee5, - merkle_root = 11765541441f95f7af87fc19fcc1c09a1f5b05514d130320e4dfe6d729690230, - leaves = - - opvault: [ - push(5eb59117ddf962d44e11da5ce76c699cd9e6af53764795600543f02960b66023) - 10 - push(523882cb06ae65b1c2ba6e2009c0bf94e3d93ffe74470b354f854d335d9936e2) - OP_VAULT - ] (version=192), -) - - -"Initial vaulting" - -CTransaction 83b4308ccaa83eeb95316050fe2bfd1b027e285ddf31b0bd69762ec113140126: (nVersion=2) - vin: - - [0] CTxIn(prevout=COutPoint(hash=b4ba2b24be456aacaf743be5fe5de25eb3ebebb52f3faf75aecf45921a810101 n=0) scriptSig= nSequence=0) - vout: - - [0] Coin(4999990000, sPK=[1 push(062eb40e358106ea4f39bcac8ce046e44b84e5c0cf8799bd3d08f9ffb4afeb7a)]) - witnesses: - nLockTime: 0 - - -"Trigger" - -CTransaction e0844e873c4319222ebc407b0aa8f385c8a036e3145289d87750d5b895a88b33: (nVersion=2) - vin: - - [0] CTxIn(prevout=COutPoint(hash=83b4308ccaa83eeb95316050fe2bfd1b027e285ddf31b0bd69762ec113140126 n=0) scriptSig= nSequence=0) - vout: - - [0] Coin(4999990000, sPK=[1 push(9a15dca153a8651b610a02f3a92df3ada3cd45fd7f6183c7b2c1bc333bed1e63)]) - witnesses: - - [0] - - [0.0] [push(bdb4b3f6af17c93308af5ea689b33425497e388a0075f4311540e50d4d3d76f068ab645603333929e5ac62ecc125fc98a053aff53f65b0cffaaeef31efd415ff)] - - [0.1] [1 push(418c46636d9e1a683f58e35b42336e776fdcc3b2d4e39e7a0bf1ab0716e3c5fa)] - - [0.2] [push(c707f3e01b67c9dac06ad15cf0800cc07278a0a1c4f54cb92457ee5c0d84519a)] - - [0.3] [push()] - - [0.4] [ - push(5eb59117ddf962d44e11da5ce76c699cd9e6af53764795600543f02960b66023) - 10 - push(523882cb06ae65b1c2ba6e2009c0bf94e3d93ffe74470b354f854d335d9936e2) - OP_VAULT - ] - - [0.5] [push(c0c6047f9441ed7d6d3045406e95c07cd85c778e4b8cef3ca7abac09b95c709ee5)] - nLockTime: 0 - - -"Withdrawal" - -CTransaction 9595af9728de3ae9ca6110c040ad34f02f9db8b610296f99618354b99d5ec395: (nVersion=2) - vin: - - [0] CTxIn(prevout=COutPoint(hash=e0844e873c4319222ebc407b0aa8f385c8a036e3145289d87750d5b895a88b33 n=0) scriptSig= nSequence=10) - vout: - - [0] Coin(1666663333, sPK=[push() push(c42e7ef92fdb603af844d064faad95db9bcdfd3d)]) - - [1] Coin(1666663333, sPK=[push() push(4747e8746cddb33b0f7f95a90f89f89fb387cbb6)]) - - [2] Coin(1666663334, sPK=[push() push(7fda9cf020c16cacf529c87d8de89bfc70b8c9cb)]) - witnesses: - - [0] - - [0.0] [ - push(5eb59117ddf962d44e11da5ce76c699cd9e6af53764795600543f02960b66023) - 10 - push(c707f3e01b67c9dac06ad15cf0800cc07278a0a1c4f54cb92457ee5c0d84519a) - OP_UNVAULT - ] - - [0.1] [push(c150929b74c1a04954b78b4b6035e97a5e078a5a0f28ec96d547bfee9ace803ac0)] - nLockTime: 0 - - == References == * [https://lists.linuxfoundation.org/pipermail/bitcoin-dev/2016-February/012470.html [bitcoin-dev] Bitcoin Vaults (2016)] From a0b433471dfa4adfb39844274bf52159e4574cf6 Mon Sep 17 00:00:00 2001 From: James O'Beirne Date: Thu, 23 Mar 2023 13:23:08 -0400 Subject: [PATCH 069/454] fixup! rename vaults BIP --- bip-vaults.mediawiki => bip-0345.mediawiki | 0 1 file changed, 0 insertions(+), 0 deletions(-) rename bip-vaults.mediawiki => bip-0345.mediawiki (100%) diff --git a/bip-vaults.mediawiki b/bip-0345.mediawiki similarity index 100% rename from bip-vaults.mediawiki rename to bip-0345.mediawiki From a6452eaf1a7fca69746f73931852b038c708123e Mon Sep 17 00:00:00 2001 From: James O'Beirne Date: Thu, 23 Mar 2023 13:31:22 -0400 Subject: [PATCH 070/454] fixup! add TLUV references --- bip-0345.mediawiki | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/bip-0345.mediawiki b/bip-0345.mediawiki index 72f3f4fe57..a5ffa08ffe 100644 --- a/bip-0345.mediawiki +++ b/bip-0345.mediawiki @@ -167,7 +167,9 @@ withdrawal by allowing a spending transaction to replace the OP_VAULT tapleaf with a prespecified script template, allowing for some parameters to be set at spend (trigger) time. All other leaves in the taptree must be unchanged, which preserves the recovery path as well as any -other spending conditions originally included in the vault. +other spending conditions originally included in the vault. This is similar to +the TAPLEAF_UPDATE_VERIFY design that was proposed +[https://lists.linuxfoundation.org/pipermail/bitcoin-dev/2021-September/019419.html in 2021]. These tapleaf replacement rules, described more precisely below, ensure a timelocked withdrawal, where the timelock is fixed by the original @@ -598,6 +600,7 @@ deployments for OP_CHECKSEQUENCEVERIFY and OP_CHECKLOCKTIMEVERIFY (see * [https://lists.linuxfoundation.org/pipermail/bitcoin-dev/2016-February/012470.html [bitcoin-dev] Bitcoin Vaults (2016)] * [https://lists.linuxfoundation.org/pipermail/bitcoin-dev/2018-February/015793.html [bitcoin-dev] Simple lock/unlock mechanism (2018)] * [https://lists.linuxfoundation.org/pipermail/bitcoin-dev/2020-April/017755.html [bitcoin-dev] On-chain vaults prototype (2020)] +* [https://lists.linuxfoundation.org/pipermail/bitcoin-dev/2021-September/019419.html [bitcoin-dev] TAPLEAF_UPDATE_VERIFY covenant opcode (2021)] * [https://arxiv.org/abs/2005.11776 Custody Protocols Using Bitcoin Vaults (2020)] * [https://jameso.be/vaults.pdf Vaults and Covenants (2023)] From e08f6ad4dfed1ca67de9983d375a93d1481d1644 Mon Sep 17 00:00:00 2001 From: Greg Sanders Date: Tue, 28 Mar 2023 11:51:21 -0400 Subject: [PATCH 071/454] few word changes --- bip-0345.mediawiki | 18 +++++++++--------- 1 file changed, 9 insertions(+), 9 deletions(-) diff --git a/bip-0345.mediawiki b/bip-0345.mediawiki index a5ffa08ffe..2cac3de421 100644 --- a/bip-0345.mediawiki +++ b/bip-0345.mediawiki @@ -239,22 +239,22 @@ When evaluating OP_VAULT (OP_SUCCESS187, where -* is a data push of 0 or more bytes containing a script fragment. -** In conjunction with the leaf-update data items, it dictates the tapleaf script in the output taptree that will replace the one currently executing. +* is a minimally-encoded data push of a serialized script. In conjunction with the leaf-update data items, it dictates the tapleaf script in the output taptree that will replace the one currently executing. +** Otherwise, script execution MUST fail and terminate immediately. -* is a CScriptNum-encoded number indicating how many leaf-update script items should be popped off the stack. +* is an up to 4-byte CScriptNum-encoded number indicating how many leaf-update script items should be popped off the stack. ** If this value does not decode to a valid CScriptNum, script execution when spending this output MUST fail and terminate immediately. ** If this value is less than 0, script execution when spending this output MUST fail and terminate immediately. ** If fewer than + 2 items are on the stack, script execution when spending this output MUST fail and terminate immediately. -* The following stack items are popped off the stack and prefixed as push-data arguments to the to construct the expected tapleaf replacement script. +* The following stack items are popped off the stack and prefixed as minimally-encoded push-data arguments to the to construct the expected tapleaf replacement script. ** If there are fewer than + 2 items on the stack, script execution when spending this output MUST fail and terminate immediately. -* is a CScriptNum-encoded number indicating the index of the output which, in conjunction with an optional revault output, carries forward the value of this input, and has an identical taptree aside from the currently executing leaf. +* is an up to 4-byte CScriptNum-encoded number indicating the index of the output which, in conjunction with an optional revault output, carries forward the value of this input, and has an identical taptree aside from the currently executing leaf. ** If this value does not decode to a valid CScriptNum, script execution when spending this output MUST fail and terminate immediately. ** If this value is less than 0 or is greater than or equal to the number of outputs, script execution when spending this output MUST fail and terminate immediately. -* is a CScriptNum-encoded number optionally indicating the index of an output which, in conjunction with the trigger output, carries forward the value of this input, and has an identical scriptPubKey to the current input. +* is an up to 4-byte CScriptNum-encoded number optionally indicating the index of an output which, in conjunction with the trigger output, carries forward the value of this input, and has an identical scriptPubKey to the current input. ** If this value does not decode to a valid CScriptNum, script execution when spending this output MUST fail and terminate immediately. ** If this value is greater than or equal to the number of outputs, script execution when spending this output MUST fail and terminate immediately. @@ -264,8 +264,8 @@ After the stack is parsed, the following validation checks are performed: * If the scriptPubKey of ''triggerOut'' is not a witness program of the same version as the currently executing script, script execution MUST fail and terminate immediately. * Let the script constructed by taking the and prefixing it with minimally-encoded data pushes of the leaf-update script data items be called the ''leaf-update-script''. ** The leaf-update data items will be in the same order in the ''leaf-update-script'' as they appeared on the stack. -* If the scriptPubKey of ''triggerOut'' is not a taptree that is identical to that of the current input, but with the current leaf script substituted for ''leaf-update-script'', script execution when spending this output MUST fail and terminate immediately. -** Note: the parity bit of the resulting taproot is allowed to vary. +* If the scriptPubKey of ''triggerOut'' does not match that of a taptree that is identical to that of the currently evaluated input, but with the leaf script substituted for ''leaf-update-script'', script execution when spending this output MUST fail and terminate immediately. +** Note: the parity bit of the resulting taproot output is allowed to vary, so both values for the new output must be checked. * Let the output designated by (if the index value is non-negative) be called ''revaultOut''. * If the scriptPubKey of ''revaultOut'' is not equal to the scriptPubKey of the input being spent, script execution when spending this output MUST fail and terminate immediately. * If the sum of the amounts of ''triggerOut'' and ''revaultOut'' (if any) are not greater than or equal to the value of this input, script execution when spending this output MUST fail and terminate immediately. @@ -287,7 +287,7 @@ where * is a 32-byte data push. ** If this is not 32 bytes in length, script execution when spending this output MUST fail and terminate immediately. -* is a CScriptNum-encoded number indicating the index of the recovery output. +* is an up to 4-byte CScriptNum-encoded number indicating the index of the recovery output. ** If this value does not decode to a valid CScriptNum, script execution when spending this output MUST fail and terminate immediately. ** If this value is less than 0 or is greater than or equal to the number of outputs, script execution when spending this output MUST fail and terminate immediately. From 8bad703ed8391a735e9d1adba2ba92d89a0b06e7 Mon Sep 17 00:00:00 2001 From: Greg Sanders Date: Tue, 28 Mar 2023 12:30:36 -0400 Subject: [PATCH 072/454] why n-pushes --- bip-0345.mediawiki | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/bip-0345.mediawiki b/bip-0345.mediawiki index 2cac3de421..d6d00c36fe 100644 --- a/bip-0345.mediawiki +++ b/bip-0345.mediawiki @@ -242,7 +242,7 @@ where * is a minimally-encoded data push of a serialized script. In conjunction with the leaf-update data items, it dictates the tapleaf script in the output taptree that will replace the one currently executing. ** Otherwise, script execution MUST fail and terminate immediately. -* is an up to 4-byte CScriptNum-encoded number indicating how many leaf-update script items should be popped off the stack. +* is an up to 4-byte CScriptNum-encoded number indicating how many leaf-update script items should be popped off the stack. '''Why only prepending with data pushes?''' Prepending the leaf-update-script-body with opcodes opens up the door to prepending OP_SUCCESSX opcodes, to name a single issue only, side-stepping the validation that was meant to be run by the committed script. ** If this value does not decode to a valid CScriptNum, script execution when spending this output MUST fail and terminate immediately. ** If this value is less than 0, script execution when spending this output MUST fail and terminate immediately. ** If fewer than + 2 items are on the stack, script execution when spending this output MUST fail and terminate immediately. From 8bf5b869e5840fc5564e01f62bdbabc8b8ffcab2 Mon Sep 17 00:00:00 2001 From: Greg Sanders Date: Tue, 28 Mar 2023 12:39:03 -0400 Subject: [PATCH 073/454] remove vestigial reference in applications section --- bip-0345.mediawiki | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/bip-0345.mediawiki b/bip-0345.mediawiki index d6d00c36fe..d23571d965 100644 --- a/bip-0345.mediawiki +++ b/bip-0345.mediawiki @@ -336,7 +336,7 @@ These two pieces are combined with the tapleaf update capabilities of === Creating a vault === -In order to vault coins, they must be spent into a witness v1'''Can OP_VAULT be used with a future witness version (greater than 1)?''' Yes, however use of yet to be defined witness versions is discouraged, since such a usage makes the coins spendable by anyone. scriptPubKey +In order to vault coins, they must be spent into a witness v1 scriptPubKey that contains a taptree of the form From 29345a10f0e991e8f223beb9a92984e767911ac2 Mon Sep 17 00:00:00 2001 From: Greg Sanders Date: Tue, 28 Mar 2023 12:42:48 -0400 Subject: [PATCH 074/454] Be explicit about tapleaf version forwarding --- bip-0345.mediawiki | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/bip-0345.mediawiki b/bip-0345.mediawiki index d23571d965..c0baeb2124 100644 --- a/bip-0345.mediawiki +++ b/bip-0345.mediawiki @@ -261,7 +261,7 @@ where After the stack is parsed, the following validation checks are performed: * Let the output designated by be called ''triggerOut''. -* If the scriptPubKey of ''triggerOut'' is not a witness program of the same version as the currently executing script, script execution MUST fail and terminate immediately. +* If the scriptPubKey of ''triggerOut'' is not a witness program of the same version and same tapleaf version as the currently executing script, script execution MUST fail and terminate immediately. * Let the script constructed by taking the and prefixing it with minimally-encoded data pushes of the leaf-update script data items be called the ''leaf-update-script''. ** The leaf-update data items will be in the same order in the ''leaf-update-script'' as they appeared on the stack. * If the scriptPubKey of ''triggerOut'' does not match that of a taptree that is identical to that of the currently evaluated input, but with the leaf script substituted for ''leaf-update-script'', script execution when spending this output MUST fail and terminate immediately. From 0b0674c546eba07583da87d029f42a5da551af42 Mon Sep 17 00:00:00 2001 From: Greg Sanders Date: Tue, 28 Mar 2023 15:08:03 -0400 Subject: [PATCH 075/454] few fixups --- bip-0345.mediawiki | 25 ++++++++++++------------- 1 file changed, 12 insertions(+), 13 deletions(-) diff --git a/bip-0345.mediawiki b/bip-0345.mediawiki index c0baeb2124..2276bd15e6 100644 --- a/bip-0345.mediawiki +++ b/bip-0345.mediawiki @@ -17,20 +17,19 @@ == Introduction == -This BIP proposes new tapscript opcodes, OP_VAULT and -OP_VAULT_RECOVER, that add consensus support for a specialized -covenant. These opcodes, in conjunction with +This BIP proposes two new tapscript opcodes that add consensus support for a specialized +covenant: OP_VAULT and OP_VAULT_RECOVER. These opcodes, in conjunction with OP_CHECKTEMPLATEVERIFY ([https://github.com/bitcoin/bips/blob/master/bip-0119.mediawiki BIP-0119]), allow users to enforce a delay period before designated coins may be spent to an arbitrary destination, with the exception of a prespecified "recovery" path. At any time prior to final withdrawal, the coins can be spent to the -prespecified path. +recovery path. === Motivation === -The hazard of custodying Bitcoin is well known. Users of Bitcoin must go to +The hazard of custodying Bitcoin is well-known. Users of Bitcoin must go to significant effort to secure their private keys, and hope that once provisioned their custody system does not yield to any number of evolving and persistent threats. Users have little means to intervene once a compromise is @@ -45,8 +44,8 @@ usable for custodians of any size with minimal complication. ==== Example uses ==== -An individual custodying Bitcoin uses the common "single signature and -passphrase" configuration with a hardware wallet. They are concerned about the +A common configuration for an individual custodying Bitcoin is a "single signature and +passphrase" with a hardware wallet. They are concerned about the risk associated with relying on a single manufacturer for key management as well as physical access to the hardware, so they generate a new key that is highly secure, but would be impractical for daily use. For example the key @@ -66,7 +65,7 @@ them to the highly secure recovery path, but spending the coins on a daily basis works in the same way it did prior to vaulting - aside from the spend delay. -The recovery key could be any number of things: a 2-of-3 multisig with keys +The recovery key could be any Bitcoin script policy: a 2-of-3 multisig with keys that live on different devices, a 3-of-5 with socially distributed keys, a Taproot construction that incorporates one of these methods along with a time-delayed fallback to an "easier" recovery method, in case the highly secure @@ -76,7 +75,7 @@ Institutional custodians of Bitcoin would likely use vaults in similar fashion. ===== Provable timelocks ===== -This proposal provides a solution to the +This proposal provides a mitigation to the [https://web.archive.org/web/20230210123933/https://xkcd.com/538/ "$5 wrench attack."] By setting the spend delay to, say, a week, and using as the recovery path a script that enforces a longer relative timelock, the owner of the vault can @@ -148,7 +147,7 @@ The design goals of the proposal are: * '''dynamic fee management''' that, like dynamic targets, defers the specification of fee rates and source to unvault time rather than vault creation time. These goals are accompanied by basic safety considerations (e.g. not being -vulnerable to pinning) and a desire for concision, both in terms of the number +vulnerable to mempool pinning) and a desire for concision, both in terms of the number of outputs created as well as script sizes. This proposal is designed to be compatible with any future sighash modes (e.g. SIGHASH_GROUP) or fee management strategies (e.g. [https://lists.linuxfoundation.org/pipermail/bitcoin-dev/2020-September/018168.html transaction sponsors]) that may be introduced. Use of these opcodes will benefit from, but do not strictly rely on, [https://lists.linuxfoundation.org/pipermail/bitcoin-dev/2022-September/020937.html v3 transaction relay] and [https://github.com/instagibbs/bips/blob/ephemeral_anchor/bip-ephemeralanchors.mediawiki ephemeral anchors]. @@ -166,7 +165,7 @@ The rules of OP_VAULT ensure the timelocked, interruptible withdrawal by allowing a spending transaction to replace the OP_VAULT tapleaf with a prespecified script template, allowing for some parameters to be set at spend (trigger) time. All other leaves in the -taptree must be unchanged, which preserves the recovery path as well as any +taptree must be unchanged in the destination output, which preserves the recovery path as well as any other spending conditions originally included in the vault. This is similar to the TAPLEAF_UPDATE_VERIFY design that was proposed [https://lists.linuxfoundation.org/pipermail/bitcoin-dev/2021-September/019419.html in 2021]. @@ -564,9 +563,9 @@ coins they wish to monitor; the watchtower would then alert the user if any coins matching the filter move, and the user would be responsible for ignoring false positives and handling recovery initiation. -=== Script descriptors === +=== Output descriptors === -Script descriptors for vault-related outputs will be covered in a subsequent BIP. +Output descriptors for vault-related outputs will be covered in a subsequent BIP. == Deployment == From 0e5b18c0ff8df885b1f6b326e90cc6e687e0838e Mon Sep 17 00:00:00 2001 From: Anthony Towns Date: Tue, 28 Mar 2023 09:23:35 +1000 Subject: [PATCH 076/454] BIP327: fixups for buildtable.pl --- bip-0327.mediawiki | 1 + scripts/buildtable.pl | 4 ++-- 2 files changed, 3 insertions(+), 2 deletions(-) diff --git a/bip-0327.mediawiki b/bip-0327.mediawiki index 17ccbe5223..07b40f53e7 100644 --- a/bip-0327.mediawiki +++ b/bip-0327.mediawiki @@ -10,6 +10,7 @@ Created: 2022-03-22 Post-History: 2022-04-05: https://lists.linuxfoundation.org/pipermail/bitcoin-dev/2022-April/020198.html [bitcoin-dev] MuSig2 BIP 2022-10-11: https://lists.linuxfoundation.org/pipermail/bitcoin-dev/2022-October/021000.html [bitcoin-dev] MuSig2 BIP + Comments-URI: https://github.com/bitcoin/bips/wiki/Comments:BIP-0327 == Introduction == diff --git a/scripts/buildtable.pl b/scripts/buildtable.pl index 53a126c767..292f1ee5b0 100755 --- a/scripts/buildtable.pl +++ b/scripts/buildtable.pl @@ -89,7 +89,7 @@ ); my %GrandfatheredPD = map { $_ => undef } qw(9 36 37 38 42 49 50 60 65 67 69 74 80 81 83 90 99 105 107 109 111 112 113 114 122 124 125 126 130 131 132 133 140 141 142 143 144 146 147 150 151 152); my %TolerateMissingLicense = map { $_ => undef } qw(1 10 11 12 13 14 15 16 21 31 33 34 35 39 43 44 45 47 61 64 68 70 71 72 73 101 102 106 120 121); -my %TolerateTitleTooLong = map { $_ => undef } qw(39 44 45 47 49 60 67 68 69 73 74 75 80 81 99 105 106 109 113 122 126 131 143 145 147 173); +my %TolerateTitleTooLong = map { $_ => undef } qw(39 44 45 47 49 60 67 68 69 73 74 75 80 81 99 105 106 109 113 122 126 131 143 145 147 173 327); my %emails; @@ -125,7 +125,7 @@ } elsif ($field eq 'Title') { $title = $val; my $title_len = length($title); - die "$fn has too-long TItle ($title_len > 44 char max)" if $title_len > 44 and not exists $TolerateTitleTooLong{$bipnum}; + die "$fn has too-long Title ($title_len > 44 char max)" if $title_len > 44 and not exists $TolerateTitleTooLong{$bipnum}; } elsif ($field eq 'Author') { $val =~ m/^(\S[^<@>]*\S) \<([^@>]*\@[\w.-]+\.\w+)\>$/ or die "Malformed Author line in $fn"; my ($authorname, $authoremail) = ($1, $2); From 469ccc961740c3d59dbd2ce294a82f0edf23cd9c Mon Sep 17 00:00:00 2001 From: Anthony Towns Date: Tue, 28 Mar 2023 09:44:25 +1000 Subject: [PATCH 077/454] README markup fixes --- README.mediawiki | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/README.mediawiki b/README.mediawiki index 72f26a3942..5d22fba842 100644 --- a/README.mediawiki +++ b/README.mediawiki @@ -1043,28 +1043,28 @@ Those proposing changes should consider that ultimately consent may rest with th | Suhas Daftuar | Standard | Draft -|- +|- style="background-color: #cfffcf" | [[bip-0340.mediawiki|340]] | | Schnorr Signatures for secp256k1 | Pieter Wuille, Jonas Nick, Tim Ruffing | Standard | Final -|- +|- style="background-color: #cfffcf" | [[bip-0341.mediawiki|341]] | Consensus (soft fork) | Taproot: SegWit version 1 spending rules | Pieter Wuille, Jonas Nick, Anthony Towns | Standard | Final -|- +|- style="background-color: #cfffcf" | [[bip-0342.mediawiki|342]] | Consensus (soft fork) | Validation of Taproot Scripts | Pieter Wuille, Jonas Nick, Anthony Towns | Standard | Final -|- style="background-color: #ffffcf" +|- style="background-color: #cfffcf" | [[bip-0343.mediawiki|343]] | Consensus (soft fork) | Mandatory activation of taproot deployment From cbfdce0430dbd9105a3f7cf54600e8a84d57a093 Mon Sep 17 00:00:00 2001 From: Anthony Towns Date: Tue, 28 Mar 2023 09:46:43 +1000 Subject: [PATCH 078/454] BIP157 was replaced in PR#1378 --- bip-0151.mediawiki | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/bip-0151.mediawiki b/bip-0151.mediawiki index 9b91365642..793c24411c 100644 --- a/bip-0151.mediawiki +++ b/bip-0151.mediawiki @@ -5,7 +5,7 @@ Author: Jonas Schnelli Comments-Summary: Controversial; some recommendation, and some discouragement Comments-URI: https://github.com/bitcoin/bips/wiki/Comments:BIP-0151 - Status: Withdrawn + Status: Replaced Type: Standards Track Created: 2016-03-23 License: PD From 9e4c055a7441948b3c7f28bb3cf6de19922e90c4 Mon Sep 17 00:00:00 2001 From: Anthony Towns Date: Tue, 28 Mar 2023 09:52:15 +1000 Subject: [PATCH 079/454] Use BIP-326 title from PR#1314 in README --- README.mediawiki | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.mediawiki b/README.mediawiki index 5d22fba842..815e8c3c67 100644 --- a/README.mediawiki +++ b/README.mediawiki @@ -1004,7 +1004,7 @@ Those proposing changes should consider that ultimately consent may rest with th |- | [[bip-0326.mediawiki|326]] | Applications -| Anti-fee-sniping protection in taproot transactions +| Anti-fee-sniping in taproot transactions | Chris Belcher | Informational | Draft From 838fd932190f2b54ec4bcdf7824aec5c76724571 Mon Sep 17 00:00:00 2001 From: Russell O'Connor Date: Fri, 17 Mar 2023 11:15:29 -0400 Subject: [PATCH 080/454] bip93: More invalid test vectors These examples are valid BIP-173 and BIP-350 strings (but not valid BIP-93 strings). --- bip-0093.mediawiki | 2 ++ 1 file changed, 2 insertions(+) diff --git a/bip-0093.mediawiki b/bip-0093.mediawiki index 434e479c80..1cc2dc6767 100644 --- a/bip-0093.mediawiki +++ b/bip-0093.mediawiki @@ -498,6 +498,8 @@ These examples have incorrect checksums. * ms10fauxsxxxxxxxxxxxxxxxxxxxxxxxxxxxxc55srw5jrm0 * ms10fauxsxxxxxxxxxxxxxxxxxxxxxxxxxxxxgc7rwhtudwc * ms10fauxsxxxxxxxxxxxxxxxxxxxxxxxxxxx4gy22afwghvs +* ms10fauxsxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxe8yfm0 +* ms10fauxsxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxvm597d * ms10fauxsxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxme084q0vpht7pe0 * ms10fauxsxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxme084q0vpht7pew * ms10fauxsxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxqyadsp3nywm8a From eb62f6ea71629e63ab4dc40eb7e18770e10c7b33 Mon Sep 17 00:00:00 2001 From: Andrew Poelstra Date: Wed, 29 Mar 2023 14:07:31 +0000 Subject: [PATCH 081/454] bip93: make bech32 capitalization consistently lowercase --- bip-0093.mediawiki | 34 +++++++++++++++++----------------- 1 file changed, 17 insertions(+), 17 deletions(-) diff --git a/bip-0093.mediawiki b/bip-0093.mediawiki index 1cc2dc6767..7974a30076 100644 --- a/bip-0093.mediawiki +++ b/bip-0093.mediawiki @@ -60,7 +60,7 @@ However, BIP-0039 has no error-correcting ability, cannot sensibly be extended t ===codex32=== -A codex32 string is similar to a Bech32 string defined in [https://github.com/bitcoin/bips/blob/master/bip-0173.mediawiki BIP-0173]. +A codex32 string is similar to a bech32 string defined in [https://github.com/bitcoin/bips/blob/master/bip-0173.mediawiki BIP-0173]. It reuses the base32 character set from BIP-0173, and consists of: * A human-readable part, which is the string "ms" (or "MS"). @@ -68,12 +68,12 @@ It reuses the base32 character set from BIP-0173, and consists of: * A data part which is in turn subdivided into: ** A threshold parameter, which MUST be a single digit between "2" and "9", or the digit "0". *** If the threshold parameter is "0" then the share index, defined below, MUST have a value of "s" (or "S"). -** An identifier consisting of 4 Bech32 characters. -** A share index, which is any Bech32 character. Note that a share index value of "s" (or "S") is special and denotes the unshared secret (see section "Unshared Secret"). -** A payload which is a sequence of up to 74 Bech32 characters. (However, see '''Long codex32 Strings''' below for an exception to this limit.) -** A checksum which consists of 13 Bech32 characters as described below. +** An identifier consisting of 4 bech32 characters. +** A share index, which is any bech32 character. Note that a share index value of "s" (or "S") is special and denotes the unshared secret (see section "Unshared Secret"). +** A payload which is a sequence of up to 74 bech32 characters. (However, see '''Long codex32 Strings''' below for an exception to this limit.) +** A checksum which consists of 13 bech32 characters as described below. -As with Bech32 strings, a codex32 string MUST be entirely uppercase or entirely lowercase. +As with bech32 strings, a codex32 string MUST be entirely uppercase or entirely lowercase. For presentation, lowercase is usually preferable, but uppercase SHOULD be used for handwritten codex32 strings. If a codex32 string is encoded in a QR code, it SHOULD use the uppercase form, as this is encoded more compactly. @@ -131,7 +131,7 @@ We do not specify how an implementation should implement error correction. Howev * Implementations interpret "?" as an erasure. * Implementations optionally interpret other non-bech32 characters, or characters with incorrect case, as erasures. * If a string with 8 or fewer erasures can have those erasures filled in to make a valid codex32 string, then the implementation suggests such a string as a correction. -* If a string consisting of valid Bech32 characters in the proper case can be made valid by substituting 4 or fewer characters, then the implementation suggests such a string as a correction. +* If a string consisting of valid bech32 characters in the proper case can be made valid by substituting 4 or fewer characters, then the implementation suggests such a string as a correction. ===Unshared Secret=== @@ -243,7 +243,7 @@ The conversion process consists of: # Choose a 4 bech32 character identifier #* We do not define how to choose the identifier, beyond noting that it SHOULD be distinct for every master seed the user may need to disambiguate. # Set the share index to s -# Set the payload to a Bech32 encoding of the master seed, padded with arbitrary bits +# Set the payload to a bech32 encoding of the master seed, padded with arbitrary bits # Generating a valid checksum in accordance with the Checksum section Along with the codex32 secret, the user must generate ''t''-1 other codex32 shares, each with the same threshold value, the same identifier, and a distinct share index. @@ -288,8 +288,8 @@ def ms32_create_long_checksum(data): A long codex32 string follows the same specification as a regular codex32 string with the following changes. -* The payload is a sequence of between 75 and 103 Bech32 characters. -* The checksum consists of 15 Bech32 characters as defined above. +* The payload is a sequence of between 75 and 103 bech32 characters. +* The checksum consists of 15 bech32 characters as defined above. A codex32 string with a data part of 94 or 95 characters is never legal as a regular codex32 string is limited to 93 data characters and a long codex32 string is at least 96 characters. @@ -384,9 +384,9 @@ The inline code in this BIP text can be used as a Python reference. ===Test vector 1=== This example shows the codex32 format, when used without splitting the secret into any shares. -The payload contains 26 Bech32 characters, which corresponds to 130 bits. We truncate the last two bits in order to obtain a 128-bit master seed. +The payload contains 26 bech32 characters, which corresponds to 130 bits. We truncate the last two bits in order to obtain a 128-bit master seed. -codex32 secret (Bech32): ms10testsxxxxxxxxxxxxxxxxxxxxxxxxxx4nzvca9cmczlw +codex32 secret (bech32): ms10testsxxxxxxxxxxxxxxxxxxxxxxxxxx4nzvca9cmczlw Master secret (hex): 318c6318c6318c6318c6318c6318c631 @@ -419,7 +419,7 @@ In particular, given an all uppercase codex32 string, we still use lowercase cash. -We appended two zero bits in order to obtain 26 Bech32 characters (130 bits of data) from the 128-bit master seed. +We appended two zero bits in order to obtain 26 bech32 characters (130 bits of data) from the 128-bit master seed. Master secret (hex): ffeeddccbbaa99887766554433221100 @@ -447,7 +447,7 @@ However, each choice would have resulted in a different set of derived shares. ===Test vector 4=== This example shows converting a 256-bit secret into a codex32 secret, without splitting the secret into any shares. -We appended four zero bits in order to obtain 52 Bech32 characters (260 bits of data) from the 256-bit secret. +We appended four zero bits in order to obtain 52 bech32 characters (260 bits of data) from the 256-bit secret. 256-bit secret (hex): ffeeddccbbaa99887766554433221100ffeeddccbbaa99887766554433221100 @@ -476,7 +476,7 @@ Note that the choice to append four zero bits was arbitrary, and any of the foll ===Test vector 5=== This example shows generating a new 512-bit master seed using "random" codex32 characters and appending a checksum. -The payload contains 103 Bech32 characters, which corresponds to 515 bits. The last three bits are discarded when converting to a 512-bit master seed. +The payload contains 103 bech32 characters, which corresponds to 515 bits. The last three bits are discarded when converting to a 512-bit master seed. This is an example of a '''Long codex32 String'''. @@ -576,8 +576,8 @@ These examples all incorrectly mix upper and lower case characters. ===Mathematical Companion=== -Below we use the Bech32 character set to denote values in GF[32]. -In Bech32, the letter Q denotes zero and the letter P denotes one. +Below we use the bech32 character set to denote values in GF[32]. +In bech32, the letter Q denotes zero and the letter P denotes one. The digits 0 and 2 through 9 do ''not'' denote their numeric values. They are simply elements of GF[32]. From c3b330fdec2ccd65ac4eb85160034d7f744b79f2 Mon Sep 17 00:00:00 2001 From: Andrew Poelstra Date: Wed, 29 Mar 2023 14:05:35 +0000 Subject: [PATCH 082/454] bip93: typo fixes, and fix URL format --- bip-0093.mediawiki | 28 ++++++++++++++-------------- 1 file changed, 14 insertions(+), 14 deletions(-) diff --git a/bip-0093.mediawiki b/bip-0093.mediawiki index 7974a30076..27eeea0a4f 100644 --- a/bip-0093.mediawiki +++ b/bip-0093.mediawiki @@ -61,7 +61,7 @@ However, BIP-0039 has no error-correcting ability, cannot sensibly be extended t ===codex32=== A codex32 string is similar to a bech32 string defined in [https://github.com/bitcoin/bips/blob/master/bip-0173.mediawiki BIP-0173]. -It reuses the base32 character set from BIP-0173, and consists of: +It reuses the base-32 character set from BIP-0173, and consists of: * A human-readable part, which is the string "ms" (or "MS"). * A separator, which is always "1". @@ -80,7 +80,7 @@ If a codex32 string is encoded in a QR code, it SHOULD use the uppercase form, a ===Checksum=== The last thirteen characters of the data part form a checksum and contain no information. -Valid strings MUST pass the criteria for validity specified by the Python3 code snippet below. +Valid strings MUST pass the criteria for validity specified by the Python 3 code snippet below. The function ms32_verify_checksum must return true when its argument is the data part as a list of integers representing the characters converted using the bech32 character table from BIP-0173. To construct a valid checksum given the data-part characters (excluding the checksum), the ms32_create_checksum function can be used. @@ -226,7 +226,7 @@ In the case that the user wishes to generate a fresh master seed, the user gener #* We do not define how to choose the identifier, beyond noting that it SHOULD be distinct for every master seed the user may need to disambiguate. # ''t'' many times, generate a random share by: ## Take the next available letter from the bech32 alphabet, in alphabetical order, as a, c, d, ..., to be the share index -## Set the first nine characters to be the prefix ms1, the threshold vaue ''t'', the 4-character identifier, and then the share index +## Set the first nine characters to be the prefix ms1, the threshold value ''t'', the 4-character identifier, and then the share index ## Choose the next ceil(''bitlength / 5'') characters uniformly at random ## Generate a valid checksum in accordance with the Checksum section, and append this to the resulting shares @@ -334,32 +334,32 @@ However this alternative approach is fraught with difficulties. On approach would be to encode the BIP-0039 entropy along with the BIP-0039 checksum data. This data can directly be recovered from the BIP-0039 mnemonic, and the process can be reversed if one knows the target language. -However, for a 128-bit seed, there is a 4 bit checksum yeilding 132 bits of data that needs to be encoded. +However, for a 128-bit seed, there is a 4 bit checksum yielding 132 bits of data that needs to be encoded. This exceeds the 130-bits of room that we have for storing 128 bit seeds. We would have to compromise on the 48 character size, or the size of the headers, or the size of the checksum in order to add room for an additional character of data. This approach would also eliminate our short cut generation of a fresh master secret from generating random shares. One would be required to first generate BIP-0039 entropy, and then add a BIP-0039 checksum, before adding a Codex32 checksum and then generate other shares. -In particular, this process could no longer be perfored by hand since it is effecitvely impossible to hand compute a BIP-0039 checksum. +In particular, this process could no longer be performed by hand since it is effectively impossible to hand compute a BIP-0039 checksum. -An alternative approach is to discard the BIP-0039 checksum, since it is inadqueate for error correction anyways, and rely on the Codex32 checksum. +An alternative approach is to discard the BIP-0039 checksum, since it is inadequate for error correction anyways, and rely on the Codex32 checksum. However, this approach ends up eliminating the benefits of BIP-0039 compatibility. While it is now possible to hand generate fresh shares, it is impossible to recover compatible BIP-0039 words by hand because, again, the BIP-0039 checksum is not hand computable. The only way of generating the compatible BIP-0039 mnemonic is to use wallet software. -But if the wallet software is need to support this approach to decoding entropy, we may as well bypasss all of the overhead of BIP-0039 and directly encode the entropy of a BIP-0032 master seed, which is what we do in our Codex32 proposal. +But if the wallet software is need to support this approach to decoding entropy, we may as well bypass all of the overhead of BIP-0039 and directly encode the entropy of a BIP-0032 master seed, which is what we do in our Codex32 proposal. Beyond the problems above, BIP-0039 does not define a single transformation from entropy to BIP-0032 master seed. -Instead every different language has it own word list (or word lists) and each choice of word list yeilds a different transformation from entropy to master seed. -We would need to encode the choice of word list in our share's meta-data, which takes up even more room, and is difficult to specify due to the the ever evolving choice of word lists. +Instead every different language has it own word list (or word lists) and each choice of word list yields a different transformation from entropy to master seed. +We would need to encode the choice of word list in our share's meta-data, which takes up even more room, and is difficult to specify due to the ever-evolving choice of word lists. -Alternatively we could standardize on the choice of the English word list, something that is nearly a defacto standard, and simply be incompatible with BIP-0039 wallets of other langauges. -Such a choice also risks users of BIP-0039 recovering their entropy from their language, encoding it in in Codex32 and then failing to recover thier wallet because the English word lists has replaced their language's word list. +Alternatively we could standardize on the choice of the English word list, something that is nearly a de facto standard, and simply be incompatible with BIP-0039 wallets of other languages. +Such a choice also risks users of BIP-0039 recovering their entropy from their language, encoding it in in Codex32 and then failing to recover their wallet because the English word lists has replaced their language's word list. The main advantage of this alternative approach would be that wallets could give users an option switch between backing up their entropy as a BIP-0039 mnemonic and in Codex32 format, but again, only if their language choice happens to be the English word list. In practice, we do not expect users in switch back and forth between backup formats, and instead just generate a fresh master seed using Codex32. -Seeing little value with BIP-0039 compatiabilty (English-only), all the difficulties with BIP-0039 langauge choice, not to mention the PBKDF2 overhead of using BIP-0039, we think it is best to abandon BIP-0039 and encode BIP-0032 master seeds directly. -Our aproach is semi-convertable with BIP-0039's 512-bit master seeds (in all languages, see Backwards Compatibility) and fully interconvertable with SLIP-39 encoded master seeds or any other encoding of BIP-0032 master seeds. +Seeing little value with BIP-0039 compatibility (English-only), all the difficulties with BIP-0039 language choice, not to mention the PBKDF2 overhead of using BIP-0039, we think it is best to abandon BIP-0039 and encode BIP-0032 master seeds directly. +Our approach is semi-convertible with BIP-0039's 512-bit master seeds (in all languages, see Backwards Compatibility) and fully interconvertible with SLIP-39 encoded master seeds or any other encoding of BIP-0032 master seeds. ==Backwards Compatibility== @@ -376,7 +376,7 @@ Instead, users who wish to switch to codex32 should generate a fresh seed and sw ==Reference Implementation== -Our [https://github.com/BlockstreamResearch/codex32](reference implementation repository) contains implementations in Rust and PostScript. +Our [https://github.com/BlockstreamResearch/codex32 reference implementation repository] contains implementations in Rust and PostScript. The inline code in this BIP text can be used as a Python reference. ==Test Vectors== From c02efd1456ace504a8f12c1c741a4cf0c8275934 Mon Sep 17 00:00:00 2001 From: Andrew Poelstra Date: Thu, 30 Mar 2023 01:48:22 +0000 Subject: [PATCH 083/454] add myself as a BIPs author --- bip-0093.mediawiki | 1 + 1 file changed, 1 insertion(+) diff --git a/bip-0093.mediawiki b/bip-0093.mediawiki index 27eeea0a4f..da349fdd8b 100644 --- a/bip-0093.mediawiki +++ b/bip-0093.mediawiki @@ -3,6 +3,7 @@ Layer: Applications Title: codex32: Checksummed SSSS-aware BIP32 seeds Author: Leon Olsson Curr and Pearlwort Sneed + Andrew Poelstra Comments-URI: https://github.com/bitcoin/bips/wiki/Comments:BIP-0093 Status: Draft Type: Informational From 24204e1d3c4167d154b33eee35c598f54eeeee46 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Vojt=C4=9Bch=20Strnad?= <43024885+vostrnad@users.noreply.github.com> Date: Mon, 10 Apr 2023 16:22:24 +0200 Subject: [PATCH 084/454] Mark BIP84 as Final --- README.mediawiki | 2 +- bip-0084.mediawiki | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/README.mediawiki b/README.mediawiki index 815e8c3c67..0d834b15e8 100644 --- a/README.mediawiki +++ b/README.mediawiki @@ -440,7 +440,7 @@ Those proposing changes should consider that ultimately consent may rest with th | Derivation scheme for P2WPKH based accounts | Pavol Rusnak | Informational -| Draft +| Final |- | [[bip-0085.mediawiki|85]] | Applications diff --git a/bip-0084.mediawiki b/bip-0084.mediawiki index dc5a05d93d..7f20217dcd 100644 --- a/bip-0084.mediawiki +++ b/bip-0084.mediawiki @@ -5,7 +5,7 @@ Author: Pavol Rusnak Comments-Summary: No comments yet. Comments-URI: https://github.com/bitcoin/bips/wiki/Comments:BIP-0084 - Status: Draft + Status: Final Type: Informational Created: 2017-12-28 License: CC0-1.0 From 3ffc3573d9b59d4e52c6c4d4ec8b33e8316c9f97 Mon Sep 17 00:00:00 2001 From: Stacie Date: Mon, 10 Apr 2023 15:13:32 -0400 Subject: [PATCH 085/454] BIP-137: Fix typo --- bip-0137.mediawiki | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/bip-0137.mediawiki b/bip-0137.mediawiki index 19dd536488..43addbab4c 100644 --- a/bip-0137.mediawiki +++ b/bip-0137.mediawiki @@ -25,7 +25,7 @@ This BIP is licensed under the 2-clause BSD license. ==Motivation== -Since Bitcoin private keys can not only be used to sign Bitcoin transactions, but also any other message, it has become customary to use them to sign various messages for differing purposes. Some applications of signing messages with a Bitcoin private key are as follows: proof of funds for collateral, credit worthiness, enterence to events, airdrops, audits as well as other applications. While there was no BIP written for how to digitally sign messages with Bitcoin private keys with P2PKH addresses it is a fairly well understood process, however with the introduction of Segwit (both in the form of P2SH and bech32) addresses, it is unclear how to distinguish a P2PKH, P2SH, or bech32 address from one another. This BIP proposes a standard signature format that will allow clients to distinguish between the different address formats. +Since Bitcoin private keys can not only be used to sign Bitcoin transactions, but also any other message, it has become customary to use them to sign various messages for differing purposes. Some applications of signing messages with a Bitcoin private key are as follows: proof of funds for collateral, credit worthiness, entrance to events, airdrops, audits as well as other applications. While there was no BIP written for how to digitally sign messages with Bitcoin private keys with P2PKH addresses it is a fairly well understood process, however with the introduction of Segwit (both in the form of P2SH and bech32) addresses, it is unclear how to distinguish a P2PKH, P2SH, or bech32 address from one another. This BIP proposes a standard signature format that will allow clients to distinguish between the different address formats. ==Specification== From 7112f308b356cdf0c51d917dbdc1b98e30621f80 Mon Sep 17 00:00:00 2001 From: James O'Beirne Date: Mon, 17 Apr 2023 09:40:57 -0400 Subject: [PATCH 086/454] minor wording updates --- bip-0345.mediawiki | 65 +++++++++++++++++++++++----------------------- 1 file changed, 33 insertions(+), 32 deletions(-) diff --git a/bip-0345.mediawiki b/bip-0345.mediawiki index 2276bd15e6..4005d11a58 100644 --- a/bip-0345.mediawiki +++ b/bip-0345.mediawiki @@ -44,34 +44,35 @@ usable for custodians of any size with minimal complication. ==== Example uses ==== -A common configuration for an individual custodying Bitcoin is a "single signature and -passphrase" with a hardware wallet. They are concerned about the -risk associated with relying on a single manufacturer for key management as -well as physical access to the hardware, so they generate a new key that is -highly secure, but would be impractical for daily use. For example the key -could be generated in some analog fashion, or on an old computer (with added -entropy) that is then destroyed, with the private key replicated only in paper -form. Or the key could be a 2-of-3 multisig using devices from different -manufacturers. Perhaps the key is geographically distributed. - -This individual can use OP_VAULT to make use of the highly secure +A common configuration for an individual custodying Bitcoin is "single +signature and passphrase" using a hardware wallet. A user with such a +configuration might concerned about the risk associated with relying on a +single manufacturer for key management, as well as physical access to the +hardware. + +This individual can use OP_VAULT to make use of a highly secure key as the unlikely recovery path, while using their existing signing procedure -as the withdrawal trigger key, with a configured spend delay of 1 day. They can -run software on their mobile device that monitors the blockchain for spends of -the vault outpoints. +as the withdrawal trigger key with a configured spend delay of e.g. 1 day. + +The recovery path key can be of a highly secure nature that might otherwise +make it impractical for daily use. For example, the key could be generated in +some analog fashion, or on an old computer that is then destroyed, with the +private key replicated only in paper form. Or the key could be a 2-of-3 +multisig using devices from different manufacturers. Perhaps the key is +geographically or socially distributed. -If the vaulted coins move in an unexpected way, the user can immediately sweep -them to the highly secure recovery path, but spending the coins on a daily -basis works in the same way it did prior to vaulting - aside from the spend -delay. +Since it can be any Bitcoin script policy, the recovery key can include a +number of spending conditions, e.g. a time-delayed fallback to an "easier" +recovery method, in case the highly secure key winds up being ''too'' highly +secure. -The recovery key could be any Bitcoin script policy: a 2-of-3 multisig with keys -that live on different devices, a 3-of-5 with socially distributed keys, a -Taproot construction that incorporates one of these methods along with a -time-delayed fallback to an "easier" recovery method, in case the highly secure -key winds up being ''too'' highly secure. +The user can run software on their mobile device that monitors the blockchain +for spends of the vault outpoints. If the vaulted coins move in an unexpected +way, the user can immediately sweep them to the recovery path, but spending the +coins on a daily basis works in the same way it did prior to vaulting (aside +from the spend delay). -Institutional custodians of Bitcoin would likely use vaults in similar fashion. +Institutional custodians of Bitcoin may use vaults in similar fashion. ===== Provable timelocks ===== @@ -157,7 +158,7 @@ This proposal is designed to be compatible with any future sighash modes (e.g. < In typical usage, a vault is created by encumbering coins under a taptree [https://github.com/bitcoin/bips/blob/master/bip-0341.mediawiki (BIP-341)] containing at least two leaves: one with an OP_VAULT-containing script that -facilitates the expected withdrawal process, and leaf another with +facilitates the expected withdrawal process, and another leaf with OP_VAULT_RECOVER which ensures the coins can be recovered at any time prior to withdrawal finalization. @@ -192,9 +193,9 @@ The vault has a number of stages, some of them optional: * '''trigger transaction''': spends one or more OP_VAULT-tapleaf inputs into an output which is encumbered by a timelocked withdrawal to a fixed set of outputs, chosen at trigger time. This publicly broadcasts the intent to withdraw to some specific set of outputs.

The trigger transaction may have an additional output which allocates some of the vault balance into a partial "revault," which simply encumbers the revaulted portion of the value into the same scriptPubKey as the OP_VAULT-containing input(s) being spent. -* '''withdrawal transaction''': spends the timelocked OP_CHECKTEMPLATEVERIFY trigger inputs into a compatible set of final withdrawal outputs per the CTV hash, after the trigger inputs have matured per the spend delay. Timelocked CTV transactions are the motivating usage of OP_VAULT, but any script template can be specified during the creation of the vault. +* '''withdrawal transaction''': spends the timelocked, destination-locked trigger inputs into a compatible set of final withdrawal outputs (per, e.g., a CHECKTEMPLATEVERIFY hash), after the trigger inputs have matured per the spend delay. Timelocked CTV transactions are the motivating usage of OP_VAULT, but any script template can be specified during the creation of the vault. -* '''recovery transaction''': spends one or more OP_VAULT_RECOVER-tapleaf inputs to the prespecified recovery path, which can be done at any point before the withdrawal transaction confirms. Each input can optionally require a witness satisfying a specified ''recovery authorization'' script, an optional script prefixing the OP_VAULT_RECOVER fragment. The use of recovery authorization has certain trade-offs discussed later. +* '''recovery transaction''': spends one or more vault inputs via OP_VAULT_RECOVER tapleaf to the prespecified recovery path, which can be done at any point before the withdrawal transaction confirms. Each input can optionally require a witness satisfying a specified ''recovery authorization'' script, an optional script prefixing the OP_VAULT_RECOVER fragment. The use of recovery authorization has certain trade-offs discussed later. === Fee management === @@ -208,7 +209,7 @@ Providing dynamic fee management is critical to the operation of a vault, since But dynamic fee management can introduce [https://bitcoinops.org/en/topics/transaction-pinning/ pinning vectors]. Care has been taken to avoid unnecessarily introducing these vectors when using the new -content-based spending policies that this proposal introduces. +destination-based spending policies that this proposal introduces. Originally, this proposal had a hard dependency on reformed transaction nVersion=3 policies, including ephemeral anchors, but it has since been revised @@ -262,7 +263,7 @@ After the stack is parsed, the following validation checks are performed: * Let the output designated by be called ''triggerOut''. * If the scriptPubKey of ''triggerOut'' is not a witness program of the same version and same tapleaf version as the currently executing script, script execution MUST fail and terminate immediately. * Let the script constructed by taking the and prefixing it with minimally-encoded data pushes of the leaf-update script data items be called the ''leaf-update-script''. -** The leaf-update data items will be in the same order in the ''leaf-update-script'' as they appeared on the stack. +** Note: the leaf-update data items will be in the same order in the ''leaf-update-script'' as they appeared on the stack. * If the scriptPubKey of ''triggerOut'' does not match that of a taptree that is identical to that of the currently evaluated input, but with the leaf script substituted for ''leaf-update-script'', script execution when spending this output MUST fail and terminate immediately. ** Note: the parity bit of the resulting taproot output is allowed to vary, so both values for the new output must be checked. * Let the output designated by (if the index value is non-negative) be called ''revaultOut''. @@ -303,7 +304,7 @@ If none of the conditions fail, a single true value (0x01) is left In order to prevent possible pinning attacks, recovery transactions must be replaceable. -* When validating an OP_VAULT_RECOVER input being spent, the script must FAIL (by policy, not consensus) and terminate immediately if both'''Why are recovery transactions required to be replaceable?''' In the case of unauthorized recoveries, an attacker may attempt to pin recovery transactions by broadcasting a "rebundled" version with a low fee rate. Vault owners must be able to overcome this with replacement. In the case of authorized recovery, if an attacker steals the recovery authorization key, the attacker may try to pin the recovery transaction during theft. Requiring replaceability ensures that the owner can always raise the fee rate of the recovery transaction, even if they are RBF rule #3 griefed in the process. +* When validating an OP_VAULT_RECOVER input being spent, the script MUST fail (by policy, not consensus) and terminate immediately if both'''Why are recovery transactions required to be replaceable?''' In the case of unauthorized recoveries, an attacker may attempt to pin recovery transactions by broadcasting a "rebundled" version with a low fee rate. Vault owners must be able to overcome this with replacement. In the case of authorized recovery, if an attacker steals the recovery authorization key, the attacker may try to pin the recovery transaction during theft. Requiring replaceability ensures that the owner can always raise the fee rate of the recovery transaction, even if they are RBF rule #3 griefed in the process. *# the input is not marked as opt-in replaceable by having an nSequence number less than 0xffffffff - 1, per [https://github.com/bitcoin/bips/blob/master/bip-0125.mediawiki BIP-0125], and *# the version of the recovery transaction has an nVersion other than 3. @@ -325,7 +326,7 @@ A sample implementation is available on bitcoin-inquisition [https://github.com/ == Applications == -The specification above, perhaps surprisingly, does not cover how a relative timelocked withdrawal process with a fixed target is implemented. The tapleaf update semantics specified in OP_VAULT as well as the output-based authorization enabled by OP_VAULT_RECOVER can be used to implement a vault, but they are incomplete without two other pieces: +The specification above, perhaps surprisingly, does not specifically cover how a relative timelocked withdrawal process with a fixed target is implemented. The tapleaf update semantics specified in OP_VAULT as well as the output-based authorization enabled by OP_VAULT_RECOVER can be used to implement a vault, but they are incomplete without two other pieces: * a way to enforce relative timelocks, like OP_CHECKSEQUENCEVERIFY, and * a way to enforce that proposed withdrawals are ultimately being spent to a precise set of outputs, like OP_CHECKTEMPLATEVERIFY. @@ -335,7 +336,7 @@ These two pieces are combined with the tapleaf update capabilities of === Creating a vault === -In order to vault coins, they must be spent into a witness v1 scriptPubKey +In order to vault coins, they can be spent into a witness v1 scriptPubKey that contains a taptree of the form From 6163d36d0b788b8115fd2892f917a301351942de Mon Sep 17 00:00:00 2001 From: Pieter Wuille Date: Tue, 18 Aug 2020 13:55:49 -0700 Subject: [PATCH 087/454] bip340: clarify that tags are byte arrays --- bip-0340.mediawiki | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/bip-0340.mediawiki b/bip-0340.mediawiki index c99b77aa34..e3f61befc2 100644 --- a/bip-0340.mediawiki +++ b/bip-0340.mediawiki @@ -86,7 +86,7 @@ Despite halving the size of the set of valid public keys, implicit Y coordinates For example, without tagged hashing a BIP340 signature could also be valid for a signature scheme where the only difference is that the arguments to the hash function are reordered. Worse, if the BIP340 nonce derivation function was copied or independently created, then the nonce could be accidentally reused in the other scheme leaking the secret key. -This proposal suggests to include the tag by prefixing the hashed data with ''SHA256(tag) || SHA256(tag)''. Because this is a 64-byte long context-specific constant and the ''SHA256'' block size is also 64 bytes, optimized implementations are possible (identical to SHA256 itself, but with a modified initial state). Using SHA256 of the tag name itself is reasonably simple and efficient for implementations that don't choose to use the optimization. +This proposal suggests to include the tag by prefixing the hashed data with ''SHA256(tag) || SHA256(tag)''. Because this is a 64-byte long context-specific constant and the ''SHA256'' block size is also 64 bytes, optimized implementations are possible (identical to SHA256 itself, but with a modified initial state). Using SHA256 of the tag name itself is reasonably simple and efficient for implementations that don't choose to use the optimization. In general, tags can be arbitrary byte arrays, but are suggested to be textual descriptions in UTF-8 encoding. '''Final scheme''' As a result, our final scheme ends up using public key ''pk'' which is the X coordinate of a point ''P'' on the curve whose Y coordinate is even and signatures ''(r,s)'' where ''r'' is the X coordinate of a point ''R'' whose Y coordinate is even. The signature satisfies ''s⋅G = R + tagged_hash(r || pk || m)⋅P''. @@ -116,7 +116,7 @@ The following conventions are used, with constants as defined for [https://www.s *** Let ''y = c(p+1)/4 mod p''. *** Fail if ''c ≠ y2 mod p''. *** Return the unique point ''P'' such that ''x(P) = x'' and ''y(P) = y'' if ''y mod 2 = 0'' or ''y(P) = p-y'' otherwise. -** The function ''hashtag(x)'' where ''tag'' is a UTF-8 encoded tag name and ''x'' is a byte array returns the 32-byte hash ''SHA256(SHA256(tag) || SHA256(tag) || x)''. +** The function ''hashname(x)'' where ''x'' is a byte array returns the 32-byte hash ''SHA256(SHA256(tag) || SHA256(tag) || x)'', where ''tag'' is the UTF-8 encoding of ''name''. ==== Public Key Generation ==== From 200f9b26fe0a2f235a2af8b30c4be9f12f6bc9cb Mon Sep 17 00:00:00 2001 From: Tim Ruffing Date: Wed, 27 Jul 2022 14:39:13 +0200 Subject: [PATCH 088/454] bip340: Allow variable-length messages --- bip-0340.mediawiki | 31 ++++++++++++++++++++++++++++--- bip-0340/reference.py | 4 ---- bip-0340/test-vectors.csv | 4 ++++ bip-0340/test-vectors.py | 20 +++++++++++++++++++- 4 files changed, 51 insertions(+), 8 deletions(-) diff --git a/bip-0340.mediawiki b/bip-0340.mediawiki index e3f61befc2..3b61c578ce 100644 --- a/bip-0340.mediawiki +++ b/bip-0340.mediawiki @@ -138,7 +138,7 @@ As an alternative to generating keys randomly, it is also possible and safe to r Input: * The secret key ''sk'': a 32-byte array -* The message ''m'': a 32-byte array +* The message ''m'': a byte array * Auxiliary random data ''a'': a 32-byte array The algorithm ''Sign(sk, m)'' is defined as: @@ -174,7 +174,7 @@ It should be noted that various alternative signing algorithms can be used to pr Input: * The public key ''pk'': a 32-byte array -* The message ''m'': a 32-byte array +* The message ''m'': a byte array * A signature ''sig'': a 64-byte array The algorithm ''Verify(pk, m, sig)'' is defined as: @@ -197,7 +197,7 @@ Note that the correctness of verification relies on the fact that ''lift_x'' alw Input: * The number ''u'' of signatures * The public keys ''pk1..u'': ''u'' 32-byte arrays -* The messages ''m1..u'': ''u'' 32-byte arrays +* The messages ''m1..u'': ''u'' byte arrays * The signatures ''sig1..u'': ''u'' 64-byte arrays The algorithm ''BatchVerify(pk1..u, m1..u, sig1..u)'' is defined as: @@ -213,6 +213,30 @@ The algorithm ''BatchVerify(pk1..u, m1..u, sig1..u
In theory, the message size is restricted due to the fact that SHA256 accepts byte strings only up to size of 2^61-1 bytes.
+It is understood that implementations may reject messages which are too large in their environment or application context, +e.g., messages which exceed predefined buffers or would otherwise cause resource exhaustion. + +Earlier revisions of this BIP required messages to be exactly 32 bytes. +This restriction puts a burden on callers +who typically need to perform pre-hashing of the actual input message by feeding it through SHA256 (or another collision-resistant cryptographic hash function) +to create a 32-byte digest which can be passed to signing or verification +(as for example done in [[bip-0341.mediawiki|BIP341]].) + +Since pre-hashing may not always be desirable, +e.g., when actual messages are shorter than 32 bytes,Another reason to omit pre-hashing is to protect against certain types of cryptanalytic advances against the hash function used for pre-hashing: If pre-hashing is used, an attacker that can find collisions in the pre-hashing function can necessarily forge signatures under chosen-message attacks. If pre-hashing is not used, an attacker that can find collisions in SHA256 (as used inside the signature scheme) may not be able to forge signatures. However, this seeming advantage is mostly irrelevant in the context of Bitcoin, which already relies on collision resistance of SHA256 in other places, e.g., for transaction hashes. +the restriction to 32-byte messages has been lifted. +We note that pre-hashing is recommended for performance reasons in applications that deal with large messages. +If large messages are not pre-hashed, +the algorithms of the signature scheme will perform more hashing internally. +In particular, the signing algorithm needs two sequential hashing passes over the message, +which means that the full message must necessarily be kept in memory during signing, +and large messages entail a runtime penalty.Typically, messages of 56 bytes or longer enjoy a performance benefit from pre-hashing, assuming the speed of SHA256 inside the signing algorithm matches that of the pre-hashing done by the calling application. + == Applications == There are several interesting applications beyond simple signatures. @@ -248,6 +272,7 @@ The reference implementation is for demonstration purposes only and not to be us To help implementors understand updates to this BIP, we keep a list of substantial changes. * 2022-08: Fix function signature of lift_x in reference code +* 2023-04: Allow messages of arbitrary size == Footnotes == diff --git a/bip-0340/reference.py b/bip-0340/reference.py index 162bb88d99..b327e0a228 100644 --- a/bip-0340/reference.py +++ b/bip-0340/reference.py @@ -96,8 +96,6 @@ def pubkey_gen(seckey: bytes) -> bytes: return bytes_from_point(P) def schnorr_sign(msg: bytes, seckey: bytes, aux_rand: bytes) -> bytes: - if len(msg) != 32: - raise ValueError('The message must be a 32-byte array.') d0 = int_from_bytes(seckey) if not (1 <= d0 <= n - 1): raise ValueError('The secret key must be an integer in the range 1..n-1.') @@ -121,8 +119,6 @@ def schnorr_sign(msg: bytes, seckey: bytes, aux_rand: bytes) -> bytes: return sig def schnorr_verify(msg: bytes, pubkey: bytes, sig: bytes) -> bool: - if len(msg) != 32: - raise ValueError('The message must be a 32-byte array.') if len(pubkey) != 32: raise ValueError('The public key must be a 32-byte array.') if len(sig) != 64: diff --git a/bip-0340/test-vectors.csv b/bip-0340/test-vectors.csv index a1a63e1283..672339129a 100644 --- a/bip-0340/test-vectors.csv +++ b/bip-0340/test-vectors.csv @@ -14,3 +14,7 @@ index,secret key,public key,aux_rand,message,signature,verification result,comme 12,,DFF1D77F2A671C5F36183726DB2341BE58FEAE1DA2DECED843240F7B502BA659,,243F6A8885A308D313198A2E03707344A4093822299F31D0082EFA98EC4E6C89,FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEFFFFFC2F69E89B4C5564D00349106B8497785DD7D1D713A8AE82B32FA79D5F7FC407D39B,FALSE,sig[0:32] is equal to field size 13,,DFF1D77F2A671C5F36183726DB2341BE58FEAE1DA2DECED843240F7B502BA659,,243F6A8885A308D313198A2E03707344A4093822299F31D0082EFA98EC4E6C89,6CFF5C3BA86C69EA4B7376F31A9BCB4F74C1976089B2D9963DA2E5543E177769FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEBAAEDCE6AF48A03BBFD25E8CD0364141,FALSE,sig[32:64] is equal to curve order 14,,FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEFFFFFC30,,243F6A8885A308D313198A2E03707344A4093822299F31D0082EFA98EC4E6C89,6CFF5C3BA86C69EA4B7376F31A9BCB4F74C1976089B2D9963DA2E5543E17776969E89B4C5564D00349106B8497785DD7D1D713A8AE82B32FA79D5F7FC407D39B,FALSE,public key is not a valid X coordinate because it exceeds the field size +15,0340034003400340034003400340034003400340034003400340034003400340,778CAA53B4393AC467774D09497A87224BF9FAB6F6E68B23086497324D6FD117,0000000000000000000000000000000000000000000000000000000000000000,,71535DB165ECD9FBBC046E5FFAEA61186BB6AD436732FCCC25291A55895464CF6069CE26BF03466228F19A3A62DB8A649F2D560FAC652827D1AF0574E427AB63,TRUE,message of size 0 (added 2022-12) +16,0340034003400340034003400340034003400340034003400340034003400340,778CAA53B4393AC467774D09497A87224BF9FAB6F6E68B23086497324D6FD117,0000000000000000000000000000000000000000000000000000000000000000,11,08A20A0AFEF64124649232E0693C583AB1B9934AE63B4C3511F3AE1134C6A303EA3173BFEA6683BD101FA5AA5DBC1996FE7CACFC5A577D33EC14564CEC2BACBF,TRUE,message of size 1 (added 2022-12) +17,0340034003400340034003400340034003400340034003400340034003400340,778CAA53B4393AC467774D09497A87224BF9FAB6F6E68B23086497324D6FD117,0000000000000000000000000000000000000000000000000000000000000000,0102030405060708090A0B0C0D0E0F1011,5130F39A4059B43BC7CAC09A19ECE52B5D8699D1A71E3C52DA9AFDB6B50AC370C4A482B77BF960F8681540E25B6771ECE1E5A37FD80E5A51897C5566A97EA5A5,TRUE,message of size 17 (added 2022-12) +18,0340034003400340034003400340034003400340034003400340034003400340,778CAA53B4393AC467774D09497A87224BF9FAB6F6E68B23086497324D6FD117,0000000000000000000000000000000000000000000000000000000000000000,99999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999,403B12B0D8555A344175EA7EC746566303321E5DBFA8BE6F091635163ECA79A8585ED3E3170807E7C03B720FC54C7B23897FCBA0E9D0B4A06894CFD249F22367,TRUE,message of size 100 (added 2022-12) diff --git a/bip-0340/test-vectors.py b/bip-0340/test-vectors.py index d1bf6b28bc..317f2ece69 100644 --- a/bip-0340/test-vectors.py +++ b/bip-0340/test-vectors.py @@ -249,6 +249,20 @@ def vector14(): return (None, pubkey, None, msg, sig, "FALSE", "public key is not a valid X coordinate because it exceeds the field size") +def varlen_vector(msg_int): + seckey = bytes_from_int(int(16 * "0340", 16)) + pubkey = pubkey_gen(seckey) + aux_rand = bytes_from_int(0) + msg = msg_int.to_bytes((msg_int.bit_length() + 7) // 8, "big") + sig = schnorr_sign(msg, seckey, aux_rand) + comment = "message of size %d (added 2022-12)" + return (seckey, pubkey, aux_rand, msg, sig, "TRUE", comment % len(msg)) + +vector15 = lambda : varlen_vector(0) +vector16 = lambda : varlen_vector(0x11) +vector17 = lambda : varlen_vector(0x0102030405060708090A0B0C0D0E0F1011) +vector18 = lambda : varlen_vector(int(100 * "99", 16)) + vectors = [ vector0(), vector1(), @@ -264,7 +278,11 @@ def vector14(): vector11(), vector12(), vector13(), - vector14() + vector14(), + vector15(), + vector16(), + vector17(), + vector18(), ] # Converts the byte strings of a test vector into hex strings From d80e437ab1660a134c0cdd3e0397f37482e47f43 Mon Sep 17 00:00:00 2001 From: Tim Ruffing Date: Wed, 27 Jul 2022 16:01:04 +0200 Subject: [PATCH 089/454] bip340: Add subsection on Domain Separation --- bip-0340.mediawiki | 20 ++++++++++++++++++++ 1 file changed, 20 insertions(+) diff --git a/bip-0340.mediawiki b/bip-0340.mediawiki index 3b61c578ce..c94191670b 100644 --- a/bip-0340.mediawiki +++ b/bip-0340.mediawiki @@ -237,6 +237,26 @@ In particular, the signing algorithm needs two sequential hashing passes over th which means that the full message must necessarily be kept in memory during signing, and large messages entail a runtime penalty.Typically, messages of 56 bytes or longer enjoy a performance benefit from pre-hashing, assuming the speed of SHA256 inside the signing algorithm matches that of the pre-hashing done by the calling application. +==== Domain Separation ==== + +It is good cryptographic practice to use a key pair only for a single purpose. +Nevertheless, there may be situations in which it may be desirable to use the same key pair in multiple contexts, +i.e., to sign different types of messages within the same application +or even messages in entirely different applications +(e.g., a secret key may be used to sign Bitcoin transactions as well plain text messages). + +As a consequence, applications should ensure that a signed application message intended for one context is never deemed valid in a different context +(e.g., a signed plain text message should never be misinterpreted as a signed Bitcoin transaction, because this could cause unintended loss of funds). +This is called "domain separation" and it is typically realized by partitioning the message space. +Even if key pairs are intended to be used only within a single context, +domain separation is a good idea because it makes it easy to add more contexts later. + +As a best practice, we recommend applications to use exactly one of the following methods to pre-process application messages before passing it to the signature scheme: +* Either, pre-hash the application message using ''hashname'', where ''name'' identifies the context uniquely (e.g., "foo-app/signed-bar"), +* or prefix the actual message with a 33-byte string that identifies the context uniquely (e.g., the UTF-8 encoding of "foo-app/signed-bar", padded with null bytes to 33 bytes). + +As the two pre-processing methods yield different message sizes (32 bytes vs. at least 33 bytes), there is no risk of collision between them. + == Applications == There are several interesting applications beyond simple signatures. From da6f9ed17c59743a725600bb647c9efdae10e2b0 Mon Sep 17 00:00:00 2001 From: stratospher <44024636+stratospher@users.noreply.github.com> Date: Wed, 26 Apr 2023 21:41:17 +0530 Subject: [PATCH 090/454] bip324: fix link to chacha20 --- bip-0324.mediawiki | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/bip-0324.mediawiki b/bip-0324.mediawiki index c0572a3313..ced459bfa1 100644 --- a/bip-0324.mediawiki +++ b/bip-0324.mediawiki @@ -396,7 +396,7 @@ Packet encryption is built on two existing primitives: * '''ChaCha20Poly1305''' is specified as AEAD_CHACHA20_POLY1305 in [https://datatracker.ietf.org/doc/html/rfc8439#section-2.8 RFC 8439 section 2.8]. It is an authenticated encryption protocol with associated data (AEAD), taking a 256-bit key, 96-bit nonce, and an arbitrary-length byte array of associated authenticated data (AAD). Due to the built-in authentication tag, ciphertexts are 16 bytes longer than the corresponding plaintext. In what follows: ** aead_chacha20_poly1305_encrypt(key, nonce, aad, plaintext) refers to a function that takes as input a 32-byte array ''key'', a 12-byte array ''nonce'', an arbitrary-length byte array ''aad'', and an arbitrary-length byte array ''plaintext'', and returns a byte array ''ciphertext'', 16 bytes longer than the plaintext. ** aead_chacha20_poly1305_decrypt(key, nonce, aad, ciphertext) refers to a function that takes as input a 32-byte array ''key'', a 12-byte array ''nonce'', an arbitrary-length byte array ''aad'', and an arbitrary-length byte array ''ciphertext'', and returns either a byte array ''plaintext'' (16 bytes shorter than the ciphertext), or ''None'' in case the ciphertext was not a valid ChaCha20Poly1305 encryption of any plaintext with the specified ''key'', ''nonce'', and ''aad''. -* The '''ChaCha20 Block Function''' is specified in [https://datatracker.ietf.org/doc/html/rfc8439#section-2.8 RFC 8439 section 2.3]. It is a pseudorandom function (PRF) taking a 256-bit key, 96-bit nonce, and 32-bit counter, and outputs 64 pseudorandom bytes. It is the underlying building block on which ChaCha20 (and ultimately, ChaCha20Poly1305) is built. In what follows: +* The '''ChaCha20 Block Function''' is specified in [https://datatracker.ietf.org/doc/html/rfc8439#section-2.3 RFC 8439 section 2.3]. It is a pseudorandom function (PRF) taking a 256-bit key, 96-bit nonce, and 32-bit counter, and outputs 64 pseudorandom bytes. It is the underlying building block on which ChaCha20 (and ultimately, ChaCha20Poly1305) is built. In what follows: ** chacha20_block(key, nonce, count) refers to a function that takes as input a 32-byte array ''key'', a 12-byte array ''nonce'', and an integer ''count'' in range ''0..232-1'', and returns a byte array of length 64. These will be used for plaintext encryption and length encryption, respectively. From 5f3e216d3f144ff353786a49b534d927d0dc2ddc Mon Sep 17 00:00:00 2001 From: yahiheb <52379387+yahiheb@users.noreply.github.com> Date: Thu, 27 Apr 2023 08:19:38 +0100 Subject: [PATCH 091/454] Fix text format --- bip-0039.mediawiki | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/bip-0039.mediawiki b/bip-0039.mediawiki index d8a4d253d6..2180b6c407 100644 --- a/bip-0039.mediawiki +++ b/bip-0039.mediawiki @@ -39,7 +39,7 @@ security is improved but the sentence length increases. We refer to the initial entropy length as ENT. The allowed size of ENT is 128-256 bits. First, an initial entropy of ENT bits is generated. A checksum is generated by -taking the first
ENT / 32
bits of its SHA256 hash. This checksum is +taking the first ENT / 32 bits of its SHA256 hash. This checksum is appended to the end of the initial entropy. Next, these concatenated bits are split into groups of 11 bits, each encoding a number from 0-2047, serving as an index into a wordlist. Finally, we convert these numbers into words and From 9b03e64c93353bec0ce8c6db3c2769e5edcf45e4 Mon Sep 17 00:00:00 2001 From: Christian Lewe Date: Thu, 18 May 2023 18:08:00 +0200 Subject: [PATCH 092/454] Mark bech32m as final --- README.mediawiki | 2 +- bip-0350.mediawiki | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/README.mediawiki b/README.mediawiki index 0d834b15e8..015038ed07 100644 --- a/README.mediawiki +++ b/README.mediawiki @@ -1077,7 +1077,7 @@ Those proposing changes should consider that ultimately consent may rest with th | Bech32m format for v1+ witness addresses | Pieter Wuille | Standard -| Draft +| Final |- | [[bip-0351.mediawiki|351]] | Applications diff --git a/bip-0350.mediawiki b/bip-0350.mediawiki index 9873d80966..439b2a25a9 100644 --- a/bip-0350.mediawiki +++ b/bip-0350.mediawiki @@ -5,7 +5,7 @@ Author: Pieter Wuille Comments-Summary: No comments yet. Comments-URI: https://github.com/bitcoin/bips/wiki/Comments:BIP-0350 - Status: Draft + Status: Final Type: Standards Track Created: 2020-12-16 License: BSD-2-Clause From 1684344515eb1ec29fd931cbfacc86584572890f Mon Sep 17 00:00:00 2001 From: Seth For Privacy Date: Mon, 15 May 2023 12:01:58 -0400 Subject: [PATCH 093/454] Add `spendable` state --- bip-0329.mediawiki | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/bip-0329.mediawiki b/bip-0329.mediawiki index 737a75d77a..3440614487 100644 --- a/bip-0329.mediawiki +++ b/bip-0329.mediawiki @@ -62,6 +62,9 @@ Each JSON object must contain 3 or 4 key/value pairs, defined as follows: |- | origin | Optional key origin information referencing the wallet associated with the label +|- +| spendable +| One of true or false, denoting if an output should be spendable by the wallet |} The reference is defined for each type as follows: @@ -110,6 +113,7 @@ For security reasons no private key types are defined. * An importing wallet may ignore records it does not store, and truncate labels if necessary. A suggested default for maximum label length is 255 characters, and an importing wallet should consider warning the user if truncation is applied. * Wallets importing public key records may derive addresses from them to match against known wallet addresses. * Wallets importing extended public keys may match them against signers, for example in a multisig setup. +* Wallets importing outputs should respect the spendable state, defaulting to true if none is found ==Backwards Compatibility== @@ -124,7 +128,7 @@ The following fragment represents a wallet label export: { "type": "addr", "ref": "bc1q34aq5drpuwy3wgl9lhup9892qp6svr8ldzyy7c", "label": "Address" } { "type": "pubkey", "ref": "0283409659355b6d1cc3c32decd5d561abaac86c37a353b52895a5e6c196d6f448", "label": "Public Key" } { "type": "input", "ref": "f91d0a8a78462bc59398f2c5d7a84fcff491c26ba54c4833478b202796c8aafd:0", "label": "Input" } -{ "type": "output", "ref": "f91d0a8a78462bc59398f2c5d7a84fcff491c26ba54c4833478b202796c8aafd:1", "label": "Output" } +{ "type": "output", "ref": "f91d0a8a78462bc59398f2c5d7a84fcff491c26ba54c4833478b202796c8aafd:1", "label": "Output" , "spendable" : "false" } { "type": "xpub", "ref": "xpub661MyMwAqRbcFtXgS5sYJABqqG9YLmC4Q1Rdap9gSE8NqtwybGhePY2gZ29ESFjqJoCu1Rupje8YtGqsefD265TMg7usUDFdp6W1EGMcet8", "label": "Extended Public Key" } { "type": "tx", "ref": "f546156d9044844e02b181026a1a407abfca62e7ea1159f87bbeaa77b4286c74", "label": "Account #1 Transaction", "origin": "wpkh([d34db33f/84'/0'/1'])" } From d20444a3ae65296b3c8b3f364c63618662218c4f Mon Sep 17 00:00:00 2001 From: Seth For Privacy Date: Mon, 15 May 2023 13:22:19 -0400 Subject: [PATCH 094/454] Add motivation for spendable tag --- bip-0329.mediawiki | 2 ++ 1 file changed, 2 insertions(+) diff --git a/bip-0329.mediawiki b/bip-0329.mediawiki index 3440614487..d79175c0a6 100644 --- a/bip-0329.mediawiki +++ b/bip-0329.mediawiki @@ -26,8 +26,10 @@ These standards are well supported and allow users to move easily between differ There is, however, no defined standard to transfer any labels the user may have applied to the transactions, addresses, public keys, inputs, outputs or xpubs in their wallet. The UTXO model that Bitcoin uses makes these labels particularly valuable as they may indicate the source of funds, whether received externally or as a result of change from a prior transaction. In both cases, care must be taken when spending to avoid undesirable leaks of private information. + Labels provide valuable guidance in this regard, and have even become mandatory when spending in several Bitcoin wallets. Allowing users to import and export their labels in a standardized way ensures that they do not experience lock-in to a particular wallet application. +In addition, many wallets allow unspent outputs to be frozen or made unspendable within the wallet. Since this wallet-related metadata is similar to labels and not captured elsewhere, it is also included in this format. ==Rationale== From fc0950e07eac6de2ebf68aa0493f17d3024fbe7c Mon Sep 17 00:00:00 2001 From: Seth For Privacy Date: Tue, 30 May 2023 09:42:26 -0400 Subject: [PATCH 095/454] Properly handle `spendable` state and JSON edge cases --- bip-0329.mediawiki | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/bip-0329.mediawiki b/bip-0329.mediawiki index d79175c0a6..fc5da4253c 100644 --- a/bip-0329.mediawiki +++ b/bip-0329.mediawiki @@ -102,6 +102,8 @@ The reference is defined for each type as follows: | xpub661MyMwAqRbcFtXgS5sYJABqqG9YLmC4Q1Rdap9gSE8Nq... |} +Each JSON object must contain both type and ref properties. The label, origin and spendable properties are optional. If the label or spendable properties are omitted, the importing wallet should not alter these values. The origin property should only appear where type is tx, and the spendable property only where type is output. + If present, the optional origin property must contain an abbreviated output descriptor (as defined by BIP380[https://github.com/bitcoin/bips/blob/master/bip-0380.mediawiki BIP-0380]) describing a BIP32 compatible originating wallet, including all key origin information but excluding any actual keys, any child path elements, or a checksum. This property should be used to disambiguate transaction labels from different wallets contained in the same export, particularly when exporting multiple accounts derived from the same seed. @@ -115,7 +117,6 @@ For security reasons no private key types are defined. * An importing wallet may ignore records it does not store, and truncate labels if necessary. A suggested default for maximum label length is 255 characters, and an importing wallet should consider warning the user if truncation is applied. * Wallets importing public key records may derive addresses from them to match against known wallet addresses. * Wallets importing extended public keys may match them against signers, for example in a multisig setup. -* Wallets importing outputs should respect the spendable state, defaulting to true if none is found ==Backwards Compatibility== From 8f506d8e2759fcf6970d0085fc70e702ace182ca Mon Sep 17 00:00:00 2001 From: Luis Miguel Date: Tue, 6 Jun 2023 15:47:37 +0200 Subject: [PATCH 096/454] Typos in bip-0119 --- bip-0119.mediawiki | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/bip-0119.mediawiki b/bip-0119.mediawiki index aa226d0be1..86defa7cf7 100644 --- a/bip-0119.mediawiki +++ b/bip-0119.mediawiki @@ -61,7 +61,7 @@ references. ==Detailed Specification== The below code is the main logic for verifying CHECKTEMPLATEVERIFY, described -in pythonic pseduocode. The canonical specification for the semantics of +in pythonic pseudocode. The canonical specification for the semantics of OP_CHECKTEMPLATEVERIFY as implemented in C++ in the context of Bitcoin Core can be seen in the reference implementation. @@ -225,12 +225,12 @@ A recent commit hash in that PR including tests and vectors can be found here ht Once the PR is merged, this BIP should be updated to point to the specific code released. Test vectors are available in [/bip-0119/vectors the bip-0119/vectors -directory] for checking compatibility with the refrence implementation and BIP. +directory] for checking compatibility with the reference implementation and BIP. ==Rationale== The goal of CHECKTEMPLATEVERIFY is to be minimal impact on the existing codebase -- in the -future, as we become aware of more complex but shown to be safe use cases new template types can be added. +future, as we become aware of more complex but shown to be safe use cases, new template types can be added. Below we'll discuss the rules one-by-one: @@ -250,7 +250,7 @@ Were these values not committed, it would be possible to delay the spending of an output arbitrarily as well as possible to change the TXID. Committing these values, rather than restricting them to specific values, is -more flexible as it permits users of CHECKTEMPLATEVERIFY the set the version and +more flexible as it permits users of CHECKTEMPLATEVERIFY to set the version and locktime as they please. =====Committing to the ScriptSigs Hash===== @@ -258,7 +258,7 @@ locktime as they please. The scriptsig in a segwit transaction must be exactly empty, unless it is a P2SH segwit transaction in which case it must be only the exact redeemscript. P2SH is incompatible (unless the P2SH hash is broken) with CHECKTEMPLATEVERIFY because the template hash must commit -to the ScriptSig, which must contain the redeemscript, which is a hash cycle. +to the ScriptSig, which must contain the redeemscript, which is a hash cycle. To prevent malleability when not using a segwit input, we also commit to the scriptsig. This makes it possible to use a 2 input CHECKTEMPLATEVERIFY with a legacy pre-signed From cb50446a65cb8504499e1ebded22539188612bb3 Mon Sep 17 00:00:00 2001 From: James O'Beirne Date: Wed, 14 Jun 2023 16:36:43 -0400 Subject: [PATCH 097/454] fixup! add and clarify deferred checks This change makes the amount being revaulted (if any) explicit to avoid issues surfaced by AJ Towns (e.g. multiple compatible vault inputs duplicating triggers and revaults to confuse the old deferred check logic). Pseudocode is also provided for the deferred checks, and their inline validation description has been changed to be more faithful to the implementation - we make mention of queueing deferred checks, and then later describe the algorithm used to aggregate and perform them. --- bip-0345.mediawiki | 73 +++++++++++++++++++++++++++++++++++++++++++--- 1 file changed, 69 insertions(+), 4 deletions(-) diff --git a/bip-0345.mediawiki b/bip-0345.mediawiki index 4005d11a58..b7692ebe86 100644 --- a/bip-0345.mediawiki +++ b/bip-0345.mediawiki @@ -235,6 +235,7 @@ When evaluating OP_VAULT (OP_SUCCESS187, [ n leaf-update script data items ... ] + where @@ -258,6 +259,11 @@ where ** If this value does not decode to a valid CScriptNum, script execution when spending this output MUST fail and terminate immediately. ** If this value is greater than or equal to the number of outputs, script execution when spending this output MUST fail and terminate immediately. +* is an up to 7-byte CScriptNum-encoded number indicating the number of satoshis being revaulted. +** If this value does not decode to a valid CScriptNum, script execution when spending this output MUST fail and terminate immediately. +** If this value is not greater than or equal to 0, script execution when spending this output MUST fail and terminate immediately. +** If this value is non-zero but is negative, script execution when spending this output MUST fail and terminate immediately. + After the stack is parsed, the following validation checks are performed: * Let the output designated by be called ''triggerOut''. @@ -268,8 +274,11 @@ After the stack is parsed, the following validation checks are performed: ** Note: the parity bit of the resulting taproot output is allowed to vary, so both values for the new output must be checked. * Let the output designated by (if the index value is non-negative) be called ''revaultOut''. * If the scriptPubKey of ''revaultOut'' is not equal to the scriptPubKey of the input being spent, script execution when spending this output MUST fail and terminate immediately. -* If the sum of the amounts of ''triggerOut'' and ''revaultOut'' (if any) are not greater than or equal to the value of this input, script execution when spending this output MUST fail and terminate immediately. -* (Deferred'''What is a deferred check and why does this proposal require them for correct script evaluation?''' A deferred check is a validation check that is executed only after all input scripts have been validated, and is based on aggregate information collected during each input's EvalScript run.

Currently, the validity of each input is (usually) checked concurrently across all inputs in a transaction. Because this proposal allows batching the spend of multiple vault inputs into a single recovery or withdrawal output, we need a mechanism to ensure that all expected values per output can be summed and then checked. This necessitates the introduction of an "aggregating" set of checks which can only be executed after each input's script is evaluated. Note that similar functionality would be required for batch input validation or cross-input signature aggregation.
) the nValue of ''triggerOut'', plus the nValue of ''revaultOut'' if one exists, must equal the sum of all vault inputs which cite it as their corresponding trigger output. If these values are not equal, the script MUST fail and terminate immediately. +* Implemetation recommendation: if the sum of the amounts of ''triggerOut'' and ''revaultOut'' (if any) are not greater than or equal to the value of this input, script execution when spending this output SHOULD fail and terminate immediately. +** Amount checks are ultimately done with deferred checks, but this check can help short-circuit obviously invalid spends. +* Queue a deferred check'''What is a deferred check and why does this proposal require them for correct script evaluation?''' A deferred check is a validation check that is executed only after all input scripts have been validated, and is based on aggregate information collected during each input's EvalScript run.

Currently, the validity of each input is (usually) checked concurrently across all inputs in a transaction. Because this proposal allows batching the spend of multiple vault inputs into a single recovery or withdrawal output, we need a mechanism to ensure that all expected values per output can be summed and then checked. This necessitates the introduction of an "aggregating" set of checks which can only be executed after each input's script is evaluated. Note that similar functionality would be required for batch input validation or cross-input signature aggregation.
that ensures the satoshis for this input's nValue minus are included within the output nValue found at . +* Queue a deferred check that ensures satoshis, if non-zero, are included within the output's nValue found at . +** These deferred checks could be characterized in terms of the pseudocode below (in ''Deferred checks'') as
TriggerCheck(input_amount, , , ). If none of the conditions fail, a single true value (0x01) is left on the stack. @@ -295,11 +304,66 @@ After the stack is parsed, the following validation checks are performed: * Let the output at index be called ''recoveryOut''. * If the scriptPubKey of ''recoveryOut'' does not have a tagged hash equal to (tagged_hash("VaultRecoverySPK", recoveryOut.scriptPubKey) == recovery-sPK-hash, where tagged_hash() is from the [https://github.com/bitcoin/bips/blob/master/bip-0340/reference.py BIP-0340 reference code]), script execution when spending this output MUST fail and terminate immediately. -* If ''recoveryOut'' does not have an nValue greater than or equal to this input's amount, the script MUST fail and terminate immediately. -* (Deferred) if ''recoveryOut'' does not have an nValue equal to the sum of all OP_VAULT_RECOVER-spent inputs with a corresponding recovery-sPK-hash, the transaction validation MUST fail.'''How do recovery transactions pay for fees?''' If the recovery is unauthorized, fees are attached either via CPFP with an ephemeral anchor or as inputs which are solely spent to fees (i.e. no change output). If the recovery is authorized, fees can be attached in any manner, e.g. unrelated inputs and outputs or CPFP via anchor. +** Implementation recommendation: if ''recoveryOut'' does not have an nValue greater than or equal to this input's amount, the script SHOULD fail and terminate immediately. +* Queue a deferred check that ensures the nValue of ''recoveryOut'' contains the entire nValue of this input.'''How do recovery transactions pay for fees?''' If the recovery is unauthorized, fees are attached either via CPFP with an ephemeral anchor or as inputs which are solely spent to fees (i.e. no change output). If the recovery is authorized, fees can be attached in any manner, e.g. unrelated inputs and outputs or CPFP via anchor. +** This deferred check could be characterized in terms of the pseudocode below as RecoveryCheck(, input_amount). If none of the conditions fail, a single true value (0x01) is left on the stack. +=== Deferred check evaluation === + +Once all inputs for a transaction are validated per the rules above, any +deferred checks queued MUST be evaluated. + +The Python pseudocode for this is as follows: + + +class TriggerCheck: + """Queued by evaluation of OP_VAULT (withdrawal trigger).""" + input_amount: int + revault_amount: int + trigger_vout_idx: int + revault_vout_idx: int + + +class RecoveryCheck: + """Queued by evaluation of OP_VAULT_RECOVER.""" + input_amount: int + vout_idx: int + + +def validate_deferred_checks(checks: [DeferredCheck], tx: Transaction) -> bool: + """ + Ensure that all value from vault inputs being triggered or recovered is preserved + in suitable output nValues. + """ + # Map to hold expected output values. + out_map: Dict[int, int] = defaultdict(lambda: 0) + + for c in checks: + if isinstance(c, TriggerCheck): + out_map[c.trigger_vout_idx] += (c.input_amount - c.revault_amount) + + if c.revault_amount > 0: + out_map[c.revault_vout_idx] += c.revault_amount + + elif isinstance(c, RecoveryCheck): + out_map[c.vout_idx] += c.input_amount + + for (vout_idx, amount_sats) in out_map.items(): + if tx.vout[vout_idx].nValue != amount_sats: + return False + + return True + + +If the above procedure, or an equivalent, returns false, script execution MUST fail and terminate +immediately. + +This ensures that all compatible vault inputs can be batched into shared +corresponding trigger or recovery outputs while preserving their entire input value. + + == Policy changes == In order to prevent possible pinning attacks, recovery transactions must be replaceable. @@ -377,6 +441,7 @@ full leaf-update script (in this case, a timelocked CTV script): Witness stack: +- - (-1 if none) - - From e2ff23b3f07215450e75779f7f944d24660a9d47 Mon Sep 17 00:00:00 2001 From: James O'Beirne Date: Wed, 28 Jun 2023 12:06:35 -0400 Subject: [PATCH 098/454] fiuxp! allow larger trigger/recovery output amounts Allow trigger/recovery output nValues to exceed the amounts supplied by constituent vault inputs. This allows future compatibility for e.g. trigger collateral. --- bip-0345.mediawiki | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/bip-0345.mediawiki b/bip-0345.mediawiki index b7692ebe86..1447346b15 100644 --- a/bip-0345.mediawiki +++ b/bip-0345.mediawiki @@ -351,7 +351,9 @@ def validate_deferred_checks(checks: [DeferredCheck], tx: Transaction) -> bool: out_map[c.vout_idx] += c.input_amount for (vout_idx, amount_sats) in out_map.items(): - if tx.vout[vout_idx].nValue != amount_sats: + # Trigger/recovery value can be greater than the constituent vault input + # amounts. + if tx.vout[vout_idx].nValue < amount_sats: return False return True From bb562aa8e9c438e653668b08e5c16b7e71abc832 Mon Sep 17 00:00:00 2001 From: Andrew Chow Date: Thu, 29 Jun 2023 16:15:14 -0400 Subject: [PATCH 099/454] descriptors: add test vectors --- bip-0380.mediawiki | 57 ++++++++++++++++++++++++++++++++++++++++++++++ bip-0381.mediawiki | 46 ++++++++++++++++++++++++++++++++++++- bip-0382.mediawiki | 47 +++++++++++++++++++++++++++++++++++++- bip-0383.mediawiki | 32 +++++++++++++++++++++++++- bip-0384.mediawiki | 33 ++++++++++++++++++++++++++- bip-0385.mediawiki | 20 +++++++++++++++- bip-0386.mediawiki | 23 ++++++++++++++++++- bip-0389.mediawiki | 34 ++++++++++++++++++++++++++- 8 files changed, 285 insertions(+), 7 deletions(-) diff --git a/bip-0380.mediawiki b/bip-0380.mediawiki index 16a2cf4d12..48dd93f9e8 100644 --- a/bip-0380.mediawiki +++ b/bip-0380.mediawiki @@ -199,6 +199,63 @@ def descsum_create(s): +==Test Vectors== + +The following tests cover the checksum and character set: + +* Valid checksum: raw(deadbeef)#89f8spxm +* No checksum: raw(deadbeef) +* Missing checksum: raw(deadbeef)# +* Too long checksum (9 chars): raw(deadbeef)#89f8spxmx +* Too short checksum (7 chars): raw(deadbeef)#89f8spx +* Error in payload: raw(deedbeef)#89f8spxm +* Error in checksum: raw(deedbeef)##9f8spxm +* Invalid characters in payload: raw(Ü)#00000000 + +The following tests cover key expressions: + +Valid expressions: + +* Compressed public key: 0260b2003c386519fc9eadf2b5cf124dd8eea4c4e68d5e154050a9346ea98ce600 +* Uncompressed public key: 04a34b99f22c790c4e36b2b3c2c35a36db06226e41c692fc82b8b56ac1c540c5bd5b8dec5235a0fa8722476c7709c02559e3aa73aa03918ba2d492eea75abea235 +* Public key with key origin: [deadbeef/0h/0h/0h]0260b2003c386519fc9eadf2b5cf124dd8eea4c4e68d5e154050a9346ea98ce600 +* Public key with key origin (' as hardened indicator): [deadbeef/0'/0'/0']0260b2003c386519fc9eadf2b5cf124dd8eea4c4e68d5e154050a9346ea98ce600 +* Public key with key origin (mixed hardened indicator): [deadbeef/0'/0h/0']0260b2003c386519fc9eadf2b5cf124dd8eea4c4e68d5e154050a9346ea98ce600 +* WIF uncompressed private key 5KYZdUEo39z3FPrtuX2QbbwGnNP5zTd7yyr2SC1j299sBCnWjss +* WIF compressed private key L4rK1yDtCWekvXuE6oXD9jCYfFNV2cWRpVuPLBcCU2z8TrisoyY1 +* Extended public key: xpub6ERApfZwUNrhLCkDtcHTcxd75RbzS1ed54G1LkBUHQVHQKqhMkhgbmJbZRkrgZw4koxb5JaHWkY4ALHY2grBGRjaDMzQLcgJvLJuZZvRcEL +* Extended public key with key origin: [deadbeef/0h/1h/2h]xpub6ERApfZwUNrhLCkDtcHTcxd75RbzS1ed54G1LkBUHQVHQKqhMkhgbmJbZRkrgZw4koxb5JaHWkY4ALHY2grBGRjaDMzQLcgJvLJuZZvRcEL +* Extended public key with derivation: [deadbeef/0h/1h/2h]xpub6ERApfZwUNrhLCkDtcHTcxd75RbzS1ed54G1LkBUHQVHQKqhMkhgbmJbZRkrgZw4koxb5JaHWkY4ALHY2grBGRjaDMzQLcgJvLJuZZvRcEL/3/4/5 +* Extended public key with derivation and children: [deadbeef/0h/1h/2h]xpub6ERApfZwUNrhLCkDtcHTcxd75RbzS1ed54G1LkBUHQVHQKqhMkhgbmJbZRkrgZw4koxb5JaHWkY4ALHY2grBGRjaDMzQLcgJvLJuZZvRcEL/3/4/5/* +* Extended public key with hardened derivation and unhardened children: xpub6ERApfZwUNrhLCkDtcHTcxd75RbzS1ed54G1LkBUHQVHQKqhMkhgbmJbZRkrgZw4koxb5JaHWkY4ALHY2grBGRjaDMzQLcgJvLJuZZvRcEL/3h/4h/5h/* +* Extended public key with hardened derivation and children: xpub6ERApfZwUNrhLCkDtcHTcxd75RbzS1ed54G1LkBUHQVHQKqhMkhgbmJbZRkrgZw4koxb5JaHWkY4ALHY2grBGRjaDMzQLcgJvLJuZZvRcEL/3h/4h/5h/*h +* Extended public key with key origin, hardened derivation and children: [deadbeef/0h/1h/2]xpub6ERApfZwUNrhLCkDtcHTcxd75RbzS1ed54G1LkBUHQVHQKqhMkhgbmJbZRkrgZw4koxb5JaHWkY4ALHY2grBGRjaDMzQLcgJvLJuZZvRcEL/3h/4h/5h/*h +* Extended private key: xprvA1RpRA33e1JQ7ifknakTFpgNXPmW2YvmhqLQYMmrj4xJXXWYpDPS3xz7iAxn8L39njGVyuoseXzU6rcxFLJ8HFsTjSyQbLYnMpCqE2VbFWc +* Extended private key with key origin: [deadbeef/0h/1h/2h]xprvA1RpRA33e1JQ7ifknakTFpgNXPmW2YvmhqLQYMmrj4xJXXWYpDPS3xz7iAxn8L39njGVyuoseXzU6rcxFLJ8HFsTjSyQbLYnMpCqE2VbFWc +* Extended private key with derivation: [deadbeef/0h/1h/2h]xprvA1RpRA33e1JQ7ifknakTFpgNXPmW2YvmhqLQYMmrj4xJXXWYpDPS3xz7iAxn8L39njGVyuoseXzU6rcxFLJ8HFsTjSyQbLYnMpCqE2VbFWc/3/4/5 +* Extended private key with derivation and children: [deadbeef/0h/1h/2h]xprvA1RpRA33e1JQ7ifknakTFpgNXPmW2YvmhqLQYMmrj4xJXXWYpDPS3xz7iAxn8L39njGVyuoseXzU6rcxFLJ8HFsTjSyQbLYnMpCqE2VbFWc/3/4/5/* +* Extended private key with hardened derivation and unhardened children: xprvA1RpRA33e1JQ7ifknakTFpgNXPmW2YvmhqLQYMmrj4xJXXWYpDPS3xz7iAxn8L39njGVyuoseXzU6rcxFLJ8HFsTjSyQbLYnMpCqE2VbFWc/3h/4h/5h/* +* Extended private key with hardened derivation and children: xprvA1RpRA33e1JQ7ifknakTFpgNXPmW2YvmhqLQYMmrj4xJXXWYpDPS3xz7iAxn8L39njGVyuoseXzU6rcxFLJ8HFsTjSyQbLYnMpCqE2VbFWc/3h/4h/5h/*h +* Extended private key with key origin, hardened derivation and children: [deadbeef/0h/1h/2]xprvA1RpRA33e1JQ7ifknakTFpgNXPmW2YvmhqLQYMmrj4xJXXWYpDPS3xz7iAxn8L39njGVyuoseXzU6rcxFLJ8HFsTjSyQbLYnMpCqE2VbFWc/3h/4h/5h/*h + +Invalid expressiosn: + +* Children indicator in key origin: [deadbeef/0h/0h/0h/*]0260b2003c386519fc9eadf2b5cf124dd8eea4c4e68d5e154050a9346ea98ce600 +* Trailing slash in key origin: [deadbeef/0h/0h/0h/]0260b2003c386519fc9eadf2b5cf124dd8eea4c4e68d5e154050a9346ea98ce600 +* Too short fingerprint: [deadbef/0h/0h/0h]0260b2003c386519fc9eadf2b5cf124dd8eea4c4e68d5e154050a9346ea98ce600 +* Too long fingerprint: [deadbeeef/0h/0h/0h]0260b2003c386519fc9eadf2b5cf124dd8eea4c4e68d5e154050a9346ea98ce600 +* Invalid hardened indicators: [deadbeeef/0f/0f/0f]0260b2003c386519fc9eadf2b5cf124dd8eea4c4e68d5e154050a9346ea98ce600 +* Invalid hardened indicators: [deadbeeef/0H/0H/0H]0260b2003c386519fc9eadf2b5cf124dd8eea4c4e68d5e154050a9346ea98ce600 +* Invalid hardened indicators: [deadbeeef/-0/-0/-0]0260b2003c386519fc9eadf2b5cf124dd8eea4c4e68d5e154050a9346ea98ce600 +* Private key with derivation: L4rK1yDtCWekvXuE6oXD9jCYfFNV2cWRpVuPLBcCU2z8TrisoyY1/0 +* Private key with derivation children: L4rK1yDtCWekvXuE6oXD9jCYfFNV2cWRpVuPLBcCU2z8TrisoyY1/* +* Derivation index out of range: xprv9s21ZrQH143K31xYSDQpPDxsXRTUcvj2iNHm5NUtrGiGG5e2DtALGdso3pGz6ssrdK4PFmM8NSpSBHNqPqm55Qn3LqFtT2emdEXVYsCzC2U/2147483648)", "pkh(xpub661MyMwAqRbcFW31YEwpkMuc5THy2PSt5bDMsktWQcFF8syAmRUapSCGu8ED9W6oDMSgv6Zz8idoc4a6mr8BDzTJY47LJhkJ8UB7WEGuduB/2147483648 +* Invalid derivation index: xprv9s21ZrQH143K31xYSDQpPDxsXRTUcvj2iNHm5NUtrGiGG5e2DtALGdso3pGz6ssrdK4PFmM8NSpSBHNqPqm55Qn3LqFtT2emdEXVYsCzC2U/1aa)", "pkh(xpub661MyMwAqRbcFW31YEwpkMuc5THy2PSt5bDMsktWQcFF8syAmRUapSCGu8ED9W6oDMSgv6Zz8idoc4a6mr8BDzTJY47LJhkJ8UB7WEGuduB/1aa +* Multiple key origins: [aaaaaaaa][aaaaaaaa]xprv9s21ZrQH143K31xYSDQpPDxsXRTUcvj2iNHm5NUtrGiGG5e2DtALGdso3pGz6ssrdK4PFmM8NSpSBHNqPqm55Qn3LqFtT2emdEXVYsCzC2U/2147483647'/0 +* Missing key origin start: aaaaaaaa]xprv9s21ZrQH143K31xYSDQpPDxsXRTUcvj2iNHm5NUtrGiGG5e2DtALGdso3pGz6ssrdK4PFmM8NSpSBHNqPqm55Qn3LqFtT2emdEXVYsCzC2U/2147483647'/0 +* Non hex fingerprint: [gaaaaaaa]xprv9s21ZrQH143K31xYSDQpPDxsXRTUcvj2iNHm5NUtrGiGG5e2DtALGdso3pGz6ssrdK4PFmM8NSpSBHNqPqm55Qn3LqFtT2emdEXVYsCzC2U/2147483647'/0 +* Key origin with no public key: [deadbeef] + ==Backwards Compatibility== Output script descriptors are an entirely new language which is not compatible with any existing software. diff --git a/bip-0381.mediawiki b/bip-0381.mediawiki index f4395971c3..769b42d268 100644 --- a/bip-0381.mediawiki +++ b/bip-0381.mediawiki @@ -70,7 +70,51 @@ OP_HASH160 OP_EQUAL ==Test Vectors== -TBD +Valid descriptors followed by the scripts they produce. Descriptors involving derived child keys will have the 0th, 1st, and 2nd scripts listed. + +* pk(L4rK1yDtCWekvXuE6oXD9jCYfFNV2cWRpVuPLBcCU2z8TrisoyY1) +** 2103a34b99f22c790c4e36b2b3c2c35a36db06226e41c692fc82b8b56ac1c540c5bdac +* pk(03a34b99f22c790c4e36b2b3c2c35a36db06226e41c692fc82b8b56ac1c540c5bd) +** 2103a34b99f22c790c4e36b2b3c2c35a36db06226e41c692fc82b8b56ac1c540c5bdac +* pkh([deadbeef/1/2'/3/4']L4rK1yDtCWekvXuE6oXD9jCYfFNV2cWRpVuPLBcCU2z8TrisoyY1) +** 76a9149a1c78a507689f6f54b847ad1cef1e614ee23f1e88ac +* pkh([deadbeef/1/2'/3/4']03a34b99f22c790c4e36b2b3c2c35a36db06226e41c692fc82b8b56ac1c540c5bd) +** 76a9149a1c78a507689f6f54b847ad1cef1e614ee23f1e88ac +* pkh([deadbeef/1/2h/3/4h]03a34b99f22c790c4e36b2b3c2c35a36db06226e41c692fc82b8b56ac1c540c5bd) +** 76a9149a1c78a507689f6f54b847ad1cef1e614ee23f1e88ac +* pk(5KYZdUEo39z3FPrtuX2QbbwGnNP5zTd7yyr2SC1j299sBCnWjss) +** 4104a34b99f22c790c4e36b2b3c2c35a36db06226e41c692fc82b8b56ac1c540c5bd5b8dec5235a0fa8722476c7709c02559e3aa73aa03918ba2d492eea75abea235ac +* pk(04a34b99f22c790c4e36b2b3c2c35a36db06226e41c692fc82b8b56ac1c540c5bd5b8dec5235a0fa8722476c7709c02559e3aa73aa03918ba2d492eea75abea235) +** 4104a34b99f22c790c4e36b2b3c2c35a36db06226e41c692fc82b8b56ac1c540c5bd5b8dec5235a0fa8722476c7709c02559e3aa73aa03918ba2d492eea75abea235ac +* pkh(5KYZdUEo39z3FPrtuX2QbbwGnNP5zTd7yyr2SC1j299sBCnWjss) +** 76a914b5bd079c4d57cc7fc28ecf8213a6b791625b818388ac +* pkh(04a34b99f22c790c4e36b2b3c2c35a36db06226e41c692fc82b8b56ac1c540c5bd5b8dec5235a0fa8722476c7709c02559e3aa73aa03918ba2d492eea75abea235) +** 76a914b5bd079c4d57cc7fc28ecf8213a6b791625b818388ac +* sh(pk(L4rK1yDtCWekvXuE6oXD9jCYfFNV2cWRpVuPLBcCU2z8TrisoyY1)) +** a9141857af51a5e516552b3086430fd8ce55f7c1a52487 +* sh(pk(03a34b99f22c790c4e36b2b3c2c35a36db06226e41c692fc82b8b56ac1c540c5bd)) +** a9141857af51a5e516552b3086430fd8ce55f7c1a52487 +* sh(pkh(L4rK1yDtCWekvXuE6oXD9jCYfFNV2cWRpVuPLBcCU2z8TrisoyY1)) +** a9141a31ad23bf49c247dd531a623c2ef57da3c400c587 +* sh(pkh(03a34b99f22c790c4e36b2b3c2c35a36db06226e41c692fc82b8b56ac1c540c5bd)) +** a9141a31ad23bf49c247dd531a623c2ef57da3c400c587 +* pkh(xprv9s21ZrQH143K31xYSDQpPDxsXRTUcvj2iNHm5NUtrGiGG5e2DtALGdso3pGz6ssrdK4PFmM8NSpSBHNqPqm55Qn3LqFtT2emdEXVYsCzC2U/2147483647'/0) +** 76a914ebdc90806a9c4356c1c88e42216611e1cb4c1c1788ac +* pkh(xpub661MyMwAqRbcFW31YEwpkMuc5THy2PSt5bDMsktWQcFF8syAmRUapSCGu8ED9W6oDMSgv6Zz8idoc4a6mr8BDzTJY47LJhkJ8UB7WEGuduB/2147483647'/0) +** 76a914ebdc90806a9c4356c1c88e42216611e1cb4c1c1788ac +* pkh([bd16bee5/2147483647h]xpub69H7F5dQzmVd3vPuLKtcXJziMEQByuDidnX3YdwgtNsecY5HRGtAAQC5mXTt4dsv9RzyjgDjAQs9VGVV6ydYCHnprc9vvaA5YtqWyL6hyds/0) +** 76a914ebdc90806a9c4356c1c88e42216611e1cb4c1c1788ac +* pk(xprv9uPDJpEQgRQfDcW7BkF7eTya6RPxXeJCqCJGHuCJ4GiRVLzkTXBAJMu2qaMWPrS7AANYqdq6vcBcBUdJCVVFceUvJFjaPdGZ2y9WACViL4L/0) +** 210379e45b3cf75f9c5f9befd8e9506fb962f6a9d185ac87001ec44a8d3df8d4a9e3ac +* pk(xpub68NZiKmJWnxxS6aaHmn81bvJeTESw724CRDs6HbuccFQN9Ku14VQrADWgqbhhTHBaohPX4CjNLf9fq9MYo6oDaPPLPxSb7gwQN3ih19Zm4Y/0) +** 210379e45b3cf75f9c5f9befd8e9506fb962f6a9d185ac87001ec44a8d3df8d4a9e3ac + +Invalid descriptors + +* pk() only accepts key expressions: pk(pk(03a34b99f22c790c4e36b2b3c2c35a36db06226e41c692fc82b8b56ac1c540c5bd)) +* pkh() only accepts key expressions: pkh(pk(03a34b99f22c790c4e36b2b3c2c35a36db06226e41c692fc82b8b56ac1c540c5bd)) +* sh() only acceps script expressions: sh(03a34b99f22c790c4e36b2b3c2c35a36db06226e41c692fc82b8b56ac1c540c5bd) +* sh() is top level only: sh(sh(pkh(03a34b99f22c790c4e36b2b3c2c35a36db06226e41c692fc82b8b56ac1c540c5bd))) ==Backwards Compatibility== diff --git a/bip-0382.mediawiki b/bip-0382.mediawiki index 768079e510..1b7c1562c3 100644 --- a/bip-0382.mediawiki +++ b/bip-0382.mediawiki @@ -57,7 +57,52 @@ OP_0 ==Test Vectors== -TBD +Valid descriptors followed by the scripts they produce. Descriptors involving derived child keys will have the 0th, 1st, and 2nd scripts listed. + +* wpkh(L4rK1yDtCWekvXuE6oXD9jCYfFNV2cWRpVuPLBcCU2z8TrisoyY1) +** 00149a1c78a507689f6f54b847ad1cef1e614ee23f1e +* wpkh(03a34b99f22c790c4e36b2b3c2c35a36db06226e41c692fc82b8b56ac1c540c5bd) +** 00149a1c78a507689f6f54b847ad1cef1e614ee23f1e +* wpkh([ffffffff/13']xprv9vHkqa6EV4sPZHYqZznhT2NPtPCjKuDKGY38FBWLvgaDx45zo9WQRUT3dKYnjwih2yJD9mkrocEZXo1ex8G81dwSM1fwqWpWkeS3v86pgKt/1/2/0) +** 0014326b2249e3a25d5dc60935f044ee835d090ba859 +* wpkh([ffffffff/13']xpub69H7F5d8KSRgmmdJg2KhpAK8SR3DjMwAdkxj3ZuxV27CprR9LgpeyGmXUbC6wb7ERfvrnKZjXoUmmDznezpbZb7ap6r1D3tgFxHmwMkQTPH/1/2/*) +** 0014326b2249e3a25d5dc60935f044ee835d090ba859 +** 0014af0bd98abc2f2cae66e36896a39ffe2d32984fb7 +** 00141fa798efd1cbf95cebf912c031b8a4a6e9fb9f27 +* sh(wpkh(xprv9s21ZrQH143K3QTDL4LXw2F7HEK3wJUD2nW2nRk4stbPy6cq3jPPqjiChkVvvNKmPGJxWUtg6LnF5kejMRNNU3TGtRBeJgk33yuGBxrMPHi/10/20/30/40/*')) +** a9149a4d9901d6af519b2a23d4a2f51650fcba87ce7b87 +** a914bed59fc0024fae941d6e20a3b44a109ae740129287 +** a9148483aa1116eb9c05c482a72bada4b1db24af654387 +* sh(wpkh(xpub661MyMwAqRbcFtXgS5sYJABqqG9YLmC4Q1Rdap9gSE8NqtwybGhePY2gZ29ESFjqJoCu1Rupje8YtGqsefD265TMg7usUDFdp6W1EGMcet8/10/20/30/40/*h)) +** a9149a4d9901d6af519b2a23d4a2f51650fcba87ce7b87 +** a914bed59fc0024fae941d6e20a3b44a109ae740129287 +** a9148483aa1116eb9c05c482a72bada4b1db24af654387 +* wsh(pkh(L4rK1yDtCWekvXuE6oXD9jCYfFNV2cWRpVuPLBcCU2z8TrisoyY1)) +** 0020338e023079b91c58571b20e602d7805fb808c22473cbc391a41b1bd3a192e75b +* wsh(pkh(03a34b99f22c790c4e36b2b3c2c35a36db06226e41c692fc82b8b56ac1c540c5bd)) +** 0020338e023079b91c58571b20e602d7805fb808c22473cbc391a41b1bd3a192e75b +* wsh(pk(L4rK1yDtCWekvXuE6oXD9jCYfFNV2cWRpVuPLBcCU2z8TrisoyY1)) +** 00202e271faa2325c199d25d22e1ead982e45b64eeb4f31e73dbdf41bd4b5fec23fa +* wsh(pk(03a34b99f22c790c4e36b2b3c2c35a36db06226e41c692fc82b8b56ac1c540c5bd)) +** 00202e271faa2325c199d25d22e1ead982e45b64eeb4f31e73dbdf41bd4b5fec23fa +* sh(wsh(pkh(L4rK1yDtCWekvXuE6oXD9jCYfFNV2cWRpVuPLBcCU2z8TrisoyY1))) +** a914b61b92e2ca21bac1e72a3ab859a742982bea960a87 +* sh(wsh(pkh(03a34b99f22c790c4e36b2b3c2c35a36db06226e41c692fc82b8b56ac1c540c5bd))) +** a914b61b92e2ca21bac1e72a3ab859a742982bea960a87 + +Invalid descriptors with descriptions + +* Uncompressed public key in wpkh(): wpkh(5KYZdUEo39z3FPrtuX2QbbwGnNP5zTd7yyr2SC1j299sBCnWjss) +* Uncompressed public key in wpkh(): sh(wpkh(5KYZdUEo39z3FPrtuX2QbbwGnNP5zTd7yyr2SC1j299sBCnWjss)) +* Uncompressed public key in wpkh(): wpkh(04a34b99f22c790c4e36b2b3c2c35a36db06226e41c692fc82b8b56ac1c540c5bd5b8dec5235a0fa8722476c7709c02559e3aa73aa03918ba2d492eea75abea235) +* Uncompressed public key in wpkh(): sh(wpkh(04a34b99f22c790c4e36b2b3c2c35a36db06226e41c692fc82b8b56ac1c540c5bd5b8dec5235a0fa8722476c7709c02559e3aa73aa03918ba2d492eea75abea235)) +* Uncompressed public keys under wsh(): wsh(pk(5KYZdUEo39z3FPrtuX2QbbwGnNP5zTd7yyr2SC1j299sBCnWjss)) +* Uncompressed public keys under wsh(): wsh(pk(04a34b99f22c790c4e36b2b3c2c35a36db06226e41c692fc82b8b56ac1c540c5bd5b8dec5235a0fa8722476c7709c02559e3aa73aa03918ba2d492eea75abea235)) +* wpkh() nested in wsh(): wsh(wpkh(03a34b99f22c790c4e36b2b3c2c35a36db06226e41c692fc82b8b56ac1c540c5bd)) +* wsh() nested in wsh(): wsh(wsh(pkh(03a34b99f22c790c4e36b2b3c2c35a36db06226e41c692fc82b8b56ac1c540c5bd))) +* wsh() nested in wsh(): sh(wsh(wsh(pkh(03a34b99f22c790c4e36b2b3c2c35a36db06226e41c692fc82b8b56ac1c540c5bd)))) +* Script in wpkh(): wpkh(wsh(pkh(03a34b99f22c790c4e36b2b3c2c35a36db06226e41c692fc82b8b56ac1c540c5bd))) +* Key in wsh(): wsh(03a34b99f22c790c4e36b2b3c2c35a36db06226e41c692fc82b8b56ac1c540c5bd) ==Backwards Compatibility== diff --git a/bip-0383.mediawiki b/bip-0383.mediawiki index 92e86e3bda..27fb74b58c 100644 --- a/bip-0383.mediawiki +++ b/bip-0383.mediawiki @@ -65,7 +65,37 @@ This changes the keys in lockstep and allows for output scripts to be indexed in ==Test Vectors== -TBD +Valid descriptors followed by the scripts they produce. Descriptors involving derived child keys will have the 0th, 1st, and 2nd scripts listed. + +* multi(1,L4rK1yDtCWekvXuE6oXD9jCYfFNV2cWRpVuPLBcCU2z8TrisoyY1,5KYZdUEo39z3FPrtuX2QbbwGnNP5zTd7yyr2SC1j299sBCnWjss) +** 512103a34b99f22c790c4e36b2b3c2c35a36db06226e41c692fc82b8b56ac1c540c5bd4104a34b99f22c790c4e36b2b3c2c35a36db06226e41c692fc82b8b56ac1c540c5bd5b8dec5235a0fa8722476c7709c02559e3aa73aa03918ba2d492eea75abea23552ae +* multi(1,03a34b99f22c790c4e36b2b3c2c35a36db06226e41c692fc82b8b56ac1c540c5bd,04a34b99f22c790c4e36b2b3c2c35a36db06226e41c692fc82b8b56ac1c540c5bd5b8dec5235a0fa8722476c7709c02559e3aa73aa03918ba2d492eea75abea235) +** 512103a34b99f22c790c4e36b2b3c2c35a36db06226e41c692fc82b8b56ac1c540c5bd4104a34b99f22c790c4e36b2b3c2c35a36db06226e41c692fc82b8b56ac1c540c5bd5b8dec5235a0fa8722476c7709c02559e3aa73aa03918ba2d492eea75abea23552ae +* sortedmulti(1,04a34b99f22c790c4e36b2b3c2c35a36db06226e41c692fc82b8b56ac1c540c5bd5b8dec5235a0fa8722476c7709c02559e3aa73aa03918ba2d492eea75abea235,03a34b99f22c790c4e36b2b3c2c35a36db06226e41c692fc82b8b56ac1c540c5bd) +** 512103a34b99f22c790c4e36b2b3c2c35a36db06226e41c692fc82b8b56ac1c540c5bd4104a34b99f22c790c4e36b2b3c2c35a36db06226e41c692fc82b8b56ac1c540c5bd5b8dec5235a0fa8722476c7709c02559e3aa73aa03918ba2d492eea75abea23552ae +* sh(multi(2,[00000000/111'/222]xprvA1RpRA33e1JQ7ifknakTFpgNXPmW2YvmhqLQYMmrj4xJXXWYpDPS3xz7iAxn8L39njGVyuoseXzU6rcxFLJ8HFsTjSyQbLYnMpCqE2VbFWc,xprv9uPDJpEQgRQfDcW7BkF7eTya6RPxXeJCqCJGHuCJ4GiRVLzkTXBAJMu2qaMWPrS7AANYqdq6vcBcBUdJCVVFceUvJFjaPdGZ2y9WACViL4L/0)) +** a91445a9a622a8b0a1269944be477640eedc447bbd8487 +* sortedmulti(2,xpub6ERApfZwUNrhLCkDtcHTcxd75RbzS1ed54G1LkBUHQVHQKqhMkhgbmJbZRkrgZw4koxb5JaHWkY4ALHY2grBGRjaDMzQLcgJvLJuZZvRcEL/*,xpub68NZiKmJWnxxS6aaHmn81bvJeTESw724CRDs6HbuccFQN9Ku14VQrADWgqbhhTHBaohPX4CjNLf9fq9MYo6oDaPPLPxSb7gwQN3ih19Zm4Y/0/0/*) +** 5221025d5fc65ebb8d44a5274b53bac21ff8307fec2334a32df05553459f8b1f7fe1b62102fbd47cc8034098f0e6a94c6aeee8528abf0a2153a5d8e46d325b7284c046784652ae +** 52210264fd4d1f5dea8ded94c61e9641309349b62f27fbffe807291f664e286bfbe6472103f4ece6dfccfa37b211eb3d0af4d0c61dba9ef698622dc17eecdf764beeb005a652ae +** 5221022ccabda84c30bad578b13c89eb3b9544ce149787e5b538175b1d1ba259cbb83321024d902e1a2fc7a8755ab5b694c575fce742c48d9ff192e63df5193e4c7afe1f9c52ae +* wsh(multi(2,xprv9s21ZrQH143K31xYSDQpPDxsXRTUcvj2iNHm5NUtrGiGG5e2DtALGdso3pGz6ssrdK4PFmM8NSpSBHNqPqm55Qn3LqFtT2emdEXVYsCzC2U/2147483647'/0,xprv9vHkqa6EV4sPZHYqZznhT2NPtPCjKuDKGY38FBWLvgaDx45zo9WQRUT3dKYnjwih2yJD9mkrocEZXo1ex8G81dwSM1fwqWpWkeS3v86pgKt/1/2/*,xprv9s21ZrQH143K3QTDL4LXw2F7HEK3wJUD2nW2nRk4stbPy6cq3jPPqjiChkVvvNKmPGJxWUtg6LnF5kejMRNNU3TGtRBeJgk33yuGBxrMPHi/10/20/30/40/*')) +** 0020b92623201f3bb7c3771d45b2ad1d0351ea8fbf8cfe0a0e570264e1075fa1948f +** 002036a08bbe4923af41cf4316817c93b8d37e2f635dd25cfff06bd50df6ae7ea203 +** 0020a96e7ab4607ca6b261bfe3245ffda9c746b28d3f59e83d34820ec0e2b36c139c +* sh(wsh(multi(16,03669b8afcec803a0d323e9a17f3ea8e68e8abe5a278020a929adbec52421adbd0,0260b2003c386519fc9eadf2b5cf124dd8eea4c4e68d5e154050a9346ea98ce600,0362a74e399c39ed5593852a30147f2959b56bb827dfa3e60e464b02ccf87dc5e8,0261345b53de74a4d721ef877c255429961b7e43714171ac06168d7e08c542a8b8,02da72e8b46901a65d4374fe6315538d8f368557dda3a1dcf9ea903f3afe7314c8,0318c82dd0b53fd3a932d16e0ba9e278fcc937c582d5781be626ff16e201f72286,0297ccef1ef99f9d73dec9ad37476ddb232f1238aff877af19e72ba04493361009,02e502cfd5c3f972fe9a3e2a18827820638f96b6f347e54d63deb839011fd5765d,03e687710f0e3ebe81c1037074da939d409c0025f17eb86adb9427d28f0f7ae0e9,02c04d3a5274952acdbc76987f3184b346a483d43be40874624b29e3692c1df5af,02ed06e0f418b5b43a7ec01d1d7d27290fa15f75771cb69b642a51471c29c84acd,036d46073cbb9ffee90473f3da429abc8de7f8751199da44485682a989a4bebb24,02f5d1ff7c9029a80a4e36b9a5497027ef7f3e73384a4a94fbfe7c4e9164eec8bc,02e41deffd1b7cce11cde209a781adcffdabd1b91c0ba0375857a2bfd9302419f3,02d76625f7956a7fc505ab02556c23ee72d832f1bac391bcd2d3abce5710a13d06,0399eb0a5487515802dc14544cf10b3666623762fbed2ec38a3975716e2c29c232))) +** a9147fc63e13dc25e8a95a3cee3d9a714ac3afd96f1e87 +* wsh(multi(20,KzoAz5CanayRKex3fSLQ2BwJpN7U52gZvxMyk78nDMHuqrUxuSJy,KwGNz6YCCQtYvFzMtrC6D3tKTKdBBboMrLTsjr2NYVBwapCkn7Mr,KxogYhiNfwxuswvXV66eFyKcCpm7dZ7TqHVqujHAVUjJxyivxQ9X,L2BUNduTSyZwZjwNHynQTF14mv2uz2NRq5n5sYWTb4FkkmqgEE9f,L1okJGHGn1kFjdXHKxXjwVVtmCMR2JA5QsbKCSpSb7ReQjezKeoD,KxDCNSST75HFPaW5QKpzHtAyaCQC7p9Vo3FYfi2u4dXD1vgMiboK,L5edQjFtnkcf5UWURn6UuuoFrabgDQUHdheKCziwN42aLwS3KizU,KzF8UWFcEC7BYTq8Go1xVimMkDmyNYVmXV5PV7RuDicvAocoPB8i,L3nHUboKG2w4VSJ5jYZ5CBM97oeK6YuKvfZxrefdShECcjEYKMWZ,KyjHo36dWkYhimKmVVmQTq3gERv3pnqA4xFCpvUgbGDJad7eS8WE,KwsfyHKRUTZPQtysN7M3tZ4GXTnuov5XRgjdF2XCG8faAPmFruRF,KzCUbGhN9LJhdeFfL9zQgTJMjqxdBKEekRGZX24hXdgCNCijkkap,KzgpMBwwsDLwkaC5UrmBgCYaBD2WgZ7PBoGYXR8KT7gCA9UTN5a3,KyBXTPy4T7YG4q9tcAM3LkvfRpD1ybHMvcJ2ehaWXaSqeGUxEdkP,KzJDe9iwJRPtKP2F2AoN6zBgzS7uiuAwhWCfGdNeYJ3PC1HNJ8M8,L1xbHrxynrqLKkoYc4qtoQPx6uy5qYXR5ZDYVYBSRmCV5piU3JG9,KzRedjSwMggebB3VufhbzpYJnvHfHe9kPJSjCU5QpJdAW3NSZxYS,Kyjtp5858xL7JfeV4PNRCKy2t6XvgqNNepArGY9F9F1SSPqNEMs3,L2D4RLHPiHBidkHS8ftx11jJk1hGFELvxh8LoxNQheaGT58dKenW,KyLPZdwY4td98bKkXqEXTEBX3vwEYTQo1yyLjX2jKXA63GBpmSjv)) +** 0020376bd8344b8b6ebe504ff85ef743eaa1aa9272178223bcb6887e9378efb341ac +* sh(wsh(multi(20,KzoAz5CanayRKex3fSLQ2BwJpN7U52gZvxMyk78nDMHuqrUxuSJy,KwGNz6YCCQtYvFzMtrC6D3tKTKdBBboMrLTsjr2NYVBwapCkn7Mr,KxogYhiNfwxuswvXV66eFyKcCpm7dZ7TqHVqujHAVUjJxyivxQ9X,L2BUNduTSyZwZjwNHynQTF14mv2uz2NRq5n5sYWTb4FkkmqgEE9f,L1okJGHGn1kFjdXHKxXjwVVtmCMR2JA5QsbKCSpSb7ReQjezKeoD,KxDCNSST75HFPaW5QKpzHtAyaCQC7p9Vo3FYfi2u4dXD1vgMiboK,L5edQjFtnkcf5UWURn6UuuoFrabgDQUHdheKCziwN42aLwS3KizU,KzF8UWFcEC7BYTq8Go1xVimMkDmyNYVmXV5PV7RuDicvAocoPB8i,L3nHUboKG2w4VSJ5jYZ5CBM97oeK6YuKvfZxrefdShECcjEYKMWZ,KyjHo36dWkYhimKmVVmQTq3gERv3pnqA4xFCpvUgbGDJad7eS8WE,KwsfyHKRUTZPQtysN7M3tZ4GXTnuov5XRgjdF2XCG8faAPmFruRF,KzCUbGhN9LJhdeFfL9zQgTJMjqxdBKEekRGZX24hXdgCNCijkkap,KzgpMBwwsDLwkaC5UrmBgCYaBD2WgZ7PBoGYXR8KT7gCA9UTN5a3,KyBXTPy4T7YG4q9tcAM3LkvfRpD1ybHMvcJ2ehaWXaSqeGUxEdkP,KzJDe9iwJRPtKP2F2AoN6zBgzS7uiuAwhWCfGdNeYJ3PC1HNJ8M8,L1xbHrxynrqLKkoYc4qtoQPx6uy5qYXR5ZDYVYBSRmCV5piU3JG9,KzRedjSwMggebB3VufhbzpYJnvHfHe9kPJSjCU5QpJdAW3NSZxYS,Kyjtp5858xL7JfeV4PNRCKy2t6XvgqNNepArGY9F9F1SSPqNEMs3,L2D4RLHPiHBidkHS8ftx11jJk1hGFELvxh8LoxNQheaGT58dKenW,KyLPZdwY4td98bKkXqEXTEBX3vwEYTQo1yyLjX2jKXA63GBpmSjv))) +** a914c2c9c510e9d7f92fd6131e94803a8d34a8ef675e87 + +Invalid descriptors + +* More than 15 keys in P2SH multisig: sh(multi(16,03669b8afcec803a0d323e9a17f3ea8e68e8abe5a278020a929adbec52421adbd0,0260b2003c386519fc9eadf2b5cf124dd8eea4c4e68d5e154050a9346ea98ce600,0362a74e399c39ed5593852a30147f2959b56bb827dfa3e60e464b02ccf87dc5e8,0261345b53de74a4d721ef877c255429961b7e43714171ac06168d7e08c542a8b8,02da72e8b46901a65d4374fe6315538d8f368557dda3a1dcf9ea903f3afe7314c8,0318c82dd0b53fd3a932d16e0ba9e278fcc937c582d5781be626ff16e201f72286,0297ccef1ef99f9d73dec9ad37476ddb232f1238aff877af19e72ba04493361009,02e502cfd5c3f972fe9a3e2a18827820638f96b6f347e54d63deb839011fd5765d,03e687710f0e3ebe81c1037074da939d409c0025f17eb86adb9427d28f0f7ae0e9,02c04d3a5274952acdbc76987f3184b346a483d43be40874624b29e3692c1df5af,02ed06e0f418b5b43a7ec01d1d7d27290fa15f75771cb69b642a51471c29c84acd,036d46073cbb9ffee90473f3da429abc8de7f8751199da44485682a989a4bebb24,02f5d1ff7c9029a80a4e36b9a5497027ef7f3e73384a4a94fbfe7c4e9164eec8bc,02e41deffd1b7cce11cde209a781adcffdabd1b91c0ba0375857a2bfd9302419f3,02d76625f7956a7fc505ab02556c23ee72d832f1bac391bcd2d3abce5710a13d06,0399eb0a5487515802dc14544cf10b3666623762fbed2ec38a3975716e2c29c232)) +* Invalid threshold: multi(a,03a34b99f22c790c4e36b2b3c2c35a36db06226e41c692fc82b8b56ac1c540c5bd,04a34b99f22c790c4e36b2b3c2c35a36db06226e41c692fc82b8b56ac1c540c5bd5b8dec5235a0fa8722476c7709c02559e3aa73aa03918ba2d492eea75abea235) +* Threshold of 0: multi(0,03a34b99f22c790c4e36b2b3c2c35a36db06226e41c692fc82b8b56ac1c540c5bd,04a34b99f22c790c4e36b2b3c2c35a36db06226e41c692fc82b8b56ac1c540c5bd5b8dec5235a0fa8722476c7709c02559e3aa73aa03918ba2d492eea75abea235) +* Threshold larger than keys: multi(3,L4rK1yDtCWekvXuE6oXD9jCYfFNV2cWRpVuPLBcCU2z8TrisoyY1,5KYZdUEo39z3FPrtuX2QbbwGnNP5zTd7yyr2SC1j299sBCnWjss) ==Backwards Compatibility== diff --git a/bip-0384.mediawiki b/bip-0384.mediawiki index e735d74ec9..98dca77864 100644 --- a/bip-0384.mediawiki +++ b/bip-0384.mediawiki @@ -35,7 +35,38 @@ If the key is/has a compressed public key, then P2WPKH and P2SH-P2WPKH scripts a ==Test Vectors== -TBD +Valid descriptors followed by the scripts they produce. Descriptors involving derived child keys will have the 0th, and 1st scripts in additional sub-bullets. + +* combo(L4rK1yDtCWekvXuE6oXD9jCYfFNV2cWRpVuPLBcCU2z8TrisoyY1) +** 2103a34b99f22c790c4e36b2b3c2c35a36db06226e41c692fc82b8b56ac1c540c5bdac +** 76a9149a1c78a507689f6f54b847ad1cef1e614ee23f1e88ac +** 00149a1c78a507689f6f54b847ad1cef1e614ee23f1e +** a91484ab21b1b2fd065d4504ff693d832434b6108d7b87 +* combo(04a34b99f22c790c4e36b2b3c2c35a36db06226e41c692fc82b8b56ac1c540c5bd5b8dec5235a0fa8722476c7709c02559e3aa73aa03918ba2d492eea75abea235) +** 4104a34b99f22c790c4e36b2b3c2c35a36db06226e41c692fc82b8b56ac1c540c5bd5b8dec5235a0fa8722476c7709c02559e3aa73aa03918ba2d492eea75abea235ac +** 76a914b5bd079c4d57cc7fc28ecf8213a6b791625b818388ac +* combo([01234567]xpub6ERApfZwUNrhLCkDtcHTcxd75RbzS1ed54G1LkBUHQVHQKqhMkhgbmJbZRkrgZw4koxb5JaHWkY4ALHY2grBGRjaDMzQLcgJvLJuZZvRcEL) +** 2102d2b36900396c9282fa14628566582f206a5dd0bcc8d5e892611806cafb0301f0ac +** 76a91431a507b815593dfc51ffc7245ae7e5aee304246e88ac +** 001431a507b815593dfc51ffc7245ae7e5aee304246e +** a9142aafb926eb247cb18240a7f4c07983ad1f37922687 +* combo(xprvA2JDeKCSNNZky6uBCviVfJSKyQ1mDYahRjijr5idH2WwLsEd4Hsb2Tyh8RfQMuPh7f7RtyzTtdrbdqqsunu5Mm3wDvUAKRHSC34sJ7in334/*) +** Child 0 +*** 2102df12b7035bdac8e3bab862a3a83d06ea6b17b6753d52edecba9be46f5d09e076ac +*** 76a914f90e3178ca25f2c808dc76624032d352fdbdfaf288ac +*** 0014f90e3178ca25f2c808dc76624032d352fdbdfaf2 +*** a91473e39884cb71ae4e5ac9739e9225026c99763e6687 +** Child 1 +*** 21032869a233c9adff9a994e4966e5b821fd5bac066da6c3112488dc52383b4a98ecac +*** 76a914a8409d1b6dfb1ed2a3e8aa5e0ef2ff26b15b75b788ac +*** 0014a8409d1b6dfb1ed2a3e8aa5e0ef2ff26b15b75b7 +*** a91473e39884cb71ae4e5ac9739e9225026c99763e6687 + +Invalid descriptors + +* combo() in sh : sh(combo(03a34b99f22c790c4e36b2b3c2c35a36db06226e41c692fc82b8b56ac1c540c5bd)) +* combo() in wsh : wsh(combo(03a34b99f22c790c4e36b2b3c2c35a36db06226e41c692fc82b8b56ac1c540c5bd)) +* Script in combo(): combo(pkh(03a34b99f22c790c4e36b2b3c2c35a36db06226e41c692fc82b8b56ac1c540c5bd)) ==Backwards Compatibility== diff --git a/bip-0385.mediawiki b/bip-0385.mediawiki index 5c46d75e7e..f97a3316ec 100644 --- a/bip-0385.mediawiki +++ b/bip-0385.mediawiki @@ -44,7 +44,25 @@ The output script produced by this descriptor is the output script produced by t ==Test Vectors== -TBD +Valid descriptors followed by the scripts they produce. + +* raw(deadbeef) +** deadbeef +* raw(512103a34b99f22c790c4e36b2b3c2c35a36db06226e41c692fc82b8b56ac1c540c5bd4104a34b99f22c790c4e36b2b3c2c35a36db06226e41c692fc82b8b56ac1c540c5bd5b8dec5235a0fa8722476c7709c02559e3aa73aa03918ba2d492eea75abea23552ae) +** 512103a34b99f22c790c4e36b2b3c2c35a36db06226e41c692fc82b8b56ac1c540c5bd4104a34b99f22c790c4e36b2b3c2c35a36db06226e41c692fc82b8b56ac1c540c5bd5b8dec5235a0fa8722476c7709c02559e3aa73aa03918ba2d492eea75abea23552ae +* raw(a9149a4d9901d6af519b2a23d4a2f51650fcba87ce7b87) +** a9149a4d9901d6af519b2a23d4a2f51650fcba87ce7b87 +* addr(3PUNyaW7M55oKWJ3kDukwk9bsKvryra15j) +** a914eeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeee87 + +Invalid descriptors + +* Non-hex script: raw(asdf) +* Invalid address: addr(asdf) +* raw nested in sh: sh(raw(deadbeef)) +* raw nested in wsh: wsh(raw(deadbeef)) +* addr nested in sh: sh(addr(3PUNyaW7M55oKWJ3kDukwk9bsKvryra15j)) +* addr nested in wsh: wsh(addr(3PUNyaW7M55oKWJ3kDukwk9bsKvryra15j)) ==Backwards Compatibility== diff --git a/bip-0386.mediawiki b/bip-0386.mediawiki index d90e801a18..782a6f8fed 100644 --- a/bip-0386.mediawiki +++ b/bip-0386.mediawiki @@ -84,7 +84,28 @@ An additional key expression is defined only for use within a tr() desc ==Test Vectors== -TBD +Valid descriptors followed by the scripts they produce. Descriptors involving derived child keys will have the 0th, 1st, and 2nd scripts listed. + +* tr(a34b99f22c790c4e36b2b3c2c35a36db06226e41c692fc82b8b56ac1c540c5bd) +** 512077aab6e066f8a7419c5ab714c12c67d25007ed55a43cadcacb4d7a970a093f11 +* tr(L4rK1yDtCWekvXuE6oXD9jCYfFNV2cWRpVuPLBcCU2z8TrisoyY1) +** 512077aab6e066f8a7419c5ab714c12c67d25007ed55a43cadcacb4d7a970a093f11 +* tr(xprvA1RpRA33e1JQ7ifknakTFpgNXPmW2YvmhqLQYMmrj4xJXXWYpDPS3xz7iAxn8L39njGVyuoseXzU6rcxFLJ8HFsTjSyQbLYnMpCqE2VbFWc/0/*,pk(xprvA1RpRA33e1JQ7ifknakTFpgNXPmW2YvmhqLQYMmrj4xJXXWYpDPS3xz7iAxn8L39njGVyuoseXzU6rcxFLJ8HFsTjSyQbLYnMpCqE2VbFWc/1/*)) +** 512078bc707124daa551b65af74de2ec128b7525e10f374dc67b64e00ce0ab8b3e12 +** 512001f0a02a17808c20134b78faab80ef93ffba82261ccef0a2314f5d62b6438f11 +** 512021024954fcec88237a9386fce80ef2ced5f1e91b422b26c59ccfc174c8d1ad25 +* tr(a34b99f22c790c4e36b2b3c2c35a36db06226e41c692fc82b8b56ac1c540c5bd,pk(669b8afcec803a0d323e9a17f3ea8e68e8abe5a278020a929adbec52421adbd0)) +** 512017cf18db381d836d8923b1bdb246cfcd818da1a9f0e6e7907f187f0b2f937754 +* tr(a34b99f22c790c4e36b2b3c2c35a36db06226e41c692fc82b8b56ac1c540c5bd,{pk(xprvA2JDeKCSNNZky6uBCviVfJSKyQ1mDYahRjijr5idH2WwLsEd4Hsb2Tyh8RfQMuPh7f7RtyzTtdrbdqqsunu5Mm3wDvUAKRHSC34sJ7in334/0),{{pk(xpub6ERApfZwUNrhLCkDtcHTcxd75RbzS1ed54G1LkBUHQVHQKqhMkhgbmJbZRkrgZw4koxb5JaHWkY4ALHY2grBGRjaDMzQLcgJvLJuZZvRcEL),pk(02df12b7035bdac8e3bab862a3a83d06ea6b17b6753d52edecba9be46f5d09e076)},pk(L4rK1yDtCWekvXuE6oXD9jCYfFNV2cWRpVuPLBcCU2z8TrisoyY1)}}) +** 512071fff39599a7b78bc02623cbe814efebf1a404f5d8ad34ea80f213bd8943f574 + +Invalid Descriptors + +* Uncompressed private key: tr(5kyzdueo39z3fprtux2qbbwgnnp5ztd7yyr2sc1j299sbcnwjss) +* Uncompressed public key: tr(04a34b99f22c790c4e36b2b3c2c35a36db06226e41c692fc82b8b56ac1c540c5bd5b8dec5235a0fa8722476c7709c02559e3aa73aa03918ba2d492eea75abea235) +* tr() nested in wsh: wsh(tr(a34b99f22c790c4e36b2b3c2c35a36db06226e41c692fc82b8b56ac1c540c5bd)) +* tr() nested in sh: sh(tr(a34b99f22c790c4e36b2b3c2c35a36db06226e41c692fc82b8b56ac1c540c5bd)) +* pkh() nested in tr: tr(a34b99f22c790c4e36b2b3c2c35a36db06226e41c692fc82b8b56ac1c540c5bd, pkh(L4rK1yDtCWekvXuE6oXD9jCYfFNV2cWRpVuPLBcCU2z8TrisoyY1)) ==Backwards Compatibility== diff --git a/bip-0389.mediawiki b/bip-0389.mediawiki index fea7674925..fe14b629cd 100644 --- a/bip-0389.mediawiki +++ b/bip-0389.mediawiki @@ -57,7 +57,39 @@ Note that only one / specifier is allowed in a Key Exp ==Test Vectors== -TBD +Valid multipath descriptors followed by the descriptors they expand into as sub-bullets + +* pk(xpub68NZiKmJWnxxS6aaHmn81bvJeTESw724CRDs6HbuccFQN9Ku14VQrADWgqbhhTHBaohPX4CjNLf9fq9MYo6oDaPPLPxSb7gwQN3ih19Zm4Y/<0;1>) +** pk(xpub68NZiKmJWnxxS6aaHmn81bvJeTESw724CRDs6HbuccFQN9Ku14VQrADWgqbhhTHBaohPX4CjNLf9fq9MYo6oDaPPLPxSb7gwQN3ih19Zm4Y/0) +** pk(xpub68NZiKmJWnxxS6aaHmn81bvJeTESw724CRDs6HbuccFQN9Ku14VQrADWgqbhhTHBaohPX4CjNLf9fq9MYo6oDaPPLPxSb7gwQN3ih19Zm4Y/1) +* pkh(xprv9s21ZrQH143K31xYSDQpPDxsXRTUcvj2iNHm5NUtrGiGG5e2DtALGdso3pGz6ssrdK4PFmM8NSpSBHNqPqm55Qn3LqFtT2emdEXVYsCzC2U/<2147483647h;0>/0) +** pkh(xprv9s21ZrQH143K31xYSDQpPDxsXRTUcvj2iNHm5NUtrGiGG5e2DtALGdso3pGz6ssrdK4PFmM8NSpSBHNqPqm55Qn3LqFtT2emdEXVYsCzC2U/2147483647h/0) +** pkh(xprv9s21ZrQH143K31xYSDQpPDxsXRTUcvj2iNHm5NUtrGiGG5e2DtALGdso3pGz6ssrdK4PFmM8NSpSBHNqPqm55Qn3LqFtT2emdEXVYsCzC2U/0/0) +* wpkh([ffffffff/13h]xpub69H7F5d8KSRgmmdJg2KhpAK8SR3DjMwAdkxj3ZuxV27CprR9LgpeyGmXUbC6wb7ERfvrnKZjXoUmmDznezpbZb7ap6r1D3tgFxHmwMkQTPH/<1;3>/2/* +** wpkh([ffffffff/13h]xpub69H7F5d8KSRgmmdJg2KhpAK8SR3DjMwAdkxj3ZuxV27CprR9LgpeyGmXUbC6wb7ERfvrnKZjXoUmmDznezpbZb7ap6r1D3tgFxHmwMkQTPH/1/2/*) +** wpkh([ffffffff/13h]xpub69H7F5d8KSRgmmdJg2KhpAK8SR3DjMwAdkxj3ZuxV27CprR9LgpeyGmXUbC6wb7ERfvrnKZjXoUmmDznezpbZb7ap6r1D3tgFxHmwMkQTPH/3/2/*) +* multi(2,xpub6ERApfZwUNrhLCkDtcHTcxd75RbzS1ed54G1LkBUHQVHQKqhMkhgbmJbZRkrgZw4koxb5JaHWkY4ALHY2grBGRjaDMzQLcgJvLJuZZvRcEL/<1;2>/*,xpub68NZiKmJWnxxS6aaHmn81bvJeTESw724CRDs6HbuccFQN9Ku14VQrADWgqbhhTHBaohPX4CjNLf9fq9MYo6oDaPPLPxSb7gwQN3ih19Zm4Y/<3;4>/0/*) +** multi(2,xpub6ERApfZwUNrhLCkDtcHTcxd75RbzS1ed54G1LkBUHQVHQKqhMkhgbmJbZRkrgZw4koxb5JaHWkY4ALHY2grBGRjaDMzQLcgJvLJuZZvRcEL/1/*,xpub68NZiKmJWnxxS6aaHmn81bvJeTESw724CRDs6HbuccFQN9Ku14VQrADWgqbhhTHBaohPX4CjNLf9fq9MYo6oDaPPLPxSb7gwQN3ih19Zm4Y/3/0/*) +** multi(2,xpub6ERApfZwUNrhLCkDtcHTcxd75RbzS1ed54G1LkBUHQVHQKqhMkhgbmJbZRkrgZw4koxb5JaHWkY4ALHY2grBGRjaDMzQLcgJvLJuZZvRcEL/2/*,xpub68NZiKmJWnxxS6aaHmn81bvJeTESw724CRDs6HbuccFQN9Ku14VQrADWgqbhhTHBaohPX4CjNLf9fq9MYo6oDaPPLPxSb7gwQN3ih19Zm4Y/4/0/*) +* pkh(xpub661MyMwAqRbcFW31YEwpkMuc5THy2PSt5bDMsktWQcFF8syAmRUapSCGu8ED9W6oDMSgv6Zz8idoc4a6mr8BDzTJY47LJhkJ8UB7WEGuduB/<0;1;2>) +** pkh(xpub661MyMwAqRbcFW31YEwpkMuc5THy2PSt5bDMsktWQcFF8syAmRUapSCGu8ED9W6oDMSgv6Zz8idoc4a6mr8BDzTJY47LJhkJ8UB7WEGuduB/0) +** pkh(xpub661MyMwAqRbcFW31YEwpkMuc5THy2PSt5bDMsktWQcFF8syAmRUapSCGu8ED9W6oDMSgv6Zz8idoc4a6mr8BDzTJY47LJhkJ8UB7WEGuduB/1) +** pkh(xpub661MyMwAqRbcFW31YEwpkMuc5THy2PSt5bDMsktWQcFF8syAmRUapSCGu8ED9W6oDMSgv6Zz8idoc4a6mr8BDzTJY47LJhkJ8UB7WEGuduB/2) +* sh(multi(2,xpub6ERApfZwUNrhLCkDtcHTcxd75RbzS1ed54G1LkBUHQVHQKqhMkhgbmJbZRkrgZw4koxb5JaHWkY4ALHY2grBGRjaDMzQLcgJvLJuZZvRcEL/<1;2;3>/0/*,xpub68NZiKmJWnxxS6aaHmn81bvJeTESw724CRDs6HbuccFQN9Ku14VQrADWgqbhhTHBaohPX4CjNLf9fq9MYo6oDaPPLPxSb7gwQN3ih19Zm4Y/0/*,xpub661MyMwAqRbcGDZQUKLqmWodYLcoBQnQH33yYkkF3jjxeLvY8qr2wWGEWkiKFaaQfJCoi3HeEq3Dc5DptfbCyjD38fNhSqtKc1UHaP4ba3t/0/0/<3;4;5>/*)) +** sh(multi(2,xpub6ERApfZwUNrhLCkDtcHTcxd75RbzS1ed54G1LkBUHQVHQKqhMkhgbmJbZRkrgZw4koxb5JaHWkY4ALHY2grBGRjaDMzQLcgJvLJuZZvRcEL/1/0/*,xpub68NZiKmJWnxxS6aaHmn81bvJeTESw724CRDs6HbuccFQN9Ku14VQrADWgqbhhTHBaohPX4CjNLf9fq9MYo6oDaPPLPxSb7gwQN3ih19Zm4Y/0/*,xpub661MyMwAqRbcGDZQUKLqmWodYLcoBQnQH33yYkkF3jjxeLvY8qr2wWGEWkiKFaaQfJCoi3HeEq3Dc5DptfbCyjD38fNhSqtKc1UHaP4ba3t/0/0/3/*)) +** sh(multi(2,xpub6ERApfZwUNrhLCkDtcHTcxd75RbzS1ed54G1LkBUHQVHQKqhMkhgbmJbZRkrgZw4koxb5JaHWkY4ALHY2grBGRjaDMzQLcgJvLJuZZvRcEL/2/0/*,xpub68NZiKmJWnxxS6aaHmn81bvJeTESw724CRDs6HbuccFQN9Ku14VQrADWgqbhhTHBaohPX4CjNLf9fq9MYo6oDaPPLPxSb7gwQN3ih19Zm4Y/0/*,xpub661MyMwAqRbcGDZQUKLqmWodYLcoBQnQH33yYkkF3jjxeLvY8qr2wWGEWkiKFaaQfJCoi3HeEq3Dc5DptfbCyjD38fNhSqtKc1UHaP4ba3t/0/0/4/*)) +** sh(multi(2,xpub6ERApfZwUNrhLCkDtcHTcxd75RbzS1ed54G1LkBUHQVHQKqhMkhgbmJbZRkrgZw4koxb5JaHWkY4ALHY2grBGRjaDMzQLcgJvLJuZZvRcEL/3/0/*,xpub68NZiKmJWnxxS6aaHmn81bvJeTESw724CRDs6HbuccFQN9Ku14VQrADWgqbhhTHBaohPX4CjNLf9fq9MYo6oDaPPLPxSb7gwQN3ih19Zm4Y/0/*,xpub661MyMwAqRbcGDZQUKLqmWodYLcoBQnQH33yYkkF3jjxeLvY8qr2wWGEWkiKFaaQfJCoi3HeEq3Dc5DptfbCyjD38fNhSqtKc1UHaP4ba3t/0/0/5/*)) + +Invalid descriptors + +* Multiple multipath specifiers: pkh(xprv9s21ZrQH143K31xYSDQpPDxsXRTUcvj2iNHm5NUtrGiGG5e2DtALGdso3pGz6ssrdK4PFmM8NSpSBHNqPqm55Qn3LqFtT2emdEXVYsCzC2U/<0;1>/<2;3>) +* Multipath specifier in origin: pkh([deadbeef/<0;1>]xpub661MyMwAqRbcFW31YEwpkMuc5THy2PSt5bDMsktWQcFF8syAmRUapSCGu8ED9W6oDMSgv6Zz8idoc4a6mr8BDzTJY47LJhkJ8UB7WEGuduB/0) +* Multipath specifiers of mismatched lengths: tr(xpub661MyMwAqRbcF3yVrV2KyYetLMYA5mCbv4BhrKwUrFE9LZM6JRR1AEt8Jq4V4C8LwtTke6YEEdCZqgXp85YRk2j74EfJKhe3QybQ9kcUjs4/<6;7;8;9>/*,{pk(xpub6ERApfZwUNrhLCkDtcHTcxd75RbzS1ed54G1LkBUHQVHQKqhMkhgbmJbZRkrgZw4koxb5JaHWkY4ALHY2grBGRjaDMzQLcgJvLJuZZvRcEL/<1;2;3>/0/*),pk(xpub661MyMwAqRbcGDZQUKLqmWodYLcoBQnQH33yYkkF3jjxeLvY8qr2wWGEWkiKFaaQfJCoi3HeEq3Dc5DptfbCyjD38fNhSqtKc1UHaP4ba3t/0/0/<3;4;5>/*)}) +* Multipath specifiers of mismatched lengths: sh(multi(2,xprvA1RpRA33e1JQ7ifknakTFpgNXPmW2YvmhqLQYMmrj4xJXXWYpDPS3xz7iAxn8L39njGVyuoseXzU6rcxFLJ8HFsTjSyQbLYnMpCqE2VbFWc/<1;2;3>/0/*,xprv9uPDJpEQgRQfDcW7BkF7eTya6RPxXeJCqCJGHuCJ4GiRVLzkTXBAJMu2qaMWPrS7AANYqdq6vcBcBUdJCVVFceUvJFjaPdGZ2y9WACViL4L/0/*,xprv9s21ZrQH143K3jUwNHoqQNrtzJnJmx4Yup8NkNLdVQCymYbPbJXnPhwkfTfxZfptcs3rLAPUXS39oDLgrNKQGwbGsEmJJ8BU3RzQuvShEG4/0/0/<3;4>/*)) +* Empty multipath specifier: wpkh(xpub661MyMwAqRbcFW31YEwpkMuc5THy2PSt5bDMsktWQcFF8syAmRUapSCGu8ED9W6oDMSgv6Zz8idoc4a6mr8BDzTJY47LJhkJ8UB7WEGuduB/<>/*) +* Missing multipath start: wpkh(xpub661MyMwAqRbcFW31YEwpkMuc5THy2PSt5bDMsktWQcFF8syAmRUapSCGu8ED9W6oDMSgv6Zz8idoc4a6mr8BDzTJY47LJhkJ8UB7WEGuduB/0>/*) +* Missing multipath end: wpkh(xpub661MyMwAqRbcFW31YEwpkMuc5THy2PSt5bDMsktWQcFF8syAmRUapSCGu8ED9W6oDMSgv6Zz8idoc4a6mr8BDzTJY47LJhkJ8UB7WEGuduB/<0/*) +* Missing index in multipath specifier: wpkh(xpub661MyMwAqRbcFW31YEwpkMuc5THy2PSt5bDMsktWQcFF8syAmRUapSCGu8ED9W6oDMSgv6Zz8idoc4a6mr8BDzTJY47LJhkJ8UB7WEGuduB/<0;>/*) ==Backwards Compatibility== From 265d64cae5ae5a931d45dc9f923c562f33428e91 Mon Sep 17 00:00:00 2001 From: Thebora Kompanioni Date: Fri, 30 Jun 2023 10:19:55 +0200 Subject: [PATCH 100/454] fix(bip85): rectify pwd_length in PWD BASE85 table --- bip-0085.mediawiki | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/bip-0085.mediawiki b/bip-0085.mediawiki index 06277555d9..8d40e6e141 100644 --- a/bip-0085.mediawiki +++ b/bip-0085.mediawiki @@ -327,7 +327,7 @@ Entropy = log2(R ** L)
|- | 30 || 192.0 |- -| 20 || 512.0 +| 80 || 512.0 |} INPUT: From 9e6fd723149483b67be2a9095eacf47cb7c1e1fc Mon Sep 17 00:00:00 2001 From: anquii <50277099+anquii@users.noreply.github.com> Date: Thu, 26 Jan 2023 17:27:43 +0000 Subject: [PATCH 101/454] Add anquii/BIP39 (Swift) --- bip-0039.mediawiki | 1 + 1 file changed, 1 insertion(+) diff --git a/bip-0039.mediawiki b/bip-0039.mediawiki index 2180b6c407..ca5d377ae4 100644 --- a/bip-0039.mediawiki +++ b/bip-0039.mediawiki @@ -190,6 +190,7 @@ Swift: * https://github.com/matter-labs/web3swift/blob/develop/Sources/web3swift/KeystoreManager/BIP39.swift * https://github.com/zcash-hackworks/MnemonicSwift * https://github.com/ShenghaiWang/BIP39 +* https://github.com/anquii/BIP39 C++: * https://github.com/libbitcoin/libbitcoin-system/blob/master/include/bitcoin/system/wallet/mnemonic.hpp From 9f25645be58f4db49cc2ae5a0a8ceca241517767 Mon Sep 17 00:00:00 2001 From: Sebastian Falbesoner Date: Thu, 6 Jul 2023 16:36:29 +0200 Subject: [PATCH 102/454] bip-0324: fix git instruction order in test_sage_decoding.py Tiny fix correcting the order of commands, for `git checkout` one has to change into the repository directory first. --- bip-0324/test_sage_decoding.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/bip-0324/test_sage_decoding.py b/bip-0324/test_sage_decoding.py index c26c33477d..1ec5fdf45a 100644 --- a/bip-0324/test_sage_decoding.py +++ b/bip-0324/test_sage_decoding.py @@ -5,8 +5,8 @@ * Clone the SwiftEC repository, and enter the directory: git clone https://github.com/Jchavezsaab/SwiftEC - git checkout 5320a25035d91addde29d14164cce684b56a12ed cd SwiftEC + git checkout 5320a25035d91addde29d14164cce684b56a12ed * Generate parameters for the secp256k1 curve: From e7eba11645405e857cb2d91c96ca95eabd5389e4 Mon Sep 17 00:00:00 2001 From: Paul Sztorc Date: Thu, 13 Jul 2023 16:45:08 -0400 Subject: [PATCH 103/454] clearer, more failure details, + use OP_TRUE --- bip-0300.mediawiki | 239 +++++++++++++++++++++++++++++++++------------ 1 file changed, 176 insertions(+), 63 deletions(-) diff --git a/bip-0300.mediawiki b/bip-0300.mediawiki index 20d1936a2f..6ee07600f0 100644 --- a/bip-0300.mediawiki +++ b/bip-0300.mediawiki @@ -75,54 +75,44 @@ D1 is a list of active sidechains. D1 is updated via M1 and M2. | Version number. |- | 3 -| String KeyID -| string -| Used to derive all sidechain deposit addresses. -|- -| 4
-| Sidechain Private Key -| string -| The private key of the sidechain deposit script. -|- style="vertical-align:middle;" -| 5
-| ScriptPubKey -| CScript -| Where the sidechain coins go. This always stays the same, even though the CTIP (UTXO) containing the coins is always changing. -|- style="vertical-align:middle;" -| 6 | Sidechain Name | string | A human-readable name of the sidechain. |- style="vertical-align:middle;" -| 7 +| 4 | Sidechain Description | string | A human-readable name description of the sidechain. |- style="vertical-align:middle;" -| 8 +| 5 | Hash1 - tarball hash | uint256 | Intended as the sha256 hash of the tar.gz of the canonical sidechain software. (This is not enforced anywhere by Bip300, and is for human purposes only.) |- style="vertical-align:middle;" -| 9 +| 6 | Hash2 - git commit hash | uint160 | Intended as the git commit hash of the canonical sidechain node software. (This is not enforced anywhere by Bip300, and is for human purposes only.) |- -| 10 +| 7 | Active | bool | Does this sidechain slot contain an active sidechain?
|- style="vertical-align:middle;" -| 11 -| "CTIP" -- Part 1 "TxID" +| 8 +| Activation Status +| int , int +| The age of the proposal (in blocks); and the number of "fails" (a block that does NOT ack the sidechain). This is discarded after the sidechain activates. +|- style="vertical-align:middle;" +| 9 +| "CTIP" -- "TxID" | uint256 -| The CTIP, or "Critical (TxID, Index) Pair" is a variable for keeping track of where the sidechain's money is (ie, which member of the UTXO set). +| A UTXO that holds the sidechain's money. (Part 1 of 2). |- style="vertical-align:middle;" -| 12 -| "CTIP" -- Part 2 "Index" +| 10 +| "CTIP" -- "vout" | int32_t -| Of the CTIP, the second element of the pair: the Index. See #11 above. +| A UTXO that holds the sidechain's money. (Part 2 of 2). |} @@ -138,7 +128,7 @@ D2 is driven by M3, M4, M5, and M6. Those messages enforce the following princip # From one block to the next, the value in "ACKs" may either increase or decrease, by a maximum of 1 (see M4). # If a Bundle's "ACKs" reach 13150 or greater, it "succeeds" and its corresponding M6 message can be included in a block. # If the M6 of a Bundle is paid out, it is also removed. -# If a Bundle cannot possibly succeed ( 13500 - "ACKs" > "Blocks Remaining" ), it is removed immediately. +# If a Bundle cannot possibly succeed ( 13150 - "ACKs" > "Blocks Remaining" ), it is removed immediately. {| class="wikitable" @@ -158,19 +148,21 @@ D2 is driven by M3, M4, M5, and M6. Those messages enforce the following princip | A withdrawal attempt. Specifically, it is a "blinded transaction id" (ie, the double-Sha256 of a txn that has had two fields zeroed out, see M6) of a txn which could withdraw funds from a sidechain. |- | 3 -| ACKs (Work Score) +| Work Score (ACKs) | uint16_t -| The current ACK-counter, which is the total number of ACKs (the PoW that has been used to validate the Bundle). +| How many miner upvotes a withdrawal has. Starts at 0. Fastest possible rate of increase is 1 per block. |- | 4 -| Blocks Remaining (Age) +| Blocks Remaining | uint16_t -| The number of blocks which this Bundle has remaining to accumulate ACKs +| How long this bundle has left to live (measured in blocks). Starts at 26,300 and counts down. |} +D1, with all 256 slots active, reaches a maximum size of: 256 * ( 1 (map index) + 36 (outpoint) + 8 (amount) ) = 11,520 bytes. +D2, under normal conditions, would reach a size of: (38 bytes per withdrawal * 256 sidechains) = 9,728 bytes. - +It is possible to spam D2. A miner can add the max M3s (256) every block, forever. This costs 9,728 on-chain bytes per block, an opportunity cost of about 43 txns. It results in no benefit to the miner whatsoever. D2 will eventually hit a ceiling at 124.5568 MB. (By comparison, the Bitcoin UTXO set is about 7,000 MB.) When the attacker stops, D2 will eventually shrink back down to 9,728 bytes. === The Six New Bip300 Messages === @@ -188,19 +180,22 @@ M1 is a coinbase OP Return output containing the following: N-byte - The serialization of the sidechain. 1-byte nSidechain 4-byte nVersion - x-byte strKeyID - x-byte strPrivKey - x-byte scriptPubKey x-byte title x-byte description 32-byte hashID1 20-byte hashID2 -===== Examples ===== - +M1 is invalid if: + +* It would add a duplicate entry to D1. +* There is already an M1 in this block. +* The sidechain serialization does not parse. + +Otherwise: + +* A new entry is added to D1, whose initial Activation Status is (age=0, fails=0). - ==== M2 -- ACK Sidechain Proposal ==== @@ -208,14 +203,30 @@ M2 is a coinbase OP Return output containing the following: 1-byte - OP_RETURN (0x6a) 4-byte - Message header (0xD6E1C5BF) - 32-byte - sha256D hash of sidechain's serialization + 32-byte - the sha256D hash of sidechain's serialization + + +M2 is ignored if it doesn't parse, or if it is for a sidechain that doesn't exist. + +M2 is invalid if: + +* An M2 is already in this block. +* It tries to ACK two different M1s for the same slot. -===== Notes ===== +Otherwise: -The new M1/M2 validation rules are: +* The sidechain is "ACK"ed and does NOT get a "fail" for this block. (As it otherwise would.) -# Any miner can propose a new sidechain (M1) at any time. This procedure resembles BIP 9 soft fork activation: the network must see a properly-formatted M1, followed by "acknowledgment" of the sidechain (M2) in 90% of the following 2016 blocks. -# Bip300 comes with only 256 sidechain-slots. If all are used, it is possible to "overwrite" a sidechain. This requires vastly more M2 ACKs -- 50% of the following 26300 blocks must contain an M2. The possibility of overwrite, does not change the Bip300 security assumptions (because we already assume that the sidechain is vulnerable to miners, at a rate of 1 catastrophe per 13150 blocks). +A sidechain fails to activate if: + +* If the slot is unused: during the next 2016 blocks, it accumulates 201 fails. (Ie, 90% threshold). +* If the slot is in use: during the next 26,300 blocks, it accumulates 13,150 fails. (Ie, 50% threshold). + +( Thus we can overwrite a used sidechain slot. Bip300 sidechains are already vulnerable to one catastrophe per 13150 blocks (the invalid withdrawal) so this slot-overwrite option does not change the security assumptions. ) + +Otherwise, the sidechain activates (Active is set to TRUE). + +In the block in which the sidechain activates, the coinbase MUST include at least one 0-valued OP_TRUE. This output becomes the initial CTIP for the sidechain. @@ -227,7 +238,7 @@ For an M6 to be valid, it must be first "prepped" by one M3 and then 13,150+ M4s ===== What are Bundles? ===== -Sidechain withdrawals take the form of “Bundles” -- named because they "bundle up" many individual withdrawal-requests into a single rare layer1 transaction. +Sidechain withdrawals take the form of "Bundles" -- named because they "bundle up" many individual withdrawal-requests into a single rare layer1 transaction. Sidechain full nodes aggregate the withdrawal-requests into a big set. The sidechain calculates what M6 would have to look like, to pay all of these withdrawal-requests out. Finally, the sidechain calculates what the hash of this M6 would be. This 32-byte hash identifies the Bundle. @@ -248,11 +259,18 @@ M3 is a coinbase OP Return output containing the following: 1-byte - OP_RETURN (0x6a) 4-byte - Commitment header (0xD45AA943) 32-byte - The Bundle hash, to populate a new D2 entry + 1-byte - nSidechain (the slot number) + +M3 is ignored if it does not parse, or if it is for a sidechain that doesn't exist. -The new validation rules pertaining to M3 are: +M3 is invalid if: -# If the network detects a properly-formatted M3, it must add an entry to D2 in the very next block. The starting "Blocks Remaining" value is 26,299. The starting ACKs count is 1. -# Each block can only contain one M3 per sidechain. +* This block already has an M3 for that nSidechain. +* A bundle with this hash is already in D2. +* A bundle with this hash already paid out. +* A bundle with this hash was rejected in the past. + +Otherwise: M3 adds an entry to D2, with initial ACK score = 1 and initial Blocks Remaining = 26,299. (Merely being added to D2, does count as your first upvote.) Once a Bundle is in D2, how can we give it enough ACKs to make it valid? @@ -263,44 +281,139 @@ M4 is a coinbase OP Return output containing the following: 1-byte - OP_RETURN (0x6a) 4-byte - Commitment header (0xD77D1776) 1-byte - Version - n-byte - The vector describing the "upvoted" bundle-choice, for each sidechain. + n-byte - The "upvote vector" -- describes which bundle-choice is "upvoted", for each sidechain. + +The upvote vector will code "abstain" as 0xFF (or 0xFFFF); it will code "alarm" as 0xFE (or 0xFFFE). Otherwise it simply indicates which withdrawal-bundle in the list, is the one to be "upvoted". + +For example: if there are two sidechains, and we wish to upvote the 7th bundle on sidechain #1 plus the 4th bundle on sidechain #2, then the upvote vector would be { 07, 04 }. And M4 would be [0x6A,D77D1776,00,0006,0003]. -Version 0x01 uses one byte per sidechain, and applies in most cases. Version 0x02 uses two bytes per sidechain and applies in unusual situations where at least one sidechain has more than 256 distinct withdrawal-bundles in progress at one time. Other interesting versions are possible: 0x03 might say "do exactly what was done in the previous block" (which could consume a fixed 6 bytes total, regardless of how many sidechains). 0x04 might say "upvote everyone who is clearly in the lead" (which also would require a mere 6 bytes), and so forth. +The version number allows us to shrink the upvote vector in many cases. Version 0x00 requires a full two bytes per sidechain, but it always works. Version 0x01 uses half that (one byte per sidechain), and it works while all sidechains have fewer than 255 disputed withdrawals (ie, 99.99%+ of the time). Version 0x02 uses zero bytes (ie, 6 bytes for the whole M4) and sets this block's M4 equal to the previous block's M4. Version 0x03 upvotes only those withdrawals that are leading their rivals by at least 50 votes. If a sidechain has no pending bundles, then it is skipped over when M4 is created and parsed. -The upvote vector will code "abstain" as 0xFF (or 0xFFFF); it will code "alarm" as 0xFE (or 0xFFFE). Otherwise it simply indicates which withdrawal-bundle in the list, is the one to be "upvoted". For example, if there are two sidechains, and we wish to upvote the 7th bundle on sidechain #1 plus the 4th bundle on sidechain #2, then the vector would be 0x0704. +For example, an upvote vector of { 2 , N/A, 1 } would be represented as [0x6A,D77D1776,01,00,00]. It means: "upvote the first bundle in sidechain #1; and the first bundle in sidechain #3" (iff sidechains #2 has no bundles proposed). -The M4 message will be invalid (and invalidate the block), if it tries to upvote a Bundle that doesn't exist (for example, trying to upvote the 7th bundle on sidechain #2, when sidechain #2 has only three bundles). If there are no Bundles at all (no one is trying to withdraw from any sidechain), then *any* M4 message present in the coinbase will be invalid. If M4 is NOT present in a block, then it is treated as "abstain". +An upvote vector of { N/A, N/A, 4 } would be [0x6A,D77D1776,01,03]. -The ACKed withdrawal will gain one point for its ACK field. Therefore, the ACK-counter of any Bundle can only change by (-1,0,+1). -Within a sidechain-group, upvoting one Bundle ("+1") requires you to downvote all other Bundles in that group. However, the minimum ACK-counter is zero. While only one Bundle can be upvoted at once; the whole group can all be unchanged at once ("abstain"), and they can all be downvoted at once ("alarm"). +The M4 message will be invalid (and invalidate the block), if: -Finally, we describe Deposits and Withdrawals. +* It tries to upvote a Bundle that doesn't exist. (For example, trying to upvote the 7th bundle on sidechain #2, when sidechain #2 has only three bundles.) +* There are no Bundles at all, from any sidechain. + +If M4 is NOT present in a block, then it is treated as "abstain". + +If M4 is present and valid: each withdrawal-bundle that is ACKed, will gain one upvote. + +Important: Within a sidechain-group, upvoting one Bundle ("+1") automatically downvotes ("-1") all other Bundles in that group. However, the minimum ACK-counter is zero. While only one Bundle can be upvoted at once; the whole group can all be unchanged at once ("abstain"), and they can all be downvoted at once ("alarm"). + +For example: + +{| class="wikitable" +|- +! SC# +! Bundle Hash +! ACKs +! Blocks Remaining +|- +| 1 +| h1 +| 45 +| 22,109 +|- +| 1 +| h2 +| 12 +| 22,008 +|- +| 2 +| h3 +| 13 +| 22,999 +|- +| 2 +| h4 +| 8 +| 23,550
+|- +| 2 +| h5 +| 2 +| 22,560 +|} + + +...in block 900,000 could become... + + +{| class="wikitable" +|- +! SC# +! Bundle Hash +! ACKs +! Blocks Remaining +|- +| 1 +| h1 +| 46 +| 22,108 +|- +| 1 +| h2 +| 11 +| 22,007 +|- +| 2 +| h3 +| 12 +| 22,998 +|- +| 2 +| h4 +| 9 +| 23,549
+|- +| 2 +| h5 +| 1 +| 22,559 +|} + +...if M4 were [0x6A,D77D1776,00,0000,0001]. +Finally, we describe Deposits and Withdrawals. + ==== M5 -- Deposit BTC to Sidechain ==== -Both M5 and M6 are regular Bitcoin txns. They are distinguished from regular txns (non-M5 non-M6 txns), when they select one of the special Bip300 CTIP UTXOs as one of their inputs (see D1). +Each sidechain stores all its BTC in one UTXO, called the "CTIP". -All of a sidechain’s coins, are stored in one UTXO, called the "CTIP". Every time a deposit or withdrawal is made, the CTIP changes. Each deposit/withdrawal will select the sidechains CTIP, and generate a new CTIP. (Deposits/Withdrawals never cause UTXO bloat.) The current CTIP is cached in D1 (above). +By definition, an M5 is a transaction which spends the CTIP and '''increases''' the quantity of coins. An M6 is a transaction which spends the CTIP and '''decreases''' the quantity of coins in the CTIP. See [https://github.com/LayerTwo-Labs/mainchain/blob/391ab390adaa19f92871d769f8e120ca62c1cf14/src/validation.cpp#L688-L801 here]. -If the '''quantity of coins''', in the from-CTIP-to-CTIP transaction, goes '''up''', (ie, if the user is adding coins), then the txn is treated as a Deposit (M5). Else it is treated as a Withdrawal (M6). See [https://github.com/drivechain-project/mainchain/blob/e37b008fafe0701b8313993c8b02ba41dc0f8a29/src/validation.cpp#L667-L780 here]. +Every time a deposit/withdrawal is made, the old CTIP is spent and a new one is created. (Deposits/Withdrawals never cause UTXO bloat.) At all times, the CTIP of each sidechain is cached in D1 (above). + +Every M5 is valid, as long as: + +* It has at least one OP_TRUE output -- this becomes the new CTIP. +* The new CTIP has '''more''' coins in it, than before. -As far as mainchain consensus is concerned, all deposits to a sidechain are always valid. ==== M6 -- Withdraw BTC from a Sidechain ==== We come, finally, to the critical matter: where users can take their money *out* of the sidechain. -First, M6 must obey the same CTIP rules of M5 (see immediately above). +M6 is invalid if: + +* The blinded hash of M6 does NOT match one of the approved Bundle-hashes. (In other words: M6 must first be approved by 13,150 upvotes.) +* The first output of M6 is NOT an OP_TRUE. (This OP_TRUE becomes the new CTIP. In other words: all non-withdrawn coins are paid back to the sidechain.) +* The second output is NOT an OP_RETURN script of exactly 10 bytes, of which 8 bytes are a serialized Bitcoin amount. +* The txn fee of M6 is NOT exactly equal to the amount of the previous bullet point. + +Else, M6 is valid. + +(The point of the latter two bullet points, is to allow the bundle hash to cover the L1 transaction fee.) -Second, an M6 is only valid for inclusion in a block, if its blinded TxID matches an "approved" Bundle hash (ie, one with an ACK score of 13150+). In other words, an M6 can only be included in a block, after the 3+ month (13150 block) ceremony. -Third, M6 must meet two accounting criteria, lest it be invalid: -# "Give change back to Escrow" -- The first output, TxOut0, must be paid back to the sidechain's Bip300 script. In other words, all non-withdrawn coins must be paid back into the sidechain. -# "No traditional txn fee" -- For this txn, the sum of all inputs must equal the sum of all outputs. No traditional tx fee is possible. (Of course, there is still a txn fee for miners: it is paid via an OP TRUE output in the Bundle.) We want the withdraw-ers to set the fee "inside" the Bundle, and ACK it over 3 months like everything else. ==Backward compatibility== @@ -331,7 +444,7 @@ See http://www.drivechain.info/literature/index.html ==Credits== -Thanks to everyone who contributed to the discussion, especially: ZmnSCPxj, Adam Back, Peter Todd, Dan Anderson, Sergio Demian Lerner, Chris Stewart, Matt Corallo, Sjors Provoost, Tier Nolan, Erik Aronesty, Jason Dreyzehner, Joe Miyamoto, Ben Goldhaber. +Thanks to everyone who contributed to the discussion, especially: Luke Dashjr, ZmnSCPxj, Adam Back, Peter Todd, Dan Anderson, Sergio Demian Lerner, Chris Stewart, Matt Corallo, Sjors Provoost, Tier Nolan, Erik Aronesty, Jason Dreyzehner, Joe Miyamoto, Ben Goldhaber. ==Copyright== From 2cccaf650fc3f8bfbd0c8429ee52245cb2db311f Mon Sep 17 00:00:00 2001 From: Luke Dashjr Date: Wed, 26 Jul 2023 19:45:51 +0000 Subject: [PATCH 104/454] bip-0300: Add OP_DRIVECHAIN --- bip-0300.mediawiki | 14 +++++++++++--- 1 file changed, 11 insertions(+), 3 deletions(-) diff --git a/bip-0300.mediawiki b/bip-0300.mediawiki index 6ee07600f0..20c558466c 100644 --- a/bip-0300.mediawiki +++ b/bip-0300.mediawiki @@ -226,7 +226,7 @@ A sidechain fails to activate if: Otherwise, the sidechain activates (Active is set to TRUE). -In the block in which the sidechain activates, the coinbase MUST include at least one 0-valued OP_TRUE. This output becomes the initial CTIP for the sidechain. +In the block in which the sidechain activates, the coinbase MUST include at least one 0-valued OP_DRIVECHAIN output. This output becomes the initial CTIP for the sidechain. @@ -394,7 +394,7 @@ Every time a deposit/withdrawal is made, the old CTIP is spent and a new one is Every M5 is valid, as long as: -* It has at least one OP_TRUE output -- this becomes the new CTIP. +* It has at least one OP_DRIVECHAIN output -- this becomes the new CTIP. * The new CTIP has '''more''' coins in it, than before. @@ -405,7 +405,7 @@ We come, finally, to the critical matter: where users can take their money *out* M6 is invalid if: * The blinded hash of M6 does NOT match one of the approved Bundle-hashes. (In other words: M6 must first be approved by 13,150 upvotes.) -* The first output of M6 is NOT an OP_TRUE. (This OP_TRUE becomes the new CTIP. In other words: all non-withdrawn coins are paid back to the sidechain.) +* The first output of M6 is NOT an OP_DRIVECHAIN. (This OP_DRIVECHAIN becomes the new CTIP. In other words: all non-withdrawn coins are paid back to the sidechain.) * The second output is NOT an OP_RETURN script of exactly 10 bytes, of which 8 bytes are a serialized Bitcoin amount. * The txn fee of M6 is NOT exactly equal to the amount of the previous bullet point. @@ -413,8 +413,16 @@ Else, M6 is valid. (The point of the latter two bullet points, is to allow the bundle hash to cover the L1 transaction fee.) +===OP_DRIVECHAIN=== +This proposal adds a single new opcode, OP_DRIVECHAIN, which has strict semantics for usage. +OP_NOP5 (0xb4) is redefined as OP_DRIVECHAIN if and only if the entire script is OP_DRIVECHAIN followed by a single-byte push and OP_TRUE (exactly 4 bytes). +The single-byte push contains the sidechain number. +Note that this is not a "script number", and cannot be OP_1..OP_16 or any other kind of push; it is also unsigned, and must not be padded even if over sidechain number 127. +The final OP_TRUE is to ensure this change remains a softfork: +without it, sidechain numbers 0 and 128 would cause the legacy script interpreter to fail. +If an OP_DRIVECHAIN input is spent, the additional rules for M5 or M6 (see above) must be enforced. ==Backward compatibility== From 69d872461b239059d134c195347267289e19535d Mon Sep 17 00:00:00 2001 From: Luke Dashjr Date: Wed, 26 Jul 2023 19:53:36 +0000 Subject: [PATCH 105/454] bip-0300: Fix upvote vector example --- bip-0300.mediawiki | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/bip-0300.mediawiki b/bip-0300.mediawiki index 20c558466c..5a09935fe6 100644 --- a/bip-0300.mediawiki +++ b/bip-0300.mediawiki @@ -291,7 +291,7 @@ The version number allows us to shrink the upvote vector in many cases. Version If a sidechain has no pending bundles, then it is skipped over when M4 is created and parsed. -For example, an upvote vector of { 2 , N/A, 1 } would be represented as [0x6A,D77D1776,01,00,00]. It means: "upvote the first bundle in sidechain #1; and the first bundle in sidechain #3" (iff sidechains #2 has no bundles proposed). +For example, an upvote vector of { 2 , N/A, 1 } would be represented as [0x6A,D77D1776,01,01,00]. It means: "upvote the second bundle in sidechain #1; and the first bundle in sidechain #3" (iff sidechains #2 has no bundles proposed). An upvote vector of { N/A, N/A, 4 } would be [0x6A,D77D1776,01,03]. From 9d4ec80215727779142862d023c5d253ed3a997b Mon Sep 17 00:00:00 2001 From: Luke Dashjr Date: Wed, 26 Jul 2023 19:54:18 +0000 Subject: [PATCH 106/454] bip-0300: Reorder upvote vector version numbers to leave 1/2 bytes as version 1,2 respectively --- bip-0300.mediawiki | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/bip-0300.mediawiki b/bip-0300.mediawiki index 5a09935fe6..0f2ef6e97a 100644 --- a/bip-0300.mediawiki +++ b/bip-0300.mediawiki @@ -287,7 +287,11 @@ The upvote vector will code "abstain" as 0xFF (or 0xFFFF); it will code "alarm" For example: if there are two sidechains, and we wish to upvote the 7th bundle on sidechain #1 plus the 4th bundle on sidechain #2, then the upvote vector would be { 07, 04 }. And M4 would be [0x6A,D77D1776,00,0006,0003]. -The version number allows us to shrink the upvote vector in many cases. Version 0x00 requires a full two bytes per sidechain, but it always works. Version 0x01 uses half that (one byte per sidechain), and it works while all sidechains have fewer than 255 disputed withdrawals (ie, 99.99%+ of the time). Version 0x02 uses zero bytes (ie, 6 bytes for the whole M4) and sets this block's M4 equal to the previous block's M4. Version 0x03 upvotes only those withdrawals that are leading their rivals by at least 50 votes. +The version number allows us to shrink the upvote vector in many cases. +Version 0x00 omits the upvote vector entirely (ie, 6 bytes for the whole M4) and sets this block's M4 equal to the previous block's M4. +Version 0x01 uses one byte per sidechain, and can be used while all ACKed withdrawals have an index under 256 (ie, 99.99%+ of the time). +Version 0x02 uses a full two bytes per sidechain, but it always works no matter how many withdrawl proposals exist. +Version 0x03 omits the upvote vector, and instead upvotes only those withdrawals that are leading their rivals by at least 50 votes. If a sidechain has no pending bundles, then it is skipped over when M4 is created and parsed. From accaee0f33c9f8cb80dd74f8c024f01fd4c02de5 Mon Sep 17 00:00:00 2001 From: Luke Dashjr Date: Wed, 26 Jul 2023 19:59:11 +0000 Subject: [PATCH 107/454] bip-0300: Define endianness of upvote vector --- bip-0300.mediawiki | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/bip-0300.mediawiki b/bip-0300.mediawiki index 0f2ef6e97a..a265374552 100644 --- a/bip-0300.mediawiki +++ b/bip-0300.mediawiki @@ -290,7 +290,7 @@ For example: if there are two sidechains, and we wish to upvote the 7th bundle o The version number allows us to shrink the upvote vector in many cases. Version 0x00 omits the upvote vector entirely (ie, 6 bytes for the whole M4) and sets this block's M4 equal to the previous block's M4. Version 0x01 uses one byte per sidechain, and can be used while all ACKed withdrawals have an index under 256 (ie, 99.99%+ of the time). -Version 0x02 uses a full two bytes per sidechain, but it always works no matter how many withdrawl proposals exist. +Version 0x02 uses a full two bytes per sidechain (each encoded in little endian), but it always works no matter how many withdrawl proposals exist. Version 0x03 omits the upvote vector, and instead upvotes only those withdrawals that are leading their rivals by at least 50 votes. If a sidechain has no pending bundles, then it is skipped over when M4 is created and parsed. From badaf01360374ed9c95ed70042761d5bca99af20 Mon Sep 17 00:00:00 2001 From: Luke Dashjr Date: Wed, 26 Jul 2023 19:59:59 +0000 Subject: [PATCH 108/454] bip-0300: Forbid extraneous OP_DRIVECHAIN outputs in M5/M6 --- bip-0300.mediawiki | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/bip-0300.mediawiki b/bip-0300.mediawiki index a265374552..6f8a13c2e8 100644 --- a/bip-0300.mediawiki +++ b/bip-0300.mediawiki @@ -398,7 +398,7 @@ Every time a deposit/withdrawal is made, the old CTIP is spent and a new one is Every M5 is valid, as long as: -* It has at least one OP_DRIVECHAIN output -- this becomes the new CTIP. +* It has exactly one OP_DRIVECHAIN output -- this becomes the new CTIP. * The new CTIP has '''more''' coins in it, than before. @@ -412,6 +412,7 @@ M6 is invalid if: * The first output of M6 is NOT an OP_DRIVECHAIN. (This OP_DRIVECHAIN becomes the new CTIP. In other words: all non-withdrawn coins are paid back to the sidechain.) * The second output is NOT an OP_RETURN script of exactly 10 bytes, of which 8 bytes are a serialized Bitcoin amount. * The txn fee of M6 is NOT exactly equal to the amount of the previous bullet point. +* There are additional OP_DRIVECHAIN outputs after the first one. Else, M6 is valid. From 796c80eb9d78ba5bf64505fab11896c24030e9cf Mon Sep 17 00:00:00 2001 From: Luke Dashjr Date: Wed, 26 Jul 2023 20:07:54 +0000 Subject: [PATCH 109/454] bip-0300: Ensure tx fee commitment itself has zero value so sidechain coins can't get burned --- bip-0300.mediawiki | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/bip-0300.mediawiki b/bip-0300.mediawiki index 6f8a13c2e8..0a7315baf6 100644 --- a/bip-0300.mediawiki +++ b/bip-0300.mediawiki @@ -410,7 +410,7 @@ M6 is invalid if: * The blinded hash of M6 does NOT match one of the approved Bundle-hashes. (In other words: M6 must first be approved by 13,150 upvotes.) * The first output of M6 is NOT an OP_DRIVECHAIN. (This OP_DRIVECHAIN becomes the new CTIP. In other words: all non-withdrawn coins are paid back to the sidechain.) -* The second output is NOT an OP_RETURN script of exactly 10 bytes, of which 8 bytes are a serialized Bitcoin amount. +* The second output is NOT a zero-value OP_RETURN script of exactly 10 bytes, of which 8 bytes are a serialized Bitcoin amount. * The txn fee of M6 is NOT exactly equal to the amount of the previous bullet point. * There are additional OP_DRIVECHAIN outputs after the first one. From c2f4825550b5e13df0c8db650610808e1869cefd Mon Sep 17 00:00:00 2001 From: Luke Dashjr Date: Wed, 26 Jul 2023 20:39:45 +0000 Subject: [PATCH 110/454] bip-0300: Add some guesstimate weight adjustments --- bip-0300.mediawiki | 47 ++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 47 insertions(+) diff --git a/bip-0300.mediawiki b/bip-0300.mediawiki index 0a7315baf6..ab81c3223c 100644 --- a/bip-0300.mediawiki +++ b/bip-0300.mediawiki @@ -429,6 +429,53 @@ without it, sidechain numbers 0 and 128 would cause the legacy script interprete If an OP_DRIVECHAIN input is spent, the additional rules for M5 or M6 (see above) must be enforced. +====Weight adjustments==== + +To account for the additional drivechain checks, each message adds to the block's weight: + +{|class="wikitable" +! Message !! Additional weight +|- +| M1 || 840 +|- +| M2 || 336 +|- +| M3 || 848 +|- +| M4 || ? +|- +| M5 || 340 +|- +| M6 || 352 +|} + + + + ==Backward compatibility== As a soft fork, older software will continue to operate without modification. Non-upgraded nodes will see a number of phenomena that they don't understand -- coinbase txns with non-txn data, value accumulating in anyone-can-spend UTXOs for months at a time, and then random amounts leaving these UTXOs in single, infrequent bursts. However, these phenomena don't affect them, or the validity of the money that they receive. From 0033fd876fec06de361c0740ed97940dbfda1d9f Mon Sep 17 00:00:00 2001 From: Jeremy Rubin Date: Fri, 28 Jul 2023 17:34:38 -0400 Subject: [PATCH 111/454] Add James O'Beirne to 119 Author List --- bip-0119.mediawiki | 1 + 1 file changed, 1 insertion(+) diff --git a/bip-0119.mediawiki b/bip-0119.mediawiki index 86defa7cf7..acbe97cf81 100644 --- a/bip-0119.mediawiki +++ b/bip-0119.mediawiki @@ -3,6 +3,7 @@ Layer: Consensus (soft fork) Title: CHECKTEMPLATEVERIFY Author: Jeremy Rubin + James O'Beirne Comments-URI: https://github.com/bitcoin/bips/wiki/Comments:BIP-0119 Status: Draft Type: Standards Track From 2f1e2bc4d8ea0da70b7e840875292b0a5df8228e Mon Sep 17 00:00:00 2001 From: sgmoore Date: Tue, 15 Aug 2023 12:54:34 -0700 Subject: [PATCH 112/454] added colon at end of if statement - bip-0119.mediawiki Python requires a colon at the end of an if statement to denote the beginning of the block of code that will be executed if the condition is True. If the colon is omitted, a syntax error will occur, and the code will not run. Since the syntax error will prevent the code from running, it won't introduce any vulnerabilities by itself. However, it will cause the application to fail at the point where the code is parsed, which might expose other issues if error handling is not implemented properly. --- bip-0119.mediawiki | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/bip-0119.mediawiki b/bip-0119.mediawiki index 86defa7cf7..99554009b8 100644 --- a/bip-0119.mediawiki +++ b/bip-0119.mediawiki @@ -88,7 +88,7 @@ def execute_bip_119(self): self.context.precomputed_ctv_data = self.context.tx.get_default_check_template_precomputed_data() # If the hashes do not match, return error - if stack[-1] != self.context.tx.get_default_check_template_hash(self.context.nIn, self.context.precomputed_ctv_data) + if stack[-1] != self.context.tx.get_default_check_template_hash(self.context.nIn, self.context.precomputed_ctv_data): return self.errors_with(errors.script_err_template_mismatch) return self.return_as_nop() From 91bbe3307c622a420d328407d29739a41a3f8b82 Mon Sep 17 00:00:00 2001 From: Chun Date: Sun, 20 Aug 2023 08:59:19 +0100 Subject: [PATCH 113/454] Update bip-0087.mediawiki typo fix --- bip-0087.mediawiki | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/bip-0087.mediawiki b/bip-0087.mediawiki index d270027e57..308e8521e5 100644 --- a/bip-0087.mediawiki +++ b/bip-0087.mediawiki @@ -40,7 +40,7 @@ A modern standardization is needed for multisig derivation paths. There are som m / purpose' / cosigner_index / change / address_index -BIP45 unecessarily demands a single script type (here, P2SH). In addition, BIP45 sets cosigner_index in order to sort the purpose' public keys of each cosigner. This too is redundant, as descriptors can set the order of the public keys with multi or have them sorted lexicographically (as described in [https://github.com/bitcoin/bips/blob/master/bip-0067.mediawiki BIP67]) with sortedmulti. Sorting public keys between cosigners in order to create the full derivation path, prior to sending the key record to the coordinator to create the descriptor, merely adds additional unnecessary communication rounds. +BIP45 unnecessarily demands a single script type (here, P2SH). In addition, BIP45 sets cosigner_index in order to sort the purpose' public keys of each cosigner. This too is redundant, as descriptors can set the order of the public keys with multi or have them sorted lexicographically (as described in [https://github.com/bitcoin/bips/blob/master/bip-0067.mediawiki BIP67]) with sortedmulti. Sorting public keys between cosigners in order to create the full derivation path, prior to sending the key record to the coordinator to create the descriptor, merely adds additional unnecessary communication rounds. The second multisignature "standard" in use is m/48', which specifies: From 496b6c9ecc61ef7c80ce00c8925cad627bf034f6 Mon Sep 17 00:00:00 2001 From: Sebastian Falbesoner Date: Tue, 29 Aug 2023 23:39:04 +0200 Subject: [PATCH 114/454] bip-0158: remove unused and unrelated "data pushes" definition This BIP is not in any way connected to the rules of Bitcoin script, i.e. the "data pushes" term is also not used anywhere and its definition can hence be removed. --- bip-0158.mediawiki | 3 --- 1 file changed, 3 deletions(-) diff --git a/bip-0158.mediawiki b/bip-0158.mediawiki index 8887d32f14..a3e0269413 100644 --- a/bip-0158.mediawiki +++ b/bip-0158.mediawiki @@ -39,9 +39,6 @@ that is designed to reduce the filter size for regular wallets. ''CompactSize'' is a compact encoding of unsigned integers used in the Bitcoin P2P protocol. -''Data pushes'' are byte vectors pushed to the stack according to the rules of -Bitcoin script. - ''Bit streams'' are readable and writable streams of individual bits. The following functions are used in the pseudocode in this document: * new_bit_stream instantiates a new writable bit stream From 4aae726be9610a675b362e66f539ce0d5f903a5f Mon Sep 17 00:00:00 2001 From: James O'Beirne Date: Fri, 1 Sep 2023 10:12:38 -0400 Subject: [PATCH 115/454] fixup! fix off-by-one and revault-idx malleability Co-authored-by: sanket1729 --- bip-0345.mediawiki | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/bip-0345.mediawiki b/bip-0345.mediawiki index 1447346b15..87e084cc68 100644 --- a/bip-0345.mediawiki +++ b/bip-0345.mediawiki @@ -246,10 +246,9 @@ where * is an up to 4-byte CScriptNum-encoded number indicating how many leaf-update script items should be popped off the stack. '''Why only prepending with data pushes?''' Prepending the leaf-update-script-body with opcodes opens up the door to prepending OP_SUCCESSX opcodes, to name a single issue only, side-stepping the validation that was meant to be run by the committed script. ** If this value does not decode to a valid CScriptNum, script execution when spending this output MUST fail and terminate immediately. ** If this value is less than 0, script execution when spending this output MUST fail and terminate immediately. -** If fewer than + 2 items are on the stack, script execution when spending this output MUST fail and terminate immediately. +** If there are fewer than 3 items following the items on the stack, script execution when spending this output MUST fail and terminate immediately. In other words, after popping , there must be at least 3 + items remaining on the stack. * The following stack items are popped off the stack and prefixed as minimally-encoded push-data arguments to the to construct the expected tapleaf replacement script. -** If there are fewer than + 2 items on the stack, script execution when spending this output MUST fail and terminate immediately. * is an up to 4-byte CScriptNum-encoded number indicating the index of the output which, in conjunction with an optional revault output, carries forward the value of this input, and has an identical taptree aside from the currently executing leaf. ** If this value does not decode to a valid CScriptNum, script execution when spending this output MUST fail and terminate immediately. @@ -258,6 +257,7 @@ where * is an up to 4-byte CScriptNum-encoded number optionally indicating the index of an output which, in conjunction with the trigger output, carries forward the value of this input, and has an identical scriptPubKey to the current input. ** If this value does not decode to a valid CScriptNum, script execution when spending this output MUST fail and terminate immediately. ** If this value is greater than or equal to the number of outputs, script execution when spending this output MUST fail and terminate immediately. +** If this value is negative and not equal to -1, script execution when spending this output MUST fail and terminate immediately.'''Why is -1 the only allowable negative value for revault-vout-idx?''' A negative revault index indicates that no revault output exists; if this value were allowed to be any negative number, the witness could be malleated (and bloated) while a transaction is waiting for confirmation. * is an up to 7-byte CScriptNum-encoded number indicating the number of satoshis being revaulted. ** If this value does not decode to a valid CScriptNum, script execution when spending this output MUST fail and terminate immediately. From 175c5c06e03f469038d4de96a4e6acfb444b8c59 Mon Sep 17 00:00:00 2001 From: Pieter Wuille Date: Mon, 11 Sep 2023 12:00:53 -0400 Subject: [PATCH 116/454] Use 16-byte prefix to distinguish v1 from v2 --- bip-0324.mediawiki | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/bip-0324.mediawiki b/bip-0324.mediawiki index 7bd10dcb76..62e9005df4 100644 --- a/bip-0324.mediawiki +++ b/bip-0324.mediawiki @@ -112,7 +112,7 @@ Given a newly established connection (typically TCP/IP) between two v2 P2P nodes #** Generates a random ephemeral secp256k1 private key and sends a corresponding 64-byte ElligatorSwift'''What is ElligatorSwift and why use it?''' The [https://eprint.iacr.org/2022/759.pdf SwiftEC paper] describes a method called ElligatorSwift which allows encoding elliptic curve points in a way that is indistinguishable from a uniformly distributed bitstream. While a random 256-bit string has about 50% chance of being a valid X coordinate on the secp256k1 curve, every 512-bit string is a valid ElligatorSwift encoding of a curve point, making the encoded point indistinguishable from random when using an encoder that can sample uniformly.'''How fast is ElligatorSwift?''' Our benchmarks show that ElligatorSwift encoded ECDH is about 50% more expensive than unencoded ECDH. Given the fast performance of ECDH and the low frequency of new connections, we found the performance trade-off acceptable for the pseudorandom bytestream and future censorship resistance it can enable.-encoded public key to the responder. #** May send up to 4095'''How was the limit of 4095 bytes garbage chosen?''' It is a balance between having sufficient freedom to hide information, and allowing it to be large enough so that the necessary 64 bytes of public key is small compared to it on the one hand, and bandwidth waste on the other hand. bytes of arbitrary data after their public key, called '''garbage''', providing a form of shapability and avoiding a recognizable pattern of exactly 64 bytes.'''Why does the affordance for garbage exist in the protocol?''' The garbage strings after the public keys are needed for shapability of the handshake. Neither peer can send decoy packets before having received at least the other peer's public key, i.e., neither peer can send more than 64 bytes before having received 64 bytes. #* The responder: -#** Waits until one byte is received which does not match the 12 bytes consisting of the network magic followed by "version\x00". If the first 12 bytes do match, the connection is treated as using the v1 protocol instead.'''What if a v2 initiator's public key starts accidentally with these 12 bytes?''' This is so unlikely (probability of ''2-96'') to happen randomly in the v2 protocol that the initiator does not need to specifically avoid it.Bitcoin Core versions <=0.4.0 and >=22.0 ignore valid P2P messages that are received prior to a VERSION message. Bitcoin Core versions between 0.4.0 and 22.0 assign a misbehavior score to the peer upon receiving such messages. v2 clients implementing this proposal will interpret any message other than VERSION received as the first message to be the initiation of a v2 connection, and will result in disconnection for v1 initiators that send any message type other than VERSION as the first message. We are not aware of any implementations where this could pose a problem. +#** Waits until one byte is received which does not match the 16 bytes consisting of the network magic followed by "version\x00\x00\x00\x00\x00". If the first 16 bytes do match, the connection is treated as using the v1 protocol instead.'''What if a v2 initiator's public key starts accidentally with these 16 bytes?''' This is so unlikely (probability of ''2-128'') to happen randomly in the v2 protocol that the initiator does not need to specifically avoid it.Bitcoin Core versions <=0.4.0 and >=22.0 ignore valid P2P messages that are received prior to a VERSION message. Bitcoin Core versions between 0.4.0 and 22.0 assign a misbehavior score to the peer upon receiving such messages. v2 clients implementing this proposal will interpret any message other than VERSION received as the first message to be the initiation of a v2 connection, and will result in disconnection for v1 initiators that send any message type other than VERSION as the first message. We are not aware of any implementations where this could pose a problem. #** Similarly generates a random ephemeral private key and sends a corresponding 64-byte ElligatorSwift-encoded public key to the initiator. #** Similarly may send up to 4095 bytes of garbage data after their public key. #* Both parties: @@ -136,8 +136,8 @@ Given a newly established connection (typically TCP/IP) between two v2 P2P nodes To avoid the recognizable pattern of first messages being at least 64 bytes, a future backwards-compatible upgrade to this protocol may allow both peers to send their public key + garbage + garbage terminator in multiple rounds, slicing those bytes up into messages arbitrarily, as long as progress is guaranteed.'''How can progress be guaranteed in a backwards-compatible way?''' In order to guarantee progress, it must be ensured that no deadlock occurs, i.e., no state is reached in which each party waits for the other party indefinitely. For example, any upgrade that adheres to the following conditions will guarantee progress: -* The initiator must start by sending at least as many bytes as necessary to mismatch the magic/version 12 bytes prefix. -* The responder must start sending after having received at least one byte that mismatches that 12-byte prefix. +* The initiator must start by sending at least as many bytes as necessary to mismatch the magic/version 16 bytes prefix. +* The responder must start sending after having received at least one byte that mismatches that 16-byte prefix. * As soon as either party has received the other peer's garbage terminator, or has received 4095 bytes of garbage, they must send their own garbage terminator. (When either of these conditions is met, the other party has nothing to respond with anymore that would be needed to guarantee progress otherwise.) * Whenever either party receives any nonzero number of bytes, while not having sent their garbage terminator completely yet, they must send at least one byte in response without waiting for more bytes. * After either party has sent their garbage terminator, they must also send the garbage authentication packet without waiting for more bytes, and transition to the version negotiation phase. @@ -338,16 +338,16 @@ def initiate_v2_handshake(peer, garbage_len): send(peer, peer.ellswift_ours + peer.sent_garbage) -The responder generates an ephemeral keypair for itself and derives the shared ECDH secret (using the first 64 received bytes) which enables it to instantiate the encrypted transport. It then sends 64 bytes of the unencrypted ElligatorSwift encoding of its own public key and its own responder_garbage also of length garbage_len < 4096. If the first 12 bytes received match the v1 prefix, the v1 protocol is used instead. +The responder generates an ephemeral keypair for itself and derives the shared ECDH secret (using the first 64 received bytes) which enables it to instantiate the encrypted transport. It then sends 64 bytes of the unencrypted ElligatorSwift encoding of its own public key and its own responder_garbage also of length garbage_len < 4096. If the first 16 bytes received match the v1 prefix, the v1 protocol is used instead.
 TRANSPORT_VERSION = b''
 NETWORK_MAGIC = b'\xf9\xbe\xb4\xd9' # Mainnet network magic; differs on other networks.
-V1_PREFIX = NETWORK_MAGIC + b'version\x00'
+V1_PREFIX = NETWORK_MAGIC + b'version\x00\x00\x00\x00\x00'
 
 def respond_v2_handshake(peer, garbage_len):
     peer.received_prefix = b""
-    while len(peer.received_prefix) < 12:
+    while len(peer.received_prefix) < len(V1_PREFIX):
         peer.received_prefix += receive(peer, 1)
         if peer.received_prefix[-1] != V1_PREFIX[len(peer.received_prefix) - 1]:
             peer.privkey_ours, peer.ellswift_ours = ellswift_create()

From 397016ebdf43050bf76d741cfd41e1ec9879a3a7 Mon Sep 17 00:00:00 2001
From: Pieter Wuille 
Date: Mon, 11 Sep 2023 13:39:36 -0400
Subject: [PATCH 117/454] Allow detecting/disconnecting wrong-network v1 peers

---
 bip-0324.mediawiki | 6 +++++-
 1 file changed, 5 insertions(+), 1 deletion(-)

diff --git a/bip-0324.mediawiki b/bip-0324.mediawiki
index 62e9005df4..28dd62c98c 100644
--- a/bip-0324.mediawiki
+++ b/bip-0324.mediawiki
@@ -112,7 +112,8 @@ Given a newly established connection (typically TCP/IP) between two v2 P2P nodes
 #** Generates a random ephemeral secp256k1 private key and sends a corresponding 64-byte ElligatorSwift'''What is ElligatorSwift and why use it?''' The [https://eprint.iacr.org/2022/759.pdf SwiftEC paper] describes a method called ElligatorSwift which allows encoding elliptic curve points in a way that is indistinguishable from a uniformly distributed bitstream. While a random 256-bit string has about 50% chance of being a valid X coordinate on the secp256k1 curve, every 512-bit string is a valid ElligatorSwift encoding of a curve point, making the encoded point indistinguishable from random when using an encoder that can sample uniformly.'''How fast is ElligatorSwift?''' Our benchmarks show that ElligatorSwift encoded ECDH is about 50% more expensive than unencoded ECDH. Given the fast performance of ECDH and the low frequency of new connections, we found the performance trade-off acceptable for the pseudorandom bytestream and future censorship resistance it can enable.-encoded public key to the responder.
 #** May send up to 4095'''How was the limit of 4095 bytes garbage chosen?''' It is a balance between having sufficient freedom to hide information, and allowing it to be large enough so that the necessary 64 bytes of public key is small compared to it on the one hand, and bandwidth waste on the other hand. bytes of arbitrary data after their public key, called '''garbage''', providing a form of shapability and avoiding a recognizable pattern of exactly 64 bytes.'''Why does the affordance for garbage exist in the protocol?''' The garbage strings after the public keys are needed for shapability of the handshake. Neither peer can send decoy packets before having received at least the other peer's public key, i.e., neither peer can send more than 64 bytes before having received 64 bytes.
 #* The responder:
-#** Waits until one byte is received which does not match the 16 bytes consisting of the network magic followed by "version\x00\x00\x00\x00\x00". If the first 16 bytes do match, the connection is treated as using the v1 protocol instead.'''What if a v2 initiator's public key starts accidentally with these 16 bytes?''' This is so unlikely (probability of ''2-128'') to happen randomly in the v2 protocol that the initiator does not need to specifically avoid it.Bitcoin Core versions <=0.4.0 and >=22.0 ignore valid P2P messages that are received prior to a VERSION message. Bitcoin Core versions between 0.4.0 and 22.0 assign a misbehavior score to the peer upon receiving such messages. v2 clients implementing this proposal will interpret any message other than VERSION received as the first message to be the initiation of a v2 connection, and will result in disconnection for v1 initiators that send any message type other than VERSION as the first message. We are not aware of any implementations where this could pose a problem.
+#** Waits until one byte is received which does not match the 16 bytes consisting of the network magic followed by "version\x00\x00\x00\x00\x00". If the first 16 bytes do match, the connection is treated as using the v1 protocol instead.'''What if a v2 initiator's public key starts accidentally with these 16 bytes?''' This is so unlikely (probability of ''2-128'') to happen randomly in the v2 protocol that the initiator does not need to specifically avoid it. The optional detection of wrong-network v1 peers has a probability of ''2-96'', which is still negligible compared to random network failures.Bitcoin Core versions <=0.4.0 and >=22.0 ignore valid P2P messages that are received prior to a VERSION message. Bitcoin Core versions between 0.4.0 and 22.0 assign a misbehavior score to the peer upon receiving such messages. v2 clients implementing this proposal will interpret any message other than VERSION received as the first message to be the initiation of a v2 connection, and will result in disconnection for v1 initiators that send any message type other than VERSION as the first message. We are not aware of any implementations where this could pose a problem.
+#** If the first 4 received bytes do not match the network magic, but the 12 bytes after that do match the version message encoding above, implementations may interpret this as a v1 peer of a different network, and disconnect them.
 #** Similarly generates a random ephemeral private key and sends a corresponding 64-byte ElligatorSwift-encoded public key to the initiator.
 #** Similarly may send up to 4095 bytes of garbage data after their public key.
 #* Both parties:
@@ -363,6 +364,9 @@ Upon receiving the encoded responder public key, the initiator derives the share
 def complete_handshake(peer, initiating):
     received_prefix = b'' if initiating else peer.received_prefix
     ellswift_theirs = receive(peer, 64 - len(received_prefix))
+    if not initiating and ellswift_theirs[4:16] == V1_PREFIX[4:16]:
+        # Looks like a v1 peer from the wrong network.
+        disconnect(peer)
     ecdh_secret = v2_ecdh(peer.privkey_ours, ellswift_theirs, peer.ellswift_ours,
                           initiating=initiating)
     initialize_v2_transport(peer, ecdh_secret, initiating=True)

From cdcb6801a1774616ddff6f8fa0d95c3367a66a32 Mon Sep 17 00:00:00 2001
From: Pieter Wuille 
Date: Mon, 11 Sep 2023 13:40:15 -0400
Subject: [PATCH 118/454] For now, remove BIP330 messages before being adopted

---
 bip-0324.mediawiki | 7 ++-----
 1 file changed, 2 insertions(+), 5 deletions(-)

diff --git a/bip-0324.mediawiki b/bip-0324.mediawiki
index 28dd62c98c..1f3ca83594 100644
--- a/bip-0324.mediawiki
+++ b/bip-0324.mediawiki
@@ -558,12 +558,9 @@ The following table lists currently defined message type IDs:
 |GETCFHEADERS||CFHEADERS||GETCFCHECKPT||CFCHECKPT
 |-
 !+28
-|ADDRV2||REQRECON||SKETCH||REQSKETCHEXT
+|ADDRV2
 |-
-!+32
-|RECONCILDIFF
-|-
-!≥33
+!≥29
 || colspan="4" | (undefined)
 |}
 

From 75dc363d201072579289cc6d20d40ef7a67db291 Mon Sep 17 00:00:00 2001
From: Tim Ruffing 
Date: Sun, 24 Sep 2023 13:00:34 +0000
Subject: [PATCH 119/454] bip324: Remove garbage authentication packet
 (breaking change)

by merging it with the version packet. Or more accurately, by merging
it with the first packet sent after garbage termination, which may be
a decoy packet or the version packet.

The new protocol simplifies implementations:
 - A protocol state machine won't need separate states for garbage
   authentication and version phases.
 - The special case of "ignoring the ignore bit" is removed.
 - The freedom to choose the contents of the garbage authentication
   packet is removed. This simplifies testing.

The reason for having a separate garbage authentication packet was
to materialize the separation of the key exchange phase and version
negotiation phase even in the bytestream on the wire. However, this
is not necessary, and arguably, these phases are still properly
separated: Since the AEAD will ensure that AAD (=garbage) is checked
before looking at the contents (=version), the peers won't interpret
version data before having authenticated the garbage.
---
 bip-0324.mediawiki | 61 +++++++++++++++++++++++++---------------------
 1 file changed, 33 insertions(+), 28 deletions(-)

diff --git a/bip-0324.mediawiki b/bip-0324.mediawiki
index 1f3ca83594..8050b15d25 100644
--- a/bip-0324.mediawiki
+++ b/bip-0324.mediawiki
@@ -120,10 +120,11 @@ Given a newly established connection (typically TCP/IP) between two v2 P2P nodes
 #** Receive (the remainder of) the full 64-byte public key from the other side.
 #** Use X-only'''Why use X-only ECDH?''' Using only the X coordinate provides the same security as using a full encoding of the secret curve point but allows for more efficient implementation by avoiding the need for square roots to compute Y coordinates. ECDH to compute a shared secret from their private key and the exchanged public keys'''Why is the shared secret computation a function of the exact 64-byte public encodings sent?''' This makes sure that an attacker cannot modify the public key encoding used without modifying the rest of the stream. If a third party wants the ability to modify stream bytes, they need to perform a full MitM attack on the connection., and deterministically derive from the secret 4 '''encryption keys''' (two in each direction: one for packet lengths, one for content encryption), a '''session id''', and two 16-byte '''garbage terminators''''''What length is sufficient for garbage terminators?''' The length of the garbage terminators determines the probability of accidental termination of a legitimate v2 connection due to garbage bytes (sent prior to ECDH) inadvertently including the terminator. 16 byte terminators with 4095 bytes of garbage yield a negligible probability of such collision which is likely orders of magnitude lower than random connection failure on the Internet.'''What does a garbage terminator in the wild look like?''' 
[[File:bip-0324/garbage_terminator.png|none|256px|A garbage terminator model TX-v2 in the wild... sent by the responder]]
(one in each direction) using HKDF-SHA256. -#** Send their 16-byte garbage terminator'''Why does the protocol need a garbage terminator?''' While it is in principle possible to use the garbage authentication packet directly as a terminator (scan until a valid authentication packet follows), this would be significantly slower than just scanning for a fixed byte sequence, as it would require recomputing a Poly1305 tag after every received byte. followed by a '''garbage authentication packet''''''Why does the protocol require a garbage authentication packet?''' Without the garbage authentication packet, the garbage would be modifiable by a third party without consequences. We want to force any active attacker to have to maintain a full protocol state. In addition, such malleability without the consequence of connection termination could enable protocol fingerprinting., an '''encrypted packet''' (see further) with arbitrary '''contents''', and '''associated data''' equal to the garbage. +#** Send their 16-byte garbage terminator.'''Why does the protocol need a garbage terminator?''' While it is in principle possible to use the first packet after the garbage directly as a terminator (scan until a valid packet follows), this would be significantly slower than just scanning for a fixed byte sequence, as it would require recomputing a Poly1305 tag after every received byte. #** Receive up to 4111 bytes, stopping when encountering the garbage terminator. -#** Receive an encrypted packet, verify that it decrypts correctly with associated data set to the garbage received, and then ignore its contents. -#* At this point, both parties have the same keys, and all further communication proceeds in the form of encrypted packets. Packets have an '''ignore bit''', which makes them '''decoy packets''' if set. Decoy packets are to be ignored by the receiver apart from verifying they decrypt correctly. Either peer may send such decoy packets at any point after this. These form the primary shapability mechanism in the protocol. How and when to use them is out of scope for this document. +#* At this point, both parties have the same keys, and all further communication proceeds in the form of '''encrypted packets'''. +#** Encrypted packets have an '''ignore bit''', which makes them '''decoy packets''' if set. Decoy packets are to be ignored by the receiver apart from verifying they decrypt correctly. Either peer may send such decoy packets at any point from here on. These form the primary shapability mechanism in the protocol. How and when to use them is out of scope for this document. +#** For each of the two directions, the first encrypted packet that will be sent in that direction (regardless of it being a decoy packet or not) will make use of the associated authenticated data (AAD) feature of the AEAD to authenticate the garbage that has been sent in that direction.'''Why does the protocol authenticate the garbage?''' Without garbage authentication, the garbage would be modifiable by a third party without consequences. We want to force any active attacker to have to maintain a full protocol state. In addition, such malleability without the consequence of connection termination could enable protocol fingerprinting. # The '''Version negotiation phase''', where parties negotiate what transport version they will use, as well as data defined by that version.'''What features could be added in future protocol versions?''' Examples of features that could be added in future versions include post-quantum cryptography upgrades to the handshake, and optional authentication. #* The responder: #** Sends a '''version packet''' with empty content, to indicate support for the v2 P2P protocol proposed by this document. Any other value for content is reserved for future versions. @@ -141,15 +142,15 @@ To avoid the recognizable pattern of first messages being at least 64 bytes, a f * The responder must start sending after having received at least one byte that mismatches that 16-byte prefix. * As soon as either party has received the other peer's garbage terminator, or has received 4095 bytes of garbage, they must send their own garbage terminator. (When either of these conditions is met, the other party has nothing to respond with anymore that would be needed to guarantee progress otherwise.) * Whenever either party receives any nonzero number of bytes, while not having sent their garbage terminator completely yet, they must send at least one byte in response without waiting for more bytes. -* After either party has sent their garbage terminator, they must also send the garbage authentication packet without waiting for more bytes, and transition to the version negotiation phase. +* After either party has sent their garbage terminator, they must transition to the version negotiation phase without waiting for more bytes. Since the protocol as specified here adheres to these conditions, any upgrade which also adheres to these conditions will be backwards-compatible. -Note that the version negotiation phase does not need to wait for the key exchange phase to complete; version packets can be sent immediately after sending the garbage authentication packet. So the first two phases together, jointly called '''the handshake''', comprise just 1.5 roundtrips: +Note that the version negotiation phase does not need to wait for the key exchange phase to complete; version packets can be sent immediately after sending the garbage terminator. So the first two phases together, jointly called '''the handshake''', comprise just 1.5 roundtrips: * the initiator sends public key + garbage -* the responder sends public key + garbage + garbage terminator + garbage authentication packet + version packet -* the initiator sends garbage terminator + garbage authentication packet + version packet +* the responder sends public key + garbage + garbage terminator + decoy packets (optional) + version packet +* the initiator sends garbage terminator + decoy packets (optional) + version packet '''Packet encryption overview''' @@ -184,24 +185,22 @@ As explained before, these messages are sent to set up the connection: | | | x, ellswift_X = ellswift_create() | | | - | --- ellswift_X + initiator_garbage (initiator_garbage_len bytes; max 4095) ---> | + | ---- ellswift_X + initiator_garbage (initiator_garbage_len bytes; max 4095) ---> | | | | y, ellswift_Y = ellswift_create() | | ecdh_secret = v2_ecdh( | | y, ellswift_X, ellswift_Y, initiating=False) | | v2_initialize(initiator, ecdh_secret, initiating=False) | | | - | <-- ellswift_Y + responder_garbage (responder_garbage_len bytes; max 4095) + | - | responder_garbage_terminator (16 bytes) + | - | v2_enc_packet(initiator, b'', aad=responder_garbage) + | - | v2_enc_packet(initiator, RESPONDER_TRANSPORT_VERSION) --- | + | <--- ellswift_Y + responder_garbage (responder_garbage_len bytes; max 4095) + | + | responder_garbage_terminator (16 bytes) + | + | v2_enc_packet(initiator, RESPONDER_TRANSPORT_VERSION, aad=responder_garbage) ---- | | | | ecdh_secret = v2_ecdh(x, ellswift_Y, ellswift_X, initiating=True) | | v2_initialize(responder, ecdh_secret, initiating=True) | | | - | --- initiator_garbage_terminator (16 bytes) + | - | v2_enc_packet(responder, b'', aad=initiator_garbage) + | - | v2_enc_packet(responder, INITIATOR_TRANSPORT_VERSION) ---> | + | ---- initiator_garbage_terminator (16 bytes) + | + | v2_enc_packet(responder, INITIATOR_TRANSPORT_VERSION, aad=initiator_garbage) ---> | | | ----------------------------------------------------------------------------------------------------
@@ -358,10 +357,10 @@ def respond_v2_handshake(peer, garbage_len): use_v1_protocol() -Upon receiving the encoded responder public key, the initiator derives the shared ECDH secret and instantiates the encrypted transport. It then sends the derived 16-byte initiator_garbage_terminator followed by an authenticated, encrypted packet with empty contents'''Does the content of the garbage authentication packet need to be empty?''' The receiver ignores the content of the garbage authentication packet, so its content can be anything, and it can in principle be used as a shaping mechanism too. There is however no need for that, as immediately afterward the initiator can start using decoy packets as (a much more flexible) shaping mechanism instead. to authenticate the garbage, and its own version packet. It then receives the responder's garbage and garbage authentication packet (delimited by the garbage terminator), and checks if the garbage is authenticated correctly. The responder performs very similar steps but includes the earlier received prefix bytes in the public key. As mentioned before, the encrypted packets for the '''version negotiation phase''' can be piggybacked with the garbage authentication packet to minimize roundtrips. +Upon receiving the encoded responder public key, the initiator derives the shared ECDH secret and instantiates the encrypted transport. It then sends the derived 16-byte initiator_garbage_terminator, optionally followed by an arbitrary number of decoy packets. Afterwards, it receives the responder's garbage (delimited by the garbage terminator). The responder performs very similar steps but includes the earlier received prefix bytes in the public key. Both the initiator and the responder set the AAD of the first encrypted packet they send after the garbage terminator (i.e., either an optional decoy packet or the version packet) to the garbage they have just sent, not including the garbage terminator.
Code generating these test vectors can be found here: https://github.com/chris-belcher/timelocked-addresses-fidelity-bond-bip-testvectors From c88c3970ed8194a166f783aa748adeb581f79321 Mon Sep 17 00:00:00 2001 From: Ava Chow Date: Tue, 9 Jul 2024 15:15:13 -0400 Subject: [PATCH 311/454] 389: Explicitly disallow duplicate multipath --- bip-0389.mediawiki | 1 + 1 file changed, 1 insertion(+) diff --git a/bip-0389.mediawiki b/bip-0389.mediawiki index 72121b7456..6c88a89aff 100644 --- a/bip-0389.mediawiki +++ b/bip-0389.mediawiki @@ -48,6 +48,7 @@ This is modified to state: When a / is encountered, parsers should account for a presence of multiple descriptors where the first descriptor uses the first NUM, and a second descriptor uses the second NUM, and so on, until each NUM is accounted for in the production of public keys, scripts, and addresses, as well as descriptor import and export operations. Descriptors that contain multiple Key Expressions that each have a / must have tuples of exactly the same length so that they are derived in lockstep in the same way that /* paths in multiple Key expressions are handled. +Duplicate NUMs within a tuple are not allowed. The common use case for this is to represent descriptors for producing receiving and change addresses. When interpreting for this use case, wallets should use the first descriptor for producing receiving addresses, and the second descriptor for producing change addresses. From 3fd971455a3fc3a49ca47ec7fdec58c358da33dd Mon Sep 17 00:00:00 2001 From: Salvatore Ingala <6681844+bigspider@users.noreply.github.com> Date: Wed, 10 Jul 2024 17:58:48 +0200 Subject: [PATCH 312/454] Add paragraph on key reuse --- bip-0388.mediawiki | 16 +++++++++++++--- 1 file changed, 13 insertions(+), 3 deletions(-) diff --git a/bip-0388.mediawiki b/bip-0388.mediawiki index dc1b508072..1fd6994856 100644 --- a/bip-0388.mediawiki +++ b/bip-0388.mediawiki @@ -42,7 +42,7 @@ A more native, compact representation of the wallet receive and change addresses We remark that wallet policies are not related to the ''policy'' language, a higher level language that can be compiled to miniscript. -=== Security and UX concerns for hardware signing devices === +=== Security, privacy and UX concerns for hardware signing devices === The usage of complex scripts presents challenges in terms of both security and user experience for a hardware signing device. @@ -57,6 +57,18 @@ The hardware signing device must guarantee that the user knows precisely what "p This makes it impossible for an attacker to surreptitiously modify the policy, therefore stealing or burning the user's funds. +==== Avoiding key reuse ==== + +Reusing public keys within a Script is a source of malleability when using miniscript policies, which has potential security implications. + +Reusing keys across different UTXOs harms user privacy by allowing external parties to link these UTXOs to the same entity once they are spent. + +By constraining the derivation path patterns to have a uniform structure, wallet policies prevent key reuse among the same or different UTXOs of the same account. + +Using distinct public keys obtained from hardened derivation paths guarantees that no key reuse can happen also across accounts, and is strongly recommended. However, wallet policies do not mandate hardened derivation paths for the public keys, in order to maintain compatibility with existing deployments that do not adhere to this recommendation. + +It is out of scope for this document to guarantee that users do not reuse extended public keys among different wallet accounts. This responsibility is left to the users and their software wallet. + ==== UX issues ==== Miniscript (and taproot trees) allow substantially more complex spending policies. It is a challenge to ensure that the user can practically verify such spending policies per the screen. @@ -189,8 +201,6 @@ Implementations can add additional metadata that is stored together with the wal Any implementation in a software wallet that allows wallet policies not matching any of the specifications in [[bip-0044.mediawiki|BIP-44]], [[bip-0049.mediawiki|BIP-49]], [[bip-0084.mediawiki|BIP-84]], [[bip-0086.mediawiki|BIP-86]] (especially if involving external cosigners) should put great care into a process for backing up the wallet policy that represents the account. In fact, unlike standard single-signature scenarios, the seed alone is no longer enough to discover wallet policies with existing funds, and the loss of the backup is likely to lead to permanent loss of funds. Unlike the seed, leaking such backups only affects the privacy of the user, but it does not allow the attacker to steal funds. -Avoiding key reuse among different wallet accounts is also extremely important, but out of scope for this document. - === Optional derivation paths === In order to allow supporting legacy derivation schemes (for example, using simply /* instead of the more common //* scheme most software wallets use today), or other schemes that are not covered in this document, implementations might choose to permit additional derivation patterns for the key placeholder (KP) expressions. From f3bd1eba67e5e60d40b54c2d949ff1984da56363 Mon Sep 17 00:00:00 2001 From: Pieter Wuille Date: Wed, 10 Jul 2024 14:55:20 -0400 Subject: [PATCH 313/454] Mark BIP324 as final --- README.mediawiki | 4 ++-- bip-0324.mediawiki | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/README.mediawiki b/README.mediawiki index fbddd61b58..194f0bc9ff 100644 --- a/README.mediawiki +++ b/README.mediawiki @@ -987,13 +987,13 @@ Those proposing changes should consider that ultimately consent may rest with th | Karl-Johan Alm | Standard | Draft -|- +|- style="background-color: #cfffcf" | [[bip-0324.mediawiki|324]] | Peer Services | Version 2 P2P Encrypted Transport Protocol | Dhruv Mehta, Tim Ruffing, Jonas Schnelli, Pieter Wuille | Standard -| Draft +| Final |- style="background-color: #ffffcf" | [[bip-0325.mediawiki|325]] | Applications diff --git a/bip-0324.mediawiki b/bip-0324.mediawiki index 8050b15d25..2119a851b6 100644 --- a/bip-0324.mediawiki +++ b/bip-0324.mediawiki @@ -7,7 +7,7 @@ Jonas Schnelli Pieter Wuille Comments-URI: https://github.com/bitcoin/bips/wiki/Comments:BIP-0324 - Status: Draft + Status: Final Type: Standards Track Created: 2019-03-08 License: BSD-3-Clause From 729c44c4eaca2de76e83430609d1f271add0533a Mon Sep 17 00:00:00 2001 From: Suhas Daftuar Date: Wed, 10 Jul 2024 15:05:06 -0400 Subject: [PATCH 314/454] Move BIP 130 to Final --- README.mediawiki | 4 ++-- bip-0130.mediawiki | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/README.mediawiki b/README.mediawiki index fbddd61b58..7650a2fd35 100644 --- a/README.mediawiki +++ b/README.mediawiki @@ -693,13 +693,13 @@ Those proposing changes should consider that ultimately consent may rest with th | Hugo Nguyen, Peter Gray, Marko Bencun, Aaron Chen, Rodolfo Novak | Standard | Proposed -|- style="background-color: #ffffcf" +|- style="background-color: #cfffcf" | [[bip-0130.mediawiki|130]] | Peer Services | sendheaders message | Suhas Daftuar | Standard -| Proposed +| Final |- style="background-color: #ffcfcf" | [[bip-0131.mediawiki|131]] | Consensus (hard fork) diff --git a/bip-0130.mediawiki b/bip-0130.mediawiki index 8d96c0c8a3..d88329fd7b 100644 --- a/bip-0130.mediawiki +++ b/bip-0130.mediawiki @@ -5,7 +5,7 @@ Author: Suhas Daftuar Comments-Summary: No comments yet. Comments-URI: https://github.com/bitcoin/bips/wiki/Comments:BIP-0130 - Status: Proposed + Status: Final Type: Standards Track Created: 2015-05-08 License: PD From 56f7e7099167173bf36073790b7aeeb1164f7ae5 Mon Sep 17 00:00:00 2001 From: Suhas Daftuar Date: Wed, 10 Jul 2024 15:36:54 -0400 Subject: [PATCH 315/454] Move BIP 338 to Withdrawn The PR implementing this BIP was never merged into Bitcoin Core, in favor of an alternative approach. --- README.mediawiki | 4 ++-- bip-0338.mediawiki | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/README.mediawiki b/README.mediawiki index fbddd61b58..26c01f84f5 100644 --- a/README.mediawiki +++ b/README.mediawiki @@ -1050,13 +1050,13 @@ Those proposing changes should consider that ultimately consent may rest with th | Tom Briar | Standard | Draft -|- +|- style="background-color: #ffcfcf" | [[bip-0338.mediawiki|338]] | Peer Services | Disable transaction relay message | Suhas Daftuar | Standard -| Draft +| Withdrawn |- | [[bip-0339.mediawiki|339]] | Peer Services diff --git a/bip-0338.mediawiki b/bip-0338.mediawiki index 65ab616ec5..908aef63de 100644 --- a/bip-0338.mediawiki +++ b/bip-0338.mediawiki @@ -5,7 +5,7 @@ Author: Suhas Daftuar Comments-Summary: No comments yet. Comments-URI: https://github.com/bitcoin/bips/wiki/Comments:BIP-0338 - Status: Draft + Status: Withdrawn Type: Standards Track Created: 2020-09-03 License: BSD-2-Clause From 79e2d28efbc47212604cd41eb8b8466dc0e9a30e Mon Sep 17 00:00:00 2001 From: Suhas Daftuar Date: Wed, 10 Jul 2024 14:54:52 -0400 Subject: [PATCH 316/454] Move BIP 339 to Final --- README.mediawiki | 4 ++-- bip-0339.mediawiki | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/README.mediawiki b/README.mediawiki index 95651ed54c..88458ec323 100644 --- a/README.mediawiki +++ b/README.mediawiki @@ -1057,13 +1057,13 @@ Those proposing changes should consider that ultimately consent may rest with th | Suhas Daftuar | Standard | Withdrawn -|- +|- style="background-color: #cfffcf" | [[bip-0339.mediawiki|339]] | Peer Services | WTXID-based transaction relay | Suhas Daftuar | Standard -| Draft +| Final |- style="background-color: #cfffcf" | [[bip-0340.mediawiki|340]] | diff --git a/bip-0339.mediawiki b/bip-0339.mediawiki index 806ba1cf7c..7fb6bc4eed 100644 --- a/bip-0339.mediawiki +++ b/bip-0339.mediawiki @@ -5,7 +5,7 @@ Author: Suhas Daftuar Comments-Summary: No comments yet. Comments-URI: https://github.com/bitcoin/bips/wiki/Comments:BIP-0339 - Status: Draft + Status: Final Type: Standards Track Created: 2020-02-03 License: BSD-2-Clause From 6b4a03bb5deb624a1bb3d0c2fa0b69434df65f34 Mon Sep 17 00:00:00 2001 From: Ava Chow Date: Wed, 10 Jul 2024 18:59:57 -0400 Subject: [PATCH 317/454] 371: Mark as final --- README.mediawiki | 4 ++-- bip-0371.mediawiki | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/README.mediawiki b/README.mediawiki index 88458ec323..cffa3691ef 100644 --- a/README.mediawiki +++ b/README.mediawiki @@ -1141,13 +1141,13 @@ Those proposing changes should consider that ultimately consent may rest with th | Ava Chow | Standard | Draft -|- +|- style="background-color: #cfffcf" | [[bip-0371.mediawiki|371]] | Applications | Taproot Fields for PSBT | Ava Chow | Standard -| Draft +| Final |- | [[bip-0372.mediawiki|372]] | Applications diff --git a/bip-0371.mediawiki b/bip-0371.mediawiki index 45b69f8a66..92275698a4 100644 --- a/bip-0371.mediawiki +++ b/bip-0371.mediawiki @@ -5,7 +5,7 @@ Author: Ava Chow Comments-Summary: No comments yet. Comments-URI: https://github.com/bitcoin/bips/wiki/Comments:BIP-0371 - Status: Draft + Status: Final Type: Standards Track Created: 2021-06-21 License: BSD-2-Clause From 516fae672639d998f00025809c57473d704a8f61 Mon Sep 17 00:00:00 2001 From: Ava Chow Date: Wed, 10 Jul 2024 18:54:37 -0400 Subject: [PATCH 318/454] 86: Mark as final --- README.mediawiki | 4 ++-- bip-0086.mediawiki | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/README.mediawiki b/README.mediawiki index 88458ec323..3eef50955e 100644 --- a/README.mediawiki +++ b/README.mediawiki @@ -448,13 +448,13 @@ Those proposing changes should consider that ultimately consent may rest with th | Ethan Kosakovsky | Informational | Draft -|- +|- style="background-color: #cfffcf" | [[bip-0086.mediawiki|86]] | Applications | Key Derivation for Single Key P2TR Outputs | Ava Chow | Standard -| Draft +| Final |- style="background-color: #ffffcf" | [[bip-0087.mediawiki|87]] | Applications diff --git a/bip-0086.mediawiki b/bip-0086.mediawiki index 529f0946f2..7bcaf14666 100644 --- a/bip-0086.mediawiki +++ b/bip-0086.mediawiki @@ -5,7 +5,7 @@ Author: Ava Chow Comments-Summary: No comments yet. Comments-URI: https://github.com/bitcoin/bips/wiki/Comments:BIP-0086 - Status: Draft + Status: Final Type: Standards Track Created: 2021-06-22 License: BSD-2-Clause From d71428ade56ad9a90e18d643eefefefb6088fbd7 Mon Sep 17 00:00:00 2001 From: Ava Chow Date: Wed, 10 Jul 2024 19:02:19 -0400 Subject: [PATCH 319/454] 380-387: Mark basic descriptor BIPs as final --- README.mediawiki | 32 ++++++++++++++++---------------- bip-0380.mediawiki | 2 +- bip-0381.mediawiki | 2 +- bip-0382.mediawiki | 2 +- bip-0383.mediawiki | 2 +- bip-0384.mediawiki | 2 +- bip-0385.mediawiki | 2 +- bip-0386.mediawiki | 2 +- bip-0387.mediawiki | 2 +- 9 files changed, 24 insertions(+), 24 deletions(-) diff --git a/README.mediawiki b/README.mediawiki index 88458ec323..0160742510 100644 --- a/README.mediawiki +++ b/README.mediawiki @@ -1169,62 +1169,62 @@ Those proposing changes should consider that ultimately consent may rest with th | Pieter Wuille, Andrew Poelstra, Sanket Kanjalkar, Antoine Poinsot, Ava Chow | Informational | Draft -|- +|- style="background-color: #cfffcf" | [[bip-0380.mediawiki|380]] | Applications | Output Script Descriptors General Operation | Pieter Wuille, Ava Chow | Informational -| Draft -|- +| Final +|- style="background-color: #cfffcf" | [[bip-0381.mediawiki|381]] | Applications | Non-Segwit Output Script Descriptors | Pieter Wuille, Ava Chow | Informational -| Draft -|- +| Final +|- style="background-color: #cfffcf" | [[bip-0382.mediawiki|382]] | Applications | Segwit Output Script Descriptors | Pieter Wuille, Ava Chow | Informational -| Draft -|- +| Final +|- style="background-color: #cfffcf" | [[bip-0383.mediawiki|383]] | Applications | Multisig Output Script Descriptors | Pieter Wuille, Ava Chow | Informational -| Draft -|- +| Final +|- style="background-color: #cfffcf" | [[bip-0384.mediawiki|384]] | Applications | combo() Output Script Descriptors | Pieter Wuille, Ava Chow | Informational -| Draft -|- +| Final +|- style="background-color: #cfffcf" | [[bip-0385.mediawiki|385]] | Applications | raw() and addr() Output Script Descriptors | Pieter Wuille, Ava Chow | Informational -| Draft -|- +| Final +|- style="background-color: #cfffcf" | [[bip-0386.mediawiki|386]] | Applications | tr() Output Script Descriptors | Pieter Wuille, Ava Chow | Informational -| Draft -|- +| Final +|- style="background-color: #cfffcf" | [[bip-0387.mediawiki|387]] | Applications | Tapscript Multisig Output Script Descriptors | Pieter Wuille, Ava Chow | Informational -| Draft +| Final |- style="background-color: #ffffcf" | [[bip-0388.mediawiki|388]] | Applications diff --git a/bip-0380.mediawiki b/bip-0380.mediawiki index 823a92cf3d..17e48e3249 100644 --- a/bip-0380.mediawiki +++ b/bip-0380.mediawiki @@ -6,7 +6,7 @@ Ava Chow Comments-Summary: No comments yet. Comments-URI: https://github.com/bitcoin/bips/wiki/Comments:BIP-0380 - Status: Draft + Status: Final Type: Informational Created: 2021-06-27 License: BSD-2-Clause diff --git a/bip-0381.mediawiki b/bip-0381.mediawiki index bfda2c8ecc..8d12c7a4d8 100644 --- a/bip-0381.mediawiki +++ b/bip-0381.mediawiki @@ -6,7 +6,7 @@ Ava Chow Comments-Summary: No comments yet. Comments-URI: https://github.com/bitcoin/bips/wiki/Comments:BIP-0381 - Status: Draft + Status: Final Type: Informational Created: 2021-06-27 License: BSD-2-Clause diff --git a/bip-0382.mediawiki b/bip-0382.mediawiki index bb1951d63e..261b7e31b4 100644 --- a/bip-0382.mediawiki +++ b/bip-0382.mediawiki @@ -6,7 +6,7 @@ Ava Chow Comments-Summary: No comments yet. Comments-URI: https://github.com/bitcoin/bips/wiki/Comments:BIP-0382 - Status: Draft + Status: Final Type: Informational Created: 2021-06-27 License: BSD-2-Clause diff --git a/bip-0383.mediawiki b/bip-0383.mediawiki index 66e2f16090..522eb0cc72 100644 --- a/bip-0383.mediawiki +++ b/bip-0383.mediawiki @@ -6,7 +6,7 @@ Ava Chow Comments-Summary: No comments yet. Comments-URI: https://github.com/bitcoin/bips/wiki/Comments:BIP-0383 - Status: Draft + Status: Final Type: Informational Created: 2021-06-27 License: BSD-2-Clause diff --git a/bip-0384.mediawiki b/bip-0384.mediawiki index ba12b55d7b..585af5e71b 100644 --- a/bip-0384.mediawiki +++ b/bip-0384.mediawiki @@ -6,7 +6,7 @@ Ava Chow Comments-Summary: No comments yet. Comments-URI: https://github.com/bitcoin/bips/wiki/Comments:BIP-0384 - Status: Draft + Status: Final Type: Informational Created: 2021-06-27 License: BSD-2-Clause diff --git a/bip-0385.mediawiki b/bip-0385.mediawiki index 3e922b3bd1..1686ef7da5 100644 --- a/bip-0385.mediawiki +++ b/bip-0385.mediawiki @@ -6,7 +6,7 @@ Ava Chow Comments-Summary: No comments yet. Comments-URI: https://github.com/bitcoin/bips/wiki/Comments:BIP-0385 - Status: Draft + Status: Final Type: Informational Created: 2021-06-27 License: BSD-2-Clause diff --git a/bip-0386.mediawiki b/bip-0386.mediawiki index 759887d41d..55f0d156d9 100644 --- a/bip-0386.mediawiki +++ b/bip-0386.mediawiki @@ -6,7 +6,7 @@ Ava Chow Comments-Summary: No comments yet. Comments-URI: https://github.com/bitcoin/bips/wiki/Comments:BIP-0386 - Status: Draft + Status: Final Type: Informational Created: 2021-06-27 License: BSD-2-Clause diff --git a/bip-0387.mediawiki b/bip-0387.mediawiki index 5c039b8fe9..0f8c88d3a7 100644 --- a/bip-0387.mediawiki +++ b/bip-0387.mediawiki @@ -6,7 +6,7 @@ Ava Chow Comments-Summary: No comments yet. Comments-URI: https://github.com/bitcoin/bips/wiki/Comments:BIP-0387 - Status: Draft + Status: Final Type: Informational Created: 2024-04-17 License: BSD-2-Clause From 8c2f54d33beb3318f42032715bac5df7f0d61149 Mon Sep 17 00:00:00 2001 From: Salvatore Ingala <6681844+bigspider@users.noreply.github.com> Date: Thu, 11 Jul 2024 10:31:01 +0200 Subject: [PATCH 320/454] Add references to the miniscript BIP-379 --- bip-0388.mediawiki | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/bip-0388.mediawiki b/bip-0388.mediawiki index 1fd6994856..b417ac47c8 100644 --- a/bip-0388.mediawiki +++ b/bip-0388.mediawiki @@ -40,7 +40,7 @@ Moreover, other limitations like the limited size of the screen might affect wha A more native, compact representation of the wallet receive and change addresses might also benefit the UX of software wallets when they use descriptors (possibly with miniscript) for representing complex locking conditions. -We remark that wallet policies are not related to the ''policy'' language, a higher level language that can be compiled to miniscript. +We remark that wallet policies are not related to the ''policy'' language, a higher level language that can be compiled to [[bip-0379.md|miniscript]]. === Security, privacy and UX concerns for hardware signing devices === @@ -137,6 +137,8 @@ A ''wallet descriptor template'' is a SCRIPT expression. * tr(KP) or tr(KP,TREE) (top level only): P2TR output with the specified key as internal key, and optionally a tree of script paths. * any valid miniscript template (inside wsh or tr only). +See [[bip-0379.md|BIP-379]] for a precise specification of all the valid miniscript SCRIPT expressions. + TREE expressions: * any SCRIPT expression * An open brace {, a TREE expression, a comma ,, a TREE expression, and a closing brace } From 0adf7c36e1796653d2bdf778ff6f241455fbf85d Mon Sep 17 00:00:00 2001 From: Salvatore Ingala <6681844+bigspider@users.noreply.github.com> Date: Thu, 11 Jul 2024 10:33:13 +0200 Subject: [PATCH 321/454] Nit: it's not 'two' descriptors if one uses the multipath expressions per BIP-389 --- bip-0388.mediawiki | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/bip-0388.mediawiki b/bip-0388.mediawiki index b417ac47c8..225ce7ad31 100644 --- a/bip-0388.mediawiki +++ b/bip-0388.mediawiki @@ -14,7 +14,7 @@ == Abstract == -Wallet policies build on top of output script descriptors to represent the types of descriptors that are typically used to represent "accounts" in a software wallet, or a hardware signing device, in a compact, reviewable way. A wallet policy always represents exactly two descriptors, which produce the receive and change addresses that are logically part of the same account. +Wallet policies build on top of output script descriptors to represent the types of descriptors that are typically used to represent "accounts" in a software wallet, or a hardware signing device, in a compact, reviewable way. A wallet policy always represents descriptors which produce all the receive and change addresses that are logically part of the same account. We simplify the language to suit devices with limited memory, where even keeping the entire descriptor in memory could be a major hurdle, by reducing the generality of descriptors to just the essential features and by separating the extended pubkeys and other key information from the descriptor. From e7286a53566c83cf5d796fbc2285732338a500d9 Mon Sep 17 00:00:00 2001 From: Ava Chow Date: Wed, 10 Jul 2024 20:37:40 -0400 Subject: [PATCH 322/454] 370: Set reference implementation to Bitcoin Core PR. --- bip-0370.mediawiki | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/bip-0370.mediawiki b/bip-0370.mediawiki index 98f1800256..9dc09158aa 100644 --- a/bip-0370.mediawiki +++ b/bip-0370.mediawiki @@ -497,4 +497,4 @@ The timelock for the following PSBTs cannot be computed: ==Reference implementation== -The reference implementation of the PSBT format is available at https://github.com/achow101/bitcoin/tree/psbt2. +The reference implementation of the PSBT format is available in [https://github.com/bitcoin/bitcoin/pull/21283 Bitcoin Core PR 21283]. From 968c4ee20064dcf4223bbe183b81f685bfd79941 Mon Sep 17 00:00:00 2001 From: Ava Chow Date: Wed, 10 Jul 2024 18:56:44 -0400 Subject: [PATCH 323/454] 370: Mark as final --- README.mediawiki | 4 ++-- bip-0370.mediawiki | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/README.mediawiki b/README.mediawiki index 089e418387..1c9a2348cb 100644 --- a/README.mediawiki +++ b/README.mediawiki @@ -1134,13 +1134,13 @@ Those proposing changes should consider that ultimately consent may rest with th | Matt Corallo, Bastien Teinturier | Standard | Draft -|- +|- style="background-color: #cfffcf" | [[bip-0370.mediawiki|370]] | Applications | PSBT Version 2 | Ava Chow | Standard -| Draft +| Final |- style="background-color: #cfffcf" | [[bip-0371.mediawiki|371]] | Applications diff --git a/bip-0370.mediawiki b/bip-0370.mediawiki index 9dc09158aa..885dfc8cf3 100644 --- a/bip-0370.mediawiki +++ b/bip-0370.mediawiki @@ -5,7 +5,7 @@ Author: Ava Chow Comments-Summary: No comments yet. Comments-URI: https://github.com/bitcoin/bips/wiki/Comments:BIP-0370 - Status: Draft + Status: Final Type: Standards Track Created: 2021-01-14 License: BSD-2-Clause From 7a8bc14b80de79a6287a790337c5156c0891567c Mon Sep 17 00:00:00 2001 From: josibake Date: Tue, 9 Jul 2024 17:06:31 +0200 Subject: [PATCH 324/454] bip352: update appendix Numbers from the appendix were slightly innaccurate and out of date. Update to mention non-dust UTXOs and update the numbers to reflect current usage. Considering the appendix is purely informational and the corrections here are minor, Ive left of adding a changelong entry. --- bip-0352.mediawiki | 4 ++-- bip-0352/scan_data_downloader_per_month.png | Bin 54276 -> 169753 bytes 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/bip-0352.mediawiki b/bip-0352.mediawiki index 483bed3b4b..634e179a72 100644 --- a/bip-0352.mediawiki +++ b/bip-0352.mediawiki @@ -445,11 +445,11 @@ This distinction makes the problem for light clients more clear: light clients n Recall that a silent payment eligible transaction follows [[#scanning-silent-payment-eligible-transactions|certain conditions]] and should have at least one unspent taproot output. Full nodes (or any index server backed by a full node, such as electrum server) can build an index which collects all of the eligible public keys for a silent payments eligible transaction, sums them up, multiplies the sum by the ''input_hash'', and serves them to clients. This would be 33 bytes per silent payment eligible transaction. -For a typical bitcoin block of ~3500 txs, lets assume every transaction is a silent payments eligible transaction. This means a client would need to request ''33 bytes * 3500'' of data per block (roughly 100 kB per block). If a client were to request data for every block, this would amount to ~450 MB per month, assuming 100% taproot usage and all outputs remain unspent for > 1 month. As of today, these numbers are closer to 2–10 kB per block (10–50 MB per month)''' Data for Appendix A ''' These numbers are based on data from January 2023 until June 2023 (the last 6 months of data at the time of writing). See [https://github.com/josibake/bitcoin-data-analysis/blob/main/notebooks/silent-payments-light-client-data.ipynb Silent payments light client data] for the full analysis.. +For a typical bitcoin block of ~3500 txs, lets assume every transaction is a silent payments eligible transaction. This means a client would need to request ''33 bytes * 3500'' of data per block (roughly 100 kB per block). If a client were to request data for every block, this would amount to ~450 MB per month, assuming 100% taproot usage and all non-dust outputs remain unspent for > 1 month. As of today, these numbers are closer to 7–12 kB per block (30–50 MB per month)''' Data for Appendix A ''' These numbers are based on data from January 2023 until July 2024. See [https://github.com/josibake/bitcoin-data-analysis/blob/main/notebooks/silent-payments-light-client-data.ipynb Silent payments light client data] for the full analysis.. === Transaction cut-through === -It is unlikely a light client would need to scan every block and as such can take advantage of transaction cut-through, depending on how often they choose to scan for new blocks. Empirically, ~75% of transactions with at least one unspent taproot output will have spent all taproot UTXOs in 326 blocks or less. This means a client which only scans once every 3 days could ''significantly'' cut down on the number of blocks and the number of transactions per block that they need to request by only asking for data on transactions that were created since their last scan and that still have at least one unspent taproot output as of the current block height. Assuming 100% taproot usage, a client that scans once a month would likely only need around 50 MB worth of data. Based on current taproot adoption, a light client scanning once every 3 days would use roughly 15 MB per month and a client scanning once per month would use less than 5 MB per month. +It is unlikely a light client would need to scan every block and as such can take advantage of transaction cut-through, depending on how often they choose to scan for new blocks. Empirically, ~75% of transactions with at least one non-dust unspent taproot output will have spent all non-dust taproot UTXOs in 150 blocks or less. This means a client that only scans once per day could ''significantly'' cut down on the number of blocks and the number of transactions per block that they need to request by only asking for data on transactions that were created since their last scan and that still have at least one non-dust unspent taproot output as of the current block height. Based on taproot adoption as of July 2024, a light client scanning once every 3 days would use roughly 30 MB per month. [[File:bip-0352/scan_data_downloader_per_month.png]] diff --git a/bip-0352/scan_data_downloader_per_month.png b/bip-0352/scan_data_downloader_per_month.png index ffcd0ddddb8c685b39055fd19112c81c8186109b..a672a91add714f825d4b2fd8e0f9cbd3cfcfe824 100644 GIT binary patch literal 169753 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%0DHMfFLJ}U21V}7Qx5mmR%4N5{b3EYmm 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 literal 54276 zcma&O1yq%5^f!nFA_@iqA|aBZlv0w4goK22cSv`K3QB{3bPCel-6bs`-5}i@I=}ti zd*?qh>-%P{aV?j@Ip?kC+51=fcuR^4-MT?|0}T!BmhfBt_h@LBCDG6>wOvPt{}Iu~ zkcK~AS_>#xOPlFg+i6Vui-3wjp%7tbCUSX-N0aWF8L z{Lc&M%`Ej9x}KKz!G~a)zg4tCL&MQTeqT!CP5pp|)^8!q|60aAW^KYwCDi7mZoB8D zXZ33x+Q&2rkLk_P3}@SA4NE${hRPW_@$MN7J3A^F>gtV5Ds9LvOgfo;e^S7vKT*pY zK*as|#*LUOYMVou@^MaT2Qz5+QzsR^IezHHZ;O`g#4{{`0ZuNfBs7} z_!TDd!#}|kl6=?UZ^aat-{BQx{B*+qzh1&mCm<;J+-60_$kRemI#rzV`SZR}O_|lB z#dzu`Puge~#YIGB;UBq$bIBVH=Yq(4$sey_mZ?*19mqiqE9v|12=0GIW_N^=_<76u6sk;l)U2Rm(6myVvfp6$s$CMWmy z^V8{x<6f8#6}Fsrlai96prU&2dTMXGF|ODnZ)Gx8fu}h|I`&!wq4c8Za=+B}3WNB@!^Y>R!XB_v#$gq;_{6br_ z#O0GyRF8$7-QvNNTWe!uqn4_;ctB|4-Nc!*?N(Cj_0juoZWpwx6}Ic`aokP{MFw{c z#;pP!9Q5?4luJ!@r|UjFQ>`c(ox>*KA|NFtMXg@Cg3joCXdd=Vk+0HredU~Q<@JXT zPw46C2eFgtZ#{VK!BBe|?EjFhFH@eu$dlagwO|5&HK)xAuE}UodN9`|W~0HZ_JZ2; zV_zoimfz{p)U&g*WvFgW#Y)?3hclo1Pwkg}c)k@Aqu}6(LXPEfY<&~mz1d=;=EU?X z4rzC9l2AE3<>f!=_o|%^^x$5x_$X%%?7$uDE!3B&uwHKPz`XaXvooteRY{33x8|4@ zo(2^a)mIX3M@EMo9baV|tA);){8o}H8f(M(3(EA-tR@))EUKM@*~;b1DbY*A`Q%s7 zZdmz+RLw~Cq50Z_(kG*T$bRX?WSDVgaU}t z_s73{`BHVX5WQf9L&W}#q2};%Qm=w;Boascxore!Qta`YGq@;Rvb8jUiCVply z8oW(Ps=n?hBqW4>i?HeQHLPc03<`N@I5;?W@7*)9CP7nIS4U$e^l#pQEfk>H_%*V& zR4|aF>+}f4;E;u?%^`K(x`c^|X}vKXiFuFeTTqac?ulxpEtBaudxg!aV5)d*8EmiN z5|ij=*3eRtKoahDX$fut6%``8af?;~?T8op*l=HrCn`dpNT>XU$EBsM?JyrI|J$$_ z7Y}b|t+3}VKE4pVezW>OEwty|J6`qBJ<+FfSsI61Gsvwn9%huwRWrGB0s9u?)y4T) z*HjPwWL)hZCRza@p}G0_<|(%em)=$U5@BTBVPRwIwFVFq@i<3#d3lMNa+-`Xr-;Xj zgwv}cg=2qze{Hnb7glSO+o#T0PJH;aQMt*ZqM|ZfWZU3O6akMjJKPf8xfXw}-QRCyOU4TI zaX4+)G=}puuU@_SEi9}>g7>UxIA2?_%$%&dySu5m+2UZr4mDvn#iZGAwV|N_?K%!l z?jDQk((fN{{2sDl!?vS(7v-UrtH1ImeSj+U;;6?hg42#3mi0o-$%gj9#zbcXlRH#E zCfF=!a7!b(omgRwFu7Him`?a8W$UdDX8RFy4p!ZKL{Hy6OY}m&n?L!z#l_iyw2De+ zxVmdwzXWfWS?!r^uaP9~7f({x2&h9$dYuHL#YU}BEJpV5JlI{1nPHVBI*i4;9($LV zj0J!H?hzYH{8T>YZ}E`Y8!6n4DwH_NmelQ(Dc)uOfy>E$GA!`5vC_bk&05k}aea%8 zf`aEr=@O6U=`tyu5Y*6k1h;0|9fxPSGx9~%ZlCA^0ja~^JMiHx$j|NV**n4+YS)HR z`zEWMdY7$>%%;v0$8M7H#K1?!Ln*#<_wMD0yJ_|A7~1-F+oVI+u3cLokbsYe9pjUf zME>UMO(rwcYHsaw-F94b9Fk7B@#$%4({O8%Cx3@rP=)mz_UO$}k!CoJx8ma1Q_iSc z2a`?=ZfAS=;^N|H#>07^Fi4%hEiD;PiN|<}Bx`lYyc~zUb$U1#*woadK!k!?k|dic z$F<#bkEP-Z3mnSX#U+yY!(FJ5vv7OsCnjQvIc;wf5d69)!BxL9kQvEhgm>r89Y3O% zeWx{lc2U>zOvYHl=#*QC?Z!W4WthT~XALbhe18gyjfQB~M~kK5xuuRfu4cExK1t0|EEMcD zEXEt7q^5ofU9CMSkSBxSCc3YUU{detWNdGUdLW?;;%EyoS z9z56a66l0y=Z_qkh{O6<)mr&tob>VDs=jNr^N}U;qNCk@2|BH4<`2ODIMQRd9Cm^? z2hI+ra(6eUrcODisfCt*|8U>={RT(T*_P*U`U>(U2dLYf9Vrs=IZ*c$Us}w1G&3PZ zCKB3|&(Cj%wL;guz14{GwDIe$N*%v} z^wWy{jS1x^w6xC|)Qb#)kjr%jjNy|QQ6q$Li}2^T+r^n|je1CM@OS8wxgz5dJV!eI zT4`1LSb;99*`>5lfdQ9PX{n{aDMN3fL7ujQq6v>WtVj`0Y~p8OvaXxXP?Q#Q)m@L0 zkt6*4`BTQbG^I6dcc+8lDH9VDiz9=_`Zs0!#7RmDiY-(RZ^-xWO|T7*;O7t6Oo?2M zck>BK)bh2i2_^*zk-Fd(kM1O;zfbSH$T>B_Pbe#k7#~-GQuXBN)49X#IlPndvNH2I zf3_%fPIh*rTfTq)p8f$ULpBqw-=q!|s~-Jcm5U=bpsI?CkB@I_YfA%)e>hi9s7n9Q zP4p{9Lpi#2A1__Kb}cg8)6-MFd|uk&9b7?t^A1#sDXr?jKpag?&4oKD>tm%!y#@qu ziX$T<6x7sLQfl*Hn;LExU+NDLz{bX27=rtb7Vg|5pR49Cn3TTb3Qzlt#z)Iyb?)>a zBQ4Df&b-2I69BBwk?klfFepspHbbg-+p-6H$^|-@6BRaqwA|rkD7WqHZP;lg#v@t* zz1`gbV`jAzRk?ymGdYzT6-zd;47|LgXc7`VzNT%u7HMG=ptui{C!HI)(MdH z=y)~v2tc6y$$BZ~ty{=0z)K<|AtBMx(<^W~*dT0n`VmAfG`p~%=jw8{H`HI{V1-&- zsQYvUF7Jg_)AgO5oz6{dKxx&Eds-b~bh4)2leS|f#Xg$QH}KSZA|eQI1(3fl=o0#W zg*xZkqYSG74bFYx&a02G^Tx-==})ZYL;`1KW?nluywugzW#OsG<0=0_O~@}Mb`uaS z0CUT&>DO{u3iWFvg$`@^t%tBGKJ=&D0$9M8Ef;NOq}mCmdAO7mh%{Gdtaz*RSwfiC zucz%`P4@SPyz#_V-68t$;X~Shp)cvjk4J-JN9`RQkxbg?2w(#shFAL7P>EDJ+K5Bl z)RcaHe!j?XAfvqka9gxnx#~((6q{K9JpJbWPw)sATuMzRM69iuq4G9$bogc~m(H%P zcEB2az~gKmii(T>b!lO=RFpgWdsx`l`1tr{1_O3GU(_k!m$4SO?<3__`l0IV0s;bM zm6aiJaoDd64APn%NlD{rF+1Brs9#zy{T9Hox3aS8Vq!L%98Ww$i%Wn^@=&r1z@69pG@tY`E)CMJkK*45R~ zc04sR;#=oYA0WmN<7G2MHL02eNF7C%jSndf;|VA5yIY!@KLQX8&zkSe8;6-M_zJL6 z?@^0q^_~NeMAmOvc{vl{W7uBiKqLUwR9&2($euS;=XsUzRBg9BT;K@oj^&)&*a#3w z&ahAwGRa*w9Qf;L4fpwQZ%AEOSXdK)hV|;;txyqxp&Zqb5|f9nuC4_BErvpZ^hDfQ zG9d@Eme6FHs}Ckc6%+`1crUmmgS~6yCuaLQ_;!MDy_Q&|oHf34}|)4b5z_D)RKyIptlno>Y~} zP}dW8cXuX2{}>LNcCA0@6=NSn!|8Q_jp0pXKc%J3@FP-vW>Fqxw6nck-`18snmR5X z!!EVX63gY#r}dqIlQSBQ`q|yRtAkdE5*BnTu(8f&l!b-GDKxFaqobMGSw5)E^bfV) zUB$pC)NDle@%5z>#H5|tY#%;9S|lw}q663!*=)c+-|rVnI|R+Xzd%8KOH?4j)M4eu4WMm7BcdVrykpx#l$T+wk}(!@q)v zPUPLYY+GyPVb=6dclS&I4iB6U$U69@?O?QiymUn}b3iPfr@H+u-~4%~+lM$eu53Bw zb?r6zBmi${vK+~7(9&c}vNssIfQ#gaU|rVN*H2iXE6*&a@)vxgrS%v{0pnE3Wp>-O z2!U0My3;>1Uxv0|6)I<8^fSD1b8~~`S3Z3EOvRrSvbSkpoV>xUp{)T84_ohma zLfhay-Ewc<87b6Hg3hEK*nV)_F!s~!blbDp6^b9MOBA33Wn<-uA+ulK$bc=n1B;ST zlvhyjQp;s)O&eN0T277cT)l;U1%U+qIZPZJgicOQ(4n11Ow4MI^Z+s{%u%1xe~*vv z2_WV)n5-&4`p^ko%-4j7hzO9rkkoft2`afo*b7Bv)m1uecL82%pN|6Dxd$sbhy^7_Q*+$ndJFp%9V-lPo!y{KGgCnkN)LhP$_)z z8K~IVBY-SlNg?zFvbF{1Y1v9_$7t~T5gd3JSP5)RuDw6f*2{g@BqSu_+|C^kjx9rb zACRwntlhTBP!4gUC(dFksoPKJdi1Ilc@}f9l^vmXaX_nLfUaNw^_|mhLkA?71!dMn zQt6~#MymxeA0Hocb92Unh>9qqD8RwM`DZ}B_zNNk+r@jc{uFf<>KsI z24xLtDs!!YsR%)ts*NAWl$Uq#a2_wS0JVfyEQ0ZqRFYutk2e_Y?d|N&hm5e7=i&2P zT3bDT{-i*}l8f^L-oCy*Y7S06cbjD(Im)%h zFv)UvuMvk=2R1J(<^EjtS|zqC6P0!hM@L71cxwlluCE4P75P)CAMX-IDH@gsMcDOd z9v@V#*RNj#V<+Z1-DqFB7Ku$nhbHwLd0dH>Y@9UkP9-YEY0?ou7p^zdMY2j*)n8iwnv;cH00XC^K zAQxFfLuldMM!D53eh*&QFDHjH65MnK*aL5z%g6!D>jO`58&(mjjXM7J?b~%fg+th3 zy@hHWA%a4p0M!@EEy@+!jj;Mc6;7%kCYhKlC*xYMjGRyNQ zK=*Ug({-?8JK?T-d3(=f=GJJz;qb;@a&rE|{?c6&$`r(fsKg6P#+f>q2 z9?U75RX2l9Aek<+;O+hNpHCDvf{>cM6hJCT~pvWKh(~tJ$E$n?EeX! zA~-nMeybiM(S68$A1C zC>z@?YtIz?O7*iya$;T{ZgtK6iz+P8v=e8J4$BgI|F~VIEZst6Z!$ySyEKUG?WF|! z0+GEF!;q7Mzok(=d7OJiFzJ$ey~aAD$E|(?=ClDqBTwWt0dFtc+{YF8k;fQbP;mFv zD6yBQ)XdtNkEf@EJD1v1c!jGlyrR8b1nP84R~MF$5cMlpCZ81=8JX|WDlvi8)#UW_ zri0jTuah;&247vd@x+JE!h%O!Jg2POL5Y({b8c;&xOdeC7k_bXZH+bwB>CQ7!gr4D zKPU7j@JEk{QOP3qF`$4y83}I@`1eJ~UMC~u6i&$b)@wjZ7~Y^EB^??c+TIfYSJonW zH!YK*REz&zo4&wxvM6lfg#Wp8&DXg@sO41B7mmA(jt2pAU-07!Y~Lc6-xZX)wbBc; z49ExrySWChgG0H!z5QLn(Ws^-9=``x(Z!9KgAHF$huf{2P^iX$1~*Lc){T-OHUdiu z8$qwZiktJ>yJ?OE`aSei5^*1E-O$Jd{eCLGP%kJDFEpDXfk&<%{Vt)zY>E%H;3^jP zj9dZ^O&ESUd&AF=<-BW!w>s!*MjX@w`Lc=%CaZ-~z~#zW9UUFT?`6W_muK|Y{6p@Q zJx5%D`pLHG|dAn4d%R|cVg-P=2VVJLLf^>mvP90noN@_E7F;8|gD z9_+fdkharB-k#?=Z|@2VZ~Hy8V}lx)VHp5T2|)N&KxYIjhBSrxZf&2hxdlZKhzbf; zI8=h#1WK`#?gf*!;MPKPuF^BWma}t#7p<_ z4$XP?6Gn^WbX^VY;!B6;k&Zg1hZ*tWz2U@1*=es%>YP+F_3n(f+m}}*|0YuD*mX@}=g^@J7 zPefzDF5-pHA&C^4n<-TMf zLFdoZYlfXoLc}thB9{PBnuX+v0LC zAzW!o?B%^IW^8O%Ve8LwQGovT-8;?wHHPK>R8r}bDqkg+4Xj+6MJgKCy@4nCi(@Yy zytKS|aki=48GG^&h$SN;XV{F4=pXjDsm&d)dR_u<=?|?n<_p$Eg~8?dwYARa`Ztlh z7ZQI~oIxHnRFi+nVZG4#!S(z|0-Af*Dv8tDozt@`5ie27RyUJ`raH+3{pJdLQldiq zV8wquJ>{x7)M8y96S~5v^UK_{)q3_xP1q*O;zJmPw_r}|!Jw3T1Lq>LXIKWsOWryzJ z;u>#ru&@AzJ>2Q&0g10CbAppE==o+|AGK<+9o3&4G>QEpDCAk%rpvJPB~7+Cg$i%6zEV=_e36~9R*9g zYOAGWri|Z;)$&xbjqu$xbjg>O|G*f%R6L*?Hi!&Jk>!02$KOzO3+0{v}FCDZ0dg%}NemAHVE zm+xvlv7KMG?MWCNT}YvCm$E(OX2;$T&Kwj~A-Ta1fQ3)?*Jr$`mGp@n)%Gi?jWIT*izMaTv^`bSjAH*djTwwEL)Fj-TpMOZd|eAt>fjj z1EOmz^Xuzx!s#atS94$L=W~q9UYl+i}(1hTg?0UG>~SBty`m88+{7&?AP5-Q+|F~R)Xhri@Uw!=~Dk9 zhf?tkfzuCDGpG^X#MP(@FT*z;YTYw{LjF)ki&wTB@ijEF+ zs{8A$)d=nrAzzc+T2}%v`K-{mw(1&-o#v2b7fOdw@V1S%Wkjm+x0<|~gi|sFJX*M9 zcJSXc=2~nzquKDQ)jR=J0jZveb81m!9(JDogb5!GmUJz!@>F&XjyoiiEvNk9sj2wj z=#llOxHNS}#?NeQ)F-@tuKG)Q^*cZCfBNdI)|ZrmZwzKhb5l2FBPOvVI} zk{MBo+S{8CkcSk`N>V8HJ|-q6f^{7Wd`ly_9F_WDN-PT-n`GUN+Z(lR&i))3>S-op*Y!FNqo8QT zlv}w8Wexz{dG)@pj&_WSVi%mWD*{Zx5yPp2i-7Jdba&Cot>mKxa#y7;m1fM ztC;9o+zStv|Ey+~RiKjE56;=^LOoC!Ib{k{)4TdIJ63V z;W{Q}HRz)9^p(}ldVtwYPbpeP!D4hy z$;;a_o+ksbn6u2^4|g| zY}9s7iOh~~F*C}1wxYW}eCkIW1aJ81&W;v0p)y9Wnmh*bdr@f14wu+PLpPLfkd%Jb z^=mRa-z>plGlQH(GMtP>GBM|uzTkDTobH%`R)xHCiq|zcRjzJ!z<5GUexm=wUuLsD z&)x_#VPerCnV`-Z{hLnqUwkLJRO3vzh=W}7HHr0yRikzD|9FlGXNY=BE$6#?HB*16 zZ-%y4BuPB_mwp+K#~X=jFw$CI-%C+V3oLHD^xs=MKwz#Am2@4(EDz#)@{4Ycl z&7wbGft#SLW2J=QsK80|;$Nnr84{3kKM!TVN*lV|#;N=m^E;#HyLU6S7cRbFR=UIf zGY537Vm)>Z>-=xYm|)0v+#c?O@$L#6BYLM(AgPSz8k-%aY!@- z8T|)|xXNlr*8z;bzBqRWs_S`aX_O@l{Lkl3`(l%B7a?D7$iuR@rz?Ydu3$s-@n=pw zGs?Qal3y0ME2DHK!-d6LQBg|Dd0b)PD|BH8o4j5oV! zIa~iM?N4>bjzu!gxFW28HH+7*dXMnSmuq-qK(uQPXQiPw34#sPoF?_g0o5hX;3$^V z`wJY^`aI3EuD02Y2~Gz*Ak3e~#chz)^GF{s24xqoHw3rm_dD7W-N6e-N-))iyT3D(CYfX3)L6K}7xnTzZ=K z!XXSU8y@%psBJ<3qZEn_=LP2M=ltaX0X>vX?SAwu>lP(tGxDgLnyeQF~Zem(Y8EyzNl-5pl_ZEHbFjJ8jE!z6~g|l+d z;jV0?7&sk@&+P2jxRo4d(tdw|9uE-@-bT-<>#q(rssW<*A|$hFe^hy31GQeNJ~P+v zcQAQ!9l*ZOU=PDb>iC#nP_5sJtu==2|6~sjc$!Cm2rRkbcd%y02r&QHsl^?}Xl5Tx83R4@$&} z?_Oo+SQa?5kr&y$221^^3?~Phl}r1TcAE)yn>7o6F#&1D!9^509f+er#N%^F$UR6b z)%-07I%vN?(kd)2u6Ml40O<3Tq$HM#sw&c}j!rh`|IW{=&fLF2=23Q6DfUzCU>ur; zeXblk=jaA|;JVeYl-F90eAUJpt_7sOr^vQQumHsYkd zFdD=ci`=<^?*1tvq8kDeh4|IgG*E3fP7AsHs}gTGa}g~Mu?&ySs6g^?4^k>KO9}b5 z1UB>(6u2Kls6)Cga-2=f%p@d#C-ZJOR>y&B;!8oxz%caqLFKo~N}=MU*X8Bq3(B4( zBym9Yl4#l~LudeqZq#0osk!V?a&cFeEyh{ktwJni!R_M2!^g)G6o>ZRWl~fFmc;gI zuAAyk1=4Y2`z*PAS>vuww|EQ=kB#haN`l*INXcGyjZXP%p5^=$UdP3`)60p9W=%6Q zw-N0uHJ6;cF%8B%$35E7(oOT;b!{z- zsgB*{7Yt6=U{TZ@Ej$Iw2w)VDMNUPr^;7{nU4WBq1&YU>xk5Ci5Sdg={dM7ah zsgh4{QfPp5UIP|{SFZj{P6kDu8LUH)>89X7W3mA+4SwGST7J0cHq}sH9~4Axrge5) z{7hjB9|4_!Ov=k&o}QoNTCWXb3JJ9;)y9K9W0;c1-%&vK1kG=S_-hKfiA~nKyEK|% z;o%(}47_IfSvz}>F$pNOd#2%7ke!$q12X(qP&nQJYn*gkbpa+#?}QB?7#{9Bh-|0^ zkn)OXXxs+xg#;3Z)k{25QtOA)?jOM3j=eZtR0IGb4EwgpJ1|@dAjW%5E7*Q~a6P5KWqFhEygtaiUbFtn+qr>fgmh@W6#Z)&OU*w?i!)AuXjE zZ=T=hxboxDhPAJ;>AJZge=_6+)*l%ws;OZ*x(sNU$BK)Ji=%f%UDGl%i{_^FFbV4M zyUiyPsw&yyt8UD1CTYJi*llf~y7%M9=+?G{KvMd}oo8dD{BjU zPV11^65eN{Dk-sLm*@XiA!Q~29yF)kztnFN>%P5bSz^gAFZkb&B1}BHzr`qeBvpT% z+5Rzzz3B5V=C(ke=}9qSWVHprh8;eX8!t zEj61G(b9T`fwPetcpG*A^X1h8z2G2epUejn~1>VsPq2Jc0)ggdxcURzya@ zd3tIbk|D0#tQo5^h71J1pkUO6(NqmLC~k8X=bIP5Iyx%*Ix17TqS?Yhvin`@b~%uH zpAn)Mc&qpfYITh`f!e>mQRLLtkb(f!bbjVUS5m%(H~B@)arps>>)|&a7sJWl=1RsDd9KTQ;O}WM5@e{Bn$Pg5xgP0KiAB7E zEVCjcdco!Y3${&y)na!zPJ4I2d`CFcWdjrhzn&w`G1zJu6N?}`Q9XNh6C$rbW{x0n zB>e83?qHUpytRwGs1)vRqijo4v^Am}1Mwf=scb>S{JHhgb>N;5!^VL4*dkp?TW9Aq zNELU8#xDb<^tmq@$-Yen;Me=xH#ruL9{Z{Mal9D!WCG;zYg#YHGD z>IRDtztmXtMzb!*X?3iyA0~7|n^~W`X@IG=!3NoZ$lbOZ^jXV^yj9O z_wV1QS4Q)Q#qSIJu%3)2kRUbrjf#_)o5EXssFr1Ocdv`B5JI;FziXwz@+y6%&s1yPW3NaPfmsunvLh=|+(;SoZnOr z3D~WdfDNnY=bu)r9xGRgi}TcDF>rNx-Ejv%!8xQl6aw+d;9$#wmc{p(12;)s$-$`P z&mFpw(whqME(B0q2ZkPd+-_ifHfkPhnf>Xu8=F?rX%?|~Z2I1H#2!M7QTPm9NQ%e~ zlJc6aY?^CY-X|dm0DwqI`31~C(KvF5oFpVXLcA~tJPT`Tl7SVh39AZ;tPN~vGZXf% z?m<8*faoP+bqhEfGjOP8{AuF-5X)c}Qbq|Abt+leaAdRa@*pU}O+`_u-mWvF7j z!SZ}04!tg-W+p8+p{Pl2fc6tDM9|>m5RIpF ztSBVj8b+_`15q-FW#GR{06ibicL=CEP>D(wj-g}&=7EdnY=jJFWMJ=UY}yYjn!Qz1 zn>1i1+}W|D3tI$#y4r4&1aJ{*qms0*#KgnF0U(xSW$iO4QOmta_*nSejT(%SlHYpr zG}%-JSeVfX{cmt`3g7*5``y&(Ufa?w!9>2Qr9XoQK898%ve|djkbpT9O^g0_Yyw(G9oY=OwEDtqg@r_i3&?)Pw` zU)^$S>FQr?Z4DojkL3ew8FyGLrzV!qJ;y*RR{CSz zvlx50mm#yE?}5?ZU%gdZ4TaDl?>rof#iJv_n7aq+@58D+AQ z`V5~kf?;;^hGVtOO4dr_aQ?yeDN17dc=bZx^@iE@>=!fw{~Jq-m%6KSoN;cUCpDi8R6B8jrUiMoXjr_3!qwsU&k4j>9IjnU z{vIlOaWxa#)_wJ!DPO5i^ml3woj8KS<@+8j?roXZEKMX;$jn`(WnsAwrSc69w~X!t zWRsDx2AGX_3b*%TI$p-kRA}z{`uc~F0$qQ1$i@;N;c7B6G6;tZ+4I(^=-WWTNNL^f z2bSARymF4pfQ5;ymX>;)>+!XkvweujCzq)1|HL4=oSPsu}_8A{X9U zpnJWC3-y@yRPro)pd-JqkeuuX+f(`Tckw)DD_bJQ^3tLeUvAIxQ9r*iV)+Q`K4XTR zLda>P{M^+H2)_bHD#h!7F_b!JmR(@l>yeznnNot={Y!o#KQ>S z3~b14L;Rq>*6pIh%o!1CuS~D6tFF4_+K>xPHvI|;EB!E(Ghujc*Aur5LZMlHjePD^ z-ysMO>5rFfFAS+xwkQ!L1@{{0bcDUTNoeho&GQgx=|eF9UY17c! zxVV;}j}@c>p@D_h`W1rlwIpVLx1+n z*wNu(8SC3S4*mA$Y6$d`(`BaZR5US6;btsJmPMqif3afD=vSA>pZej`D>|*;NXQ1U zQz!p}ahZwz509+60A=kPfAI~e4kgcU`*&V!HX~~^Qczs;Wt=HCg^iKsx;df8zfiSI zYhH;PHAH>I{0*NG(K^fEt+Y@7>O@{oOPob-2qbfyR>dq6-!p*s`2F{u#{dSxjCror z{o={aH~P4LsbqGv{Jn)DVrs;^td&(f2M^TpV8TCB`mmMsA`l>!0_RPzMf&he*o76p zd9oXhTEE4Hbf4c{@r= zNtv$S2B7sP#9>uDq5t8Bv4)TU%`Rws?wR4`Tl{kjGJNn{27yIv&tCfxNnyLjx$oPGHZYUP$kU?-3oIpar&ftYbvYFAR zO6X6ouC_)nm71?++bK1Di*f$k!yDfoKs*N77g#O+fO5W0PmA*2jgEEs3b7+PApCxn zl^ASO&dMxfI;dv+{*iob&X+GoASKwFJB0=lEU$@(#QHN}pyI{fg@vsVeRah(NNH_? zZE(r$yqo|BM*{EJp)aIUKJD%@10ymRp#9z!68}@R5?i(#0t@e?^h}=^+3KRf%`ul5 z8eY2h_Oh%QuE1-fKZ@(8*oG%cE(stYUjo5~9sFc@waClRpGzHFOii(&MDf^7Ixv`; zngZwY$5(fb`o}1(v?5J{kev7aI_J(Qib0!k>C)lh+yP=fwggni@2@9~RNAq{yRhDe zBo%DAE3d#ry+<`Jp`gGHp&?qsVjq}L@o6P-ihx5j#{898gwP6@ZT(zlyI7!xAX4!w7ia`bTDTIt+>z3$!E{t?YGvjm z)lTXlYfy9AnZktKKn=B}YY0 zqReksGe~HB8ZgFq=k4o-Gn;QOJZKM5CC#z8dmlhB1B2P~7caa5HWYMSpm#~9y1s^s zL4&Chu{f?zAP)DXOY5U-!MU#58+7Yhd?zY8AIR%EznrQ*-SSZA%5D51cR&s`=Z;i} zF%5aCA@!anh?e8<#snlKeK`NQv?M-m+2N0HY%ph4OvWL0wK!dW1_edmdKC}jRXBY< zgv4&bj2FswX2v9fecJ-H3bx+N-@l#FX6K|Z96$u;W4$?f4}5RDXA!OBfnw;>hucY@ zaK;0qy#zsfXs-4%gy@o35gv^f4m&zNM+o)J@@ zT0jIU8>4=43!LGcr&qL2GX9`7h|SR;|R^%cCrKc6N5y zM8iE8q*X>1x4_!110qpiF~{M!FQ&2F*X&2gf?hnjTPj#;YEgB%vwFHe*28u5mjc3? zWg8Xe5S@~Sr=Z3x4(06zc5J)$=C%qn9CD{pVC8a@Ab3ip%di{LtCjX!D^i(&{FNp{ z%X79Xy0)H4#YaY#-8r_m5-Pc#&4G^}?i-g4xf|HM8P9sUx{B?qLC&I}*wt+C@Lteu zYopFsTU=a}2qdXifV}})-RIBFFnv<5665gp;xvvhRDsR@-*6b12gfJDr zj;&AP)(LI@lJutd>q95?Q+-tND^PRv^!3$s`Iil4CzW7~?h#Xdk3gv}xJ};oS`Efn z`w|aNEJur1Ux7e6R${^wp9#|;*~)Cne_qMTe3uuVhPfz}btWM{f;Pm(c5rZjl`Zt@ z)t>Y{gabGqz6GUZFVh@w^a*vI=gQyR!D~JPtfD$F7XXPYLFDyAVkd@+EALV}LmxVd0m}0mRAq#Vp(7(V{ zOfZoOPJgufJmmx<_BzBZr}0!@mCjP1<&dLww~BSjzHgofQjtOx>spYr{5 zH)E`-3F2&`pgriqonLWkgTRj6?iIR7hCrzZY1-4h!?~W@cl&%0DGQd??AjV1Xk_3E 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 z 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 From ceb4f332a47a80a5012e6e01f33392aff769d444 Mon Sep 17 00:00:00 2001 From: Sjors Provoost Date: Fri, 12 Jul 2024 09:11:17 +0200 Subject: [PATCH 325/454] =?UTF-8?q?bip353:=20improve=20=E2=82=BF-prefix=20?= =?UTF-8?q?instructions?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- bip-0353.mediawiki | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/bip-0353.mediawiki b/bip-0353.mediawiki index 16466724c3..0a7981dce2 100644 --- a/bip-0353.mediawiki +++ b/bip-0353.mediawiki @@ -68,9 +68,11 @@ Payment instructions which do contain on-chain addresses which will be re-used S === Display === -Wallets SHOULD parse recipient information in the form `user`@`domain` or ₿`user`@`domain` and resolve such entry into recipient information using the above record. Similarly, wallets accepting payment information from external devices (e.g. hardware wallets) SHOULD accept RFC 9102-formatted proofs (as a series of unsorted `AuthenticationChain` records) and, if they verify, SHOULD display the recipient in the form ₿`user`@`domain`. For the avoidance of doubt, the ₿ is *not* included in the DNS label which is resolved. +When displaying a verified human-readable address, wallets SHOULD prefix it with ₿, i.e. ₿`user`@`domain`. They SHOULD parse recipient information in both `user`@`domain` and ₿`user`@`domain` forms and resolve such entry into recipient information using the above record. For the avoidance of doubt, the ₿ is *not* included in the DNS label which is resolved. -Wallets providing users the ability to "copy" their address information generally SHOULD copy the underlying URI directly in order to avoid the DNS indirection. However, wallets providing users the ability to copy their human-readable address information MUST include the ₿ prefix (i.e. copy it in the form ₿`user`@`domain`). +Wallets providing the ability for users to "copy" their address information SHOULD copy the underlying URI directly, rather than the human-readable address. This avoids an additional DNS lookup by the application in which it is pasted. Wallets that nevertheless provide users the ability to copy their human-readable address, MUST include the ₿ prefix (i.e. copy it in the form ₿`user`@`domain`). + +Wallets accepting payment information from external devices (e.g. hardware wallets) SHOULD accept RFC 9102-formatted proofs (as a series of unsorted `AuthenticationChain` records) and, if verification succeeds, SHOULD display the recipient in the form ₿`user`@`domain`. == Rationale == From 8ba081f4722a425cf4167ab6698285aa52fc35ef Mon Sep 17 00:00:00 2001 From: Matthew Zipkin Date: Mon, 15 Jul 2024 18:46:02 -0400 Subject: [PATCH 326/454] bip353: concatenate strings in TXT --- bip-0353.mediawiki | 21 ++++++++++++++++++--- 1 file changed, 18 insertions(+), 3 deletions(-) diff --git a/bip-0353.mediawiki b/bip-0353.mediawiki index 0a7981dce2..9deba50b0b 100644 --- a/bip-0353.mediawiki +++ b/bip-0353.mediawiki @@ -50,6 +50,8 @@ Note that because resolvers are not required to support resolving non-ASCII iden Clients resolving Bitcoin payment instructions MUST ignore any TXT records at the same label which do not begin with (ignoring case) "bitcoin:". Resolvers encountering multiple "bitcoin:"-matching TXT records at the same label MUST treat the records as invalid and refuse to use any payment instructions therein. +Clients resolving Bitcoin payment instructions MUST concatenate all strings in the TXT record before processing the complete URI.TXT records are defined as "one or more character-strings" in [[https://www.rfc-editor.org/rfc/rfc1035#section-3.3.14|RFC 1035]], and a "character-string" is a single byte (with a max value of 255) followed by that many characters. + Clients resolving Bitcoin payment instructions MUST fully validate DNSSEC signatures leading to the DNS root (including any relevant CNAME or DNAME records) and MUST NOT accept DNSSEC signatures which use SHA-1 or RSA with keys shorter than 1024 bits. Resolvers MAY accept SHA-1 DS records. Clients resolving Bitcoin payment instructions MUST NOT trust a remote resolver to validate DNSSEC records on their behalf. @@ -114,15 +116,28 @@ This work is intended to extend and subsume the existing "Lightning Address" sch == Examples == -`matt@mattcorallo.com` resolves to -`matt.user._bitcoin-payment.mattcorallo.com. 3600 IN TXT "bitcoin:?lno=lno1qsgqmqvgm96frzdg8m0gc6nzeqffvzsqzrxqy32afmr3jn9ggkwg3egfwch2hy0l6jut6vfd8vpsc3h89l6u3dm4q2d6nuamav3w27xvdmv3lpgklhg7l5teypqz9l53hj7zvuaenh34xqsz2sa967yzqkylfu9xtcd5ymcmfp32h083e805y7jfd236w9afhavqqvl8uyma7x77yun4ehe9pnhu2gekjguexmxpqjcr2j822xr7q34p078gzslf9wpwz5y57alxu99s0z2ql0kfqvwhzycqq45ehh58xnfpuek80hw6spvwrvttjrrq9pphh0dpydh06qqspp5uq4gpyt6n9mwexde44qv7lstzzq60nr40ff38u27un6y53aypmx0p4qruk2tf9mjwqlhxak4znvna5y"` -Note that `lno` indicates a value containing a lightning BOLT12 offer. +matt@mattcorallo.com resolves to + +
matt.user._bitcoin-payment.mattcorallo.com. 1800 IN TXT  "bitcoin:?lno=lno1qsgr30k45jhvkfqxjqheaetac
+u4guyxvqttftvqu0f5sneckep3lkwdut7mmhhpcyjmlmnjn4hze8ed7pq88xqkxt2dcw5mlxhz644fms82f7k4ymfxs2ehhpjtxw
+xly0w5k8xdtlvpqyd8xzdq4tq8lgupnueshgydr330lc3j5kdcqh54gt7jdg9n68j4eqqeu7ts8uh0qxamee6ndj37tc6mzgejth
+vvjqj96p8dz2h" "rsh5z5n27qfk6svjz5pmkh0smq26k0j2j4q36xgq3r5qzet9kuhq4lydpen5mskxgjdvs5faqgv8pmj7cfd7
+ny84djksqpqk9ky6juc7fpezecxvg7sjx05dckyypnv9tmvfp6tkpehmtaqmvuupetxuzqf4t0azddjdcpasgw6hxuz9g"
+
+ +* Note that `lno` indicates a value containing a lightning BOLT12 offer. +* Note that the complete URI is broken into two strings with maximum 255 characters each == Reference Implementations == * A DNSSEC proof generation and validation implementation can be found at https://git.bitcoin.ninja/index.cgi?p=dnssec-prover;a=summary * A lightning-specific name to payment instruction resolver can be found at https://git.bitcoin.ninja/index.cgi?p=lightning-resolver;a=summary * Reference implementations for parsing the URI contents can be found in [[bip-0021.mediawiki|BIP 21]]. + +== Footnotes == + + + == Acknowledgements == Thanks to Rusty Russell for the concrete address rotation suggestion. From 0b3c79c257067dabadb34829fa616534a54f23af Mon Sep 17 00:00:00 2001 From: Salvatore Ingala <6681844+bigspider@users.noreply.github.com> Date: Wed, 17 Jul 2024 10:18:53 +0200 Subject: [PATCH 327/454] Apply suggestions from code review Co-authored-by: Mark "Murch" Erhardt --- bip-0388.mediawiki | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/bip-0388.mediawiki b/bip-0388.mediawiki index 225ce7ad31..fd28f0445d 100644 --- a/bip-0388.mediawiki +++ b/bip-0388.mediawiki @@ -14,7 +14,9 @@ == Abstract == -Wallet policies build on top of output script descriptors to represent the types of descriptors that are typically used to represent "accounts" in a software wallet, or a hardware signing device, in a compact, reviewable way. A wallet policy always represents descriptors which produce all the receive and change addresses that are logically part of the same account. +Software wallets and hardware signing devices sequester wallet uses into logically separate "accounts". +Wallet policies build on top of output script descriptors to represent such accounts in a compact, reviewable way. +An account encompasses a logical group of receive and change addresses, and each wallet policy represents all descriptors necessary to describe an account in its entirety. We simplify the language to suit devices with limited memory, where even keeping the entire descriptor in memory could be a major hurdle, by reducing the generality of descriptors to just the essential features and by separating the extended pubkeys and other key information from the descriptor. @@ -65,7 +67,7 @@ Reusing keys across different UTXOs harms user privacy by allowing external part By constraining the derivation path patterns to have a uniform structure, wallet policies prevent key reuse among the same or different UTXOs of the same account. -Using distinct public keys obtained from hardened derivation paths guarantees that no key reuse can happen also across accounts, and is strongly recommended. However, wallet policies do not mandate hardened derivation paths for the public keys, in order to maintain compatibility with existing deployments that do not adhere to this recommendation. +It is strongly recommended to avoid key reuse across accounts. Distinct public keys per account can be guaranteed per hardened derivation paths. This specification does not mandate hardened derivation to maintain compatibility with existing deployments that do not adhere to this recommendation. It is out of scope for this document to guarantee that users do not reuse extended public keys among different wallet accounts. This responsibility is left to the users and their software wallet. From 29312fbe912a0125ad70a95d61a3734692a25de6 Mon Sep 17 00:00:00 2001 From: Jonas Schnelli Date: Wed, 17 Jul 2024 21:46:35 +0200 Subject: [PATCH 328/454] BIP150: Deferred --- README.mediawiki | 2 +- bip-0150.mediawiki | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/README.mediawiki b/README.mediawiki index a5ad2277cd..b6eaf4b396 100644 --- a/README.mediawiki +++ b/README.mediawiki @@ -832,7 +832,7 @@ Those proposing changes should consider that ultimately consent may rest with th | Peer Authentication | Jonas Schnelli | Standard -| Draft +| Deferred |- style="background-color: #ffcfcf" | [[bip-0151.mediawiki|151]] | Peer Services diff --git a/bip-0150.mediawiki b/bip-0150.mediawiki index 277341db55..bddc2e11b7 100644 --- a/bip-0150.mediawiki +++ b/bip-0150.mediawiki @@ -5,7 +5,7 @@ Author: Jonas Schnelli Comments-Summary: Discouraged for implementation (one person) Comments-URI: https://github.com/bitcoin/bips/wiki/Comments:BIP-0150 - Status: Draft + Status: Deferred Type: Standards Track Created: 2016-03-23 License: PD From dfacb8de6ac5f6636c3d3fd55cf817c0b73cacea Mon Sep 17 00:00:00 2001 From: Jonas Schnelli Date: Wed, 17 Jul 2024 22:00:11 +0200 Subject: [PATCH 329/454] 159: Mark as final --- README.mediawiki | 4 ++-- bip-0159.mediawiki | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/README.mediawiki b/README.mediawiki index a5ad2277cd..1b42ca90b8 100644 --- a/README.mediawiki +++ b/README.mediawiki @@ -882,13 +882,13 @@ Those proposing changes should consider that ultimately consent may rest with th | Olaoluwa Osuntokun, Alex Akselrod | Standard | Draft -|- +|- style="background-color: #cfffcf" | [[bip-0159.mediawiki|159]] | Peer Services | NODE_NETWORK_LIMITED service bit | Jonas Schnelli | Standard -| Draft +| Final |- style="background-color: #ffcfcf" | [[bip-0171.mediawiki|171]] | Applications diff --git a/bip-0159.mediawiki b/bip-0159.mediawiki index 022669254b..365aee163b 100644 --- a/bip-0159.mediawiki +++ b/bip-0159.mediawiki @@ -5,7 +5,7 @@ Author: Jonas Schnelli Comments-Summary: No comments yet. Comments-URI: https://github.com/bitcoin/bips/wiki/Comments:BIP-0159 - Status: Draft + Status: Final Type: Standards Track Created: 2017-05-11 License: BSD-2-Clause From 1c6ac0c4cf1f39ea806b8594d6060b6d52fd1439 Mon Sep 17 00:00:00 2001 From: siv2r Date: Wed, 17 Jul 2024 15:32:20 +0530 Subject: [PATCH 330/454] bip327: minor fixes MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - An error test vector doesn’t specify the InvalidContributionError type - In *DeterministicSign*, use GetXonlyPubkey instead of GetPubkey - The key_agg_and_tweak fn doesn’t specify the return type - In partial_sig_verify_internal, the pubkey arg should be PlainPk - Remove unused enumerate() fn calls - In test_sign_verify, add an additional assert statement --- bip-0327.mediawiki | 2 +- bip-0327/gen_vectors_helper.py | 3 ++- bip-0327/reference.py | 25 ++++++++++++++----------- bip-0327/vectors/sig_agg_vectors.json | 3 ++- 4 files changed, 19 insertions(+), 14 deletions(-) diff --git a/bip-0327.mediawiki b/bip-0327.mediawiki index b659629bda..77a0024ea6 100644 --- a/bip-0327.mediawiki +++ b/bip-0327.mediawiki @@ -619,7 +619,7 @@ Algorithm ''DeterministicSign(sk, aggothernonce, pk1..u, tweak1. * Let ''keyagg_ctx0 = KeyAgg(pk1..u)''; fail if that fails * For ''i = 1 .. v'': ** Let ''keyagg_ctxi = ApplyTweak(keyagg_ctxi-1, tweaki, is_xonly_ti)''; fail if that fails -* Let ''aggpk = GetPubkey(keyagg_ctxv)'' +* Let ''aggpk = GetXonlyPubkey(keyagg_ctxv)'' * Let ''ki = int(hashMuSig/deterministic/nonce(sk' || aggothernonce || aggpk || bytes(8, len(m)) || m || bytes(1, i - 1))) mod n'' for ''i = 1,2'' * Fail if ''k1 = 0'' or ''k2 = 0'' * Let ''R⁎,1 = k1⋅G, R⁎,2 = k2⋅G'' diff --git a/bip-0327/gen_vectors_helper.py b/bip-0327/gen_vectors_helper.py index a70bb6f30a..03c2dbb2ac 100644 --- a/bip-0327/gen_vectors_helper.py +++ b/bip-0327/gen_vectors_helper.py @@ -153,7 +153,8 @@ def sig_agg_vectors(): "psig_indices": [7, 8], "error": { "type": "invalid_contribution", - "signer": 1 + "signer": 1, + "contrib": "psig", }, "comment": "Partial signature is invalid because it exceeds group size" } diff --git a/bip-0327/reference.py b/bip-0327/reference.py index edf6e76b0f..cc1af50547 100644 --- a/bip-0327/reference.py +++ b/bip-0327/reference.py @@ -317,7 +317,7 @@ def nonce_agg(pubnonces: List[bytes]) -> bytes: ('is_xonly', List[bool]), ('msg', bytes)]) -def key_agg_and_tweak(pubkeys: List[PlainPk], tweaks: List[bytes], is_xonly: List[bool]): +def key_agg_and_tweak(pubkeys: List[PlainPk], tweaks: List[bytes], is_xonly: List[bool]) -> KeyAggContext: if len(tweaks) != len(is_xonly): raise ValueError('The `tweaks` and `is_xonly` arrays must have the same length.') keyagg_ctx = key_agg(pubkeys) @@ -367,7 +367,7 @@ def sign(secnonce: bytearray, sk: bytes, session_ctx: SessionContext) -> bytes: raise ValueError('secret key value is out of range.') P = point_mul(G, d_) assert P is not None - pk = cbytes(P) + pk = PlainPk(cbytes(P)) if not pk == secnonce[64:97]: raise ValueError('Public key does not match nonce_gen argument') a = get_session_key_agg_coeff(session_ctx, P) @@ -430,7 +430,7 @@ def partial_sig_verify(psig: bytes, pubnonces: List[bytes], pubkeys: List[PlainP session_ctx = SessionContext(aggnonce, pubkeys, tweaks, is_xonly, msg) return partial_sig_verify_internal(psig, pubnonces[i], pubkeys[i], session_ctx) -def partial_sig_verify_internal(psig: bytes, pubnonce: bytes, pk: bytes, session_ctx: SessionContext) -> bool: +def partial_sig_verify_internal(psig: bytes, pubnonce: bytes, pk: PlainPk, session_ctx: SessionContext) -> bool: (Q, gacc, _, b, R, e) = get_session_values(session_ctx) s = int_from_bytes(psig) if s >= n: @@ -523,7 +523,7 @@ def test_key_agg_vectors() -> None: assert get_xonly_pk(key_agg(pubkeys)) == expected - for i, test_case in enumerate(error_test_cases): + for test_case in error_test_cases: exception, except_fn = get_error_details(test_case) pubkeys = [X[i] for i in test_case["key_indices"]] @@ -572,7 +572,7 @@ def test_nonce_agg_vectors() -> None: expected = bytes.fromhex(test_case["expected"]) assert nonce_agg(pubnonces) == expected - for i, test_case in enumerate(error_test_cases): + for test_case in error_test_cases: exception, except_fn = get_error_details(test_case) pubnonces = [pnonce[i] for i in test_case["pnonce_indices"]] assert_raises(exception, lambda: nonce_agg(pubnonces), except_fn) @@ -598,7 +598,10 @@ def test_sign_verify_vectors() -> None: aggnonces = fromhex_all(test_data["aggnonces"]) # The aggregate of the first three elements of pnonce is at index 0 - assert(aggnonces[0] == nonce_agg([pnonce[0], pnonce[1], pnonce[2]])) + assert (aggnonces[0] == nonce_agg([pnonce[0], pnonce[1], pnonce[2]])) + # The aggregate of the first and fourth elements of pnonce is at index 1, + # which is the infinity point encoded as a zeroed 33-byte array + assert (aggnonces[1] == nonce_agg([pnonce[0], pnonce[3]])) msgs = fromhex_all(test_data["msgs"]) @@ -626,7 +629,7 @@ def test_sign_verify_vectors() -> None: assert sign(secnonce_tmp, sk, session_ctx) == expected assert partial_sig_verify(expected, pubnonces, pubkeys, [], [], msg, signer_index) - for i, test_case in enumerate(sign_error_test_cases): + for test_case in sign_error_test_cases: exception, except_fn = get_error_details(test_case) pubkeys = [X[i] for i in test_case["key_indices"]] @@ -646,7 +649,7 @@ def test_sign_verify_vectors() -> None: assert not partial_sig_verify(sig, pubnonces, pubkeys, [], [], msg, signer_index) - for i, test_case in enumerate(verify_error_test_cases): + for test_case in verify_error_test_cases: exception, except_fn = get_error_details(test_case) sig = bytes.fromhex(test_case["sig"]) @@ -702,7 +705,7 @@ def test_tweak_vectors() -> None: assert sign(secnonce_tmp, sk, session_ctx) == expected assert partial_sig_verify(expected, pubnonces, pubkeys, tweaks, is_xonly, msg, signer_index) - for i, test_case in enumerate(error_test_cases): + for test_case in error_test_cases: exception, except_fn = get_error_details(test_case) pubkeys = [X[i] for i in test_case["key_indices"]] @@ -747,7 +750,7 @@ def test_det_sign_vectors() -> None: session_ctx = SessionContext(aggnonce, pubkeys, tweaks, is_xonly, msg) assert partial_sig_verify_internal(psig, pubnonce, pubkeys[signer_index], session_ctx) - for i, test_case in enumerate(error_test_cases): + for test_case in error_test_cases: exception, except_fn = get_error_details(test_case) pubkeys = [X[i] for i in test_case["key_indices"]] @@ -796,7 +799,7 @@ def test_sig_agg_vectors() -> None: aggpk = get_xonly_pk(key_agg_and_tweak(pubkeys, tweaks, is_xonly)) assert schnorr_verify(msg, aggpk, sig) - for i, test_case in enumerate(error_test_cases): + for test_case in error_test_cases: exception, except_fn = get_error_details(test_case) pubnonces = [pnonce[i] for i in test_case["nonce_indices"]] diff --git a/bip-0327/vectors/sig_agg_vectors.json b/bip-0327/vectors/sig_agg_vectors.json index 04a7bc6b50..519562c343 100644 --- a/bip-0327/vectors/sig_agg_vectors.json +++ b/bip-0327/vectors/sig_agg_vectors.json @@ -143,7 +143,8 @@ ], "error": { "type": "invalid_contribution", - "signer": 1 + "signer": 1, + "contrib": "psig" }, "comment": "Partial signature is invalid because it exceeds group size" } From 0d79b5eeb56af44281618b12d3ee35ef0de932e0 Mon Sep 17 00:00:00 2001 From: siv2r Date: Thu, 18 Jul 2024 17:09:19 +0530 Subject: [PATCH 331/454] remove P = None check as cpoint never returns None --- bip-0327/reference.py | 2 -- 1 file changed, 2 deletions(-) diff --git a/bip-0327/reference.py b/bip-0327/reference.py index cc1af50547..dd3bf68c9e 100644 --- a/bip-0327/reference.py +++ b/bip-0327/reference.py @@ -440,8 +440,6 @@ def partial_sig_verify_internal(psig: bytes, pubnonce: bytes, pk: PlainPk, sessi Re_s_ = point_add(R_s1, point_mul(R_s2, b)) Re_s = Re_s_ if has_even_y(R) else point_negate(Re_s_) P = cpoint(pk) - if P is None: - return False a = get_session_key_agg_coeff(session_ctx, P) g = 1 if has_even_y(Q) else n - 1 g_ = g * gacc % n From bc1c18a289770928bb5f185f2d13f392401aa604 Mon Sep 17 00:00:00 2001 From: omahs <73983677+omahs@users.noreply.github.com> Date: Sun, 21 Jul 2024 09:26:16 +0200 Subject: [PATCH 332/454] fix typo --- bip-0388/wallet_policies.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/bip-0388/wallet_policies.py b/bip-0388/wallet_policies.py index 4cd5031087..754d201058 100755 --- a/bip-0388/wallet_policies.py +++ b/bip-0388/wallet_policies.py @@ -142,7 +142,7 @@ def parse_key_expressions(only_first=False, handle_musig=False): continue if op in operators_key_all_but_first: - # skip the first argument (we now it's not a KEY expression, so it does not have a comma) + # skip the first argument (we know it's not a KEY expression, so it does not have a comma) first_comma_pos = descriptor.find(",", op_pos_start) if first_comma_pos == -1: raise Exception( From f61bdadafb82ae37166a4c2eb1ea1e4bed357f3a Mon Sep 17 00:00:00 2001 From: omahs <73983677+omahs@users.noreply.github.com> Date: Sun, 21 Jul 2024 09:31:28 +0200 Subject: [PATCH 333/454] fix typo --- bip-0390.mediawiki | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/bip-0390.mediawiki b/bip-0390.mediawiki index 05f57347b0..1024fb72b7 100644 --- a/bip-0390.mediawiki +++ b/bip-0390.mediawiki @@ -51,7 +51,7 @@ backed up, or guess, the correct order of keys.
. musig(KEY, KEY, ..., KEY)/NUM/.../* expressions are also allowed, with the same usage restrictions as in the previous section. The aggregate public key is first computed as described above, with the keys also being sorted after all derivation and prior -to aggreation. Then further BIP 32 derivation will be performed on the aggregate public key as described in +to aggregation. Then further BIP 32 derivation will be performed on the aggregate public key as described in [[bip-0328.mediawiki|BIP 328]]. As there is no aggregate private key, only unhardened derivation from the aggregate public key is allowed, and thus the derivation steps following the musig() expression cannot contain From f1a5c71094f212e088b9960eb69cdd5a9a27cb5e Mon Sep 17 00:00:00 2001 From: michael1011 Date: Sun, 21 Jul 2024 18:32:51 +0200 Subject: [PATCH 334/454] BIP46 clarify witness --- bip-0046.mediawiki | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/bip-0046.mediawiki b/bip-0046.mediawiki index e3ad575074..1602f811a1 100644 --- a/bip-0046.mediawiki +++ b/bip-0046.mediawiki @@ -90,7 +90,7 @@ month = 1 + index % 12 To derive the address from the above calculated public key and timelock, we create a witness script which locks the funds until the timelock, and then checks the signature of the derived_key. The witness script is hashed with SHA256 to produce a 32-byte hash value that forms the witness program in the output script of the P2WSH address. witnessScript: OP_CHECKLOCKTIMEVERIFY OP_DROP OP_CHECKSIG - witness: + witness: scriptSig: (empty) scriptPubKey: 0 <32-byte-hash> (0x0020{32-byte-hash}) From 26bb1d8ea3e2f0f7e02e1ec37a4b70fbc0781f85 Mon Sep 17 00:00:00 2001 From: Jonas Nick Date: Mon, 22 Jul 2024 14:14:33 +0000 Subject: [PATCH 335/454] bip-0327: 1.0.1 -> 1.0.2 (cherry picked from commit 4f2e6e7ffbd2fdc095ab8d59827be9da18b790be) --- bip-0327.mediawiki | 4 +++- bip-0327/reference.py | 4 ++-- 2 files changed, 5 insertions(+), 3 deletions(-) diff --git a/bip-0327.mediawiki b/bip-0327.mediawiki index 77a0024ea6..c9e88abddc 100644 --- a/bip-0327.mediawiki +++ b/bip-0327.mediawiki @@ -782,6 +782,8 @@ An exception to this rule is MAJOR version zero (0.y.z) which is fo The MINOR version is incremented whenever the inputs or the output of an algorithm changes in a backward-compatible way or new backward-compatible functionality is added. The PATCH version is incremented for other changes that are noteworthy (bug fixes, test vectors, important clarifications, etc.). +* '''1.0.2''' (2024-07-22): +** Fix minor bug in the specification of ''DeterministicSign'' and add small improvement to a ''PartialSigAgg'' test vector. * '''1.0.1''' (2024-05-14): ** Fix minor issue in ''PartialSigVerify'' vectors. * '''1.0.0''' (2023-03-26): @@ -825,4 +827,4 @@ The PATCH version is incremented for other changes that are notewor == Acknowledgements == -We thank Brandon Black, Riccardo Casatta, Lloyd Fournier, Russell O'Connor, and Pieter Wuille for their contributions to this document. +We thank Brandon Black, Riccardo Casatta, Sivaram Dhakshinamoorthy, Lloyd Fournier, Russell O'Connor, and Pieter Wuille for their contributions to this document. diff --git a/bip-0327/reference.py b/bip-0327/reference.py index dd3bf68c9e..17831c5f25 100644 --- a/bip-0327/reference.py +++ b/bip-0327/reference.py @@ -367,7 +367,7 @@ def sign(secnonce: bytearray, sk: bytes, session_ctx: SessionContext) -> bytes: raise ValueError('secret key value is out of range.') P = point_mul(G, d_) assert P is not None - pk = PlainPk(cbytes(P)) + pk = cbytes(P) if not pk == secnonce[64:97]: raise ValueError('Public key does not match nonce_gen argument') a = get_session_key_agg_coeff(session_ctx, P) @@ -430,7 +430,7 @@ def partial_sig_verify(psig: bytes, pubnonces: List[bytes], pubkeys: List[PlainP session_ctx = SessionContext(aggnonce, pubkeys, tweaks, is_xonly, msg) return partial_sig_verify_internal(psig, pubnonces[i], pubkeys[i], session_ctx) -def partial_sig_verify_internal(psig: bytes, pubnonce: bytes, pk: PlainPk, session_ctx: SessionContext) -> bool: +def partial_sig_verify_internal(psig: bytes, pubnonce: bytes, pk: bytes, session_ctx: SessionContext) -> bool: (Q, gacc, _, b, R, e) = get_session_values(session_ctx) s = int_from_bytes(psig) if s >= n: From 9a56d3544eac1f949a747c251810f7a440d63fb9 Mon Sep 17 00:00:00 2001 From: Orfeas Stefanos Thyfronitis Litos Date: Thu, 25 Jul 2024 18:35:39 +0300 Subject: [PATCH 336/454] Remove trailing whitespace from all BIPs --- bip-0009.mediawiki | 2 +- bip-0017.mediawiki | 2 +- bip-0038.mediawiki | 12 ++-- bip-0042.mediawiki | 2 +- bip-0052.mediawiki | 4 +- bip-0064.mediawiki | 2 +- bip-0065.mediawiki | 20 +++--- bip-0066.mediawiki | 4 +- bip-0067.mediawiki | 46 ++++++------- bip-0068.mediawiki | 6 +- bip-0072.mediawiki | 2 +- bip-0075.mediawiki | 18 ++--- bip-0083.mediawiki | 2 +- bip-0088.mediawiki | 2 +- bip-0090.mediawiki | 2 +- bip-0099.mediawiki | 28 ++++---- bip-0104.mediawiki | 2 +- bip-0105.mediawiki | 24 +++---- bip-0106.mediawiki | 6 +- bip-0107.mediawiki | 16 ++--- bip-0109.mediawiki | 2 +- bip-0112.mediawiki | 10 +-- bip-0113.mediawiki | 8 +-- bip-0120.mediawiki | 4 +- bip-0122.mediawiki | 8 +-- bip-0123.mediawiki | 2 +- bip-0129.mediawiki | 8 +-- bip-0132.mediawiki | 2 +- bip-0134.mediawiki | 2 +- bip-0141.mediawiki | 14 ++-- bip-0142.mediawiki | 22 +++--- bip-0143.mediawiki | 166 ++++++++++++++++++++++----------------------- bip-0144.mediawiki | 2 +- bip-0154.mediawiki | 8 +-- bip-0155.mediawiki | 2 +- bip-0156.mediawiki | 2 +- bip-0159.mediawiki | 2 +- bip-0174.mediawiki | 2 +- bip-0176.mediawiki | 2 +- bip-0199.mediawiki | 20 +++--- bip-0300.mediawiki | 14 ++-- bip-0301.mediawiki | 2 +- bip-0329.mediawiki | 12 ++-- bip-0340.mediawiki | 2 +- bip-0343.mediawiki | 2 +- bip-0345.mediawiki | 54 +++++++-------- bip-0347.mediawiki | 4 +- bip-0380.mediawiki | 2 +- 48 files changed, 291 insertions(+), 291 deletions(-) diff --git a/bip-0009.mediawiki b/bip-0009.mediawiki index f7fbad1c94..1883562dba 100644 --- a/bip-0009.mediawiki +++ b/bip-0009.mediawiki @@ -119,7 +119,7 @@ other one simultaneously transitions to STARTED, which would mean both would dem Note that a block's state never depends on its own nVersion; only on that of its ancestors. - case STARTED: + case STARTED: if (GetMedianTimePast(block.parent) >= timeout) { return FAILED; } diff --git a/bip-0017.mediawiki b/bip-0017.mediawiki index 671f75ab5d..aeb8764486 100644 --- a/bip-0017.mediawiki +++ b/bip-0017.mediawiki @@ -86,7 +86,7 @@ Avoiding a block-chain split by malicious pay-to-script transactions requires ca * A pay-to-script-hash transaction that is invalid for new clients/miners but valid for old clients/miners. -To gracefully upgrade and ensure no long-lasting block-chain split occurs, more than 50% of miners must support full validation of the new transaction type and must switch from the old validation rules to the new rules at the same time. +To gracefully upgrade and ensure no long-lasting block-chain split occurs, more than 50% of miners must support full validation of the new transaction type and must switch from the old validation rules to the new rules at the same time. To judge whether or not more than 50% of hashing power supports this BIP, miners are asked to upgrade their software and put the string "p2sh/CHV" in the input of the coinbase transaction for blocks that they create. diff --git a/bip-0038.mediawiki b/bip-0038.mediawiki index ab1a15839f..6bcf41198e 100644 --- a/bip-0038.mediawiki +++ b/bip-0038.mediawiki @@ -64,7 +64,7 @@ To keep the size of the encrypted key down, no initialization vectors (IVs) are * How the user sees it: 58 characters always starting with '6P' ** Visual cues are present in the third character for visually identifying the EC-multiply and compress flag. * Count of payload bytes (beyond prefix): 37 -** 1 byte (''flagbyte''): +** 1 byte (''flagbyte''): *** the most significant two bits are set as follows to preserve the visibility of the compression flag in the prefix, as well as to keep the payload within the range of allowable values that keep the "6P" prefix intact. For non-EC-multiplied keys, the bits are 11. For EC-multiplied keys, the bits are 00. *** the bit with value 0x20 when set indicates the key should be converted to a base58check encoded P2PKH bitcoin address using the DER compressed public key format. When not set, it should be a base58check encoded P2PKH bitcoin address using the DER uncompressed public key format. *** the bits with values 0x10 and 0x08 are reserved for a future specification that contemplates using multisig as a way to combine the factors such that parties in possession of the separate factors can independently sign a proposed transaction without requiring that any party possess both factors. These bits must be 0 to comply with this version of the specification. @@ -75,10 +75,10 @@ To keep the size of the encrypted key down, no initialization vectors (IVs) are **16 bytes: lasthalf: An AES-encrypted key material record (contents depend on whether EC multiplication is used) * Range in base58check encoding for non-EC-multiplied keys without compression (prefix 6PR): ** Minimum value: 6PRHv1jg1ytiE4kT2QtrUz8gEjMQghZDWg1FuxjdYDzjUkcJeGdFj9q9Vi (based on 01 42 C0 plus thirty-six 00's) -** Maximum value: 6PRWdmoT1ZursVcr5NiD14p5bHrKVGPG7yeEoEeRb8FVaqYSHnZTLEbYsU (based on 01 42 C0 plus thirty-six FF's) +** Maximum value: 6PRWdmoT1ZursVcr5NiD14p5bHrKVGPG7yeEoEeRb8FVaqYSHnZTLEbYsU (based on 01 42 C0 plus thirty-six FF's) * Range in base58check encoding for non-EC-multiplied keys with compression (prefix 6PY): ** Minimum value: 6PYJxKpVnkXUsnZAfD2B5ZsZafJYNp4ezQQeCjs39494qUUXLnXijLx6LG (based on 01 42 E0 plus thirty-six 00's) -** Maximum value: 6PYXg5tGnLYdXDRZiAqXbeYxwDoTBNthbi3d61mqBxPpwZQezJTvQHsCnk (based on 01 42 E0 plus thirty-six FF's) +** Maximum value: 6PYXg5tGnLYdXDRZiAqXbeYxwDoTBNthbi3d61mqBxPpwZQezJTvQHsCnk (based on 01 42 E0 plus thirty-six FF's) * Range in base58check encoding for EC-multiplied keys without compression (prefix 6Pf): ** Minimum value: 6PfKzduKZXAFXWMtJ19Vg9cSvbFg4va6U8p2VWzSjtHQCCLk3JSBpUvfpf (based on 01 43 00 plus thirty-six 00's) ** Maximum value: 6PfYiPy6Z7BQAwEHLxxrCEHrH9kasVQ95ST1NnuEnnYAJHGsgpNPQ9dTHc (based on 01 43 00 plus thirty-six FF's) @@ -272,7 +272,7 @@ Test 2: Test 1: *Passphrase: MOLON LABE -*Passphrase code: passphraseaB8feaLQDENqCgr4gKZpmf4VoaT6qdjJNJiv7fsKvjqavcJxvuR1hy25aTu5sX +*Passphrase code: passphraseaB8feaLQDENqCgr4gKZpmf4VoaT6qdjJNJiv7fsKvjqavcJxvuR1hy25aTu5sX *Encrypted key: 6PgNBNNzDkKdhkT6uJntUXwwzQV8Rr2tZcbkDcuC9DZRsS6AtHts4Ypo1j *Bitcoin address: 1Jscj8ALrYu2y9TD8NrpvDBugPedmbj4Yh *Unencrypted private key (WIF): 5JLdxTtcTHcfYcmJsNVy1v2PMDx432JPoYcBTVVRHpPaxUrdtf8 @@ -280,9 +280,9 @@ Test 1: *Confirmation code: cfrm38V8aXBn7JWA1ESmFMUn6erxeBGZGAxJPY4e36S9QWkzZKtaVqLNMgnifETYw7BPwWC9aPD *Lot/Sequence: 263183/1 -Test 2: +Test 2: *Passphrase (all letters are Greek - test UTF-8 compatibility with this): ΜΟΛΩΝ ΛΑΒΕ -*Passphrase code: passphrased3z9rQJHSyBkNBwTRPkUGNVEVrUAcfAXDyRU1V28ie6hNFbqDwbFBvsTK7yWVK +*Passphrase code: passphrased3z9rQJHSyBkNBwTRPkUGNVEVrUAcfAXDyRU1V28ie6hNFbqDwbFBvsTK7yWVK *Encrypted private key: 6PgGWtx25kUg8QWvwuJAgorN6k9FbE25rv5dMRwu5SKMnfpfVe5mar2ngH *Bitcoin address: 1Lurmih3KruL4xDB5FmHof38yawNtP9oGf *Unencrypted private key (WIF): 5KMKKuUmAkiNbA3DazMQiLfDq47qs8MAEThm4yL8R2PhV1ov33D diff --git a/bip-0042.mediawiki b/bip-0042.mediawiki index 2c5de6dfa3..c233e268d9 100644 --- a/bip-0042.mediawiki +++ b/bip-0042.mediawiki @@ -42,7 +42,7 @@ Note that several other programming languages do not exhibit this behaviour, mak ===Floating-point approximation=== -An obvious solution would be to reimplement the shape of the subsidy curve using floating-point approximations, such as simulated annealing or quantitative easing, which have already proven their worth in consensus systems. Unfortunately, since the financial crisis everyone considers numbers with decimal points in them fishy, and integers are not well supported by Javascript. +An obvious solution would be to reimplement the shape of the subsidy curve using floating-point approximations, such as simulated annealing or quantitative easing, which have already proven their worth in consensus systems. Unfortunately, since the financial crisis everyone considers numbers with decimal points in them fishy, and integers are not well supported by Javascript. ===Truncation=== diff --git a/bip-0052.mediawiki b/bip-0052.mediawiki index ea60f139d7..aa42ab38f7 100644 --- a/bip-0052.mediawiki +++ b/bip-0052.mediawiki @@ -25,7 +25,7 @@ Bitcoin network cannot profitably mine Bitcoin even if they have the capital to invest in mining hardware. From a practical perspective, Bitcoin adoption by companies like Tesla (which recently rescinded its acceptance of Bitcoin as payment) has been hampered by its massive energy consumption and perceived -environmental impact. +environmental impact. @@ -137,7 +137,7 @@ x1 <- keccak(input) x2 <- reshape(x1, 64) // Perform a matrix-vector multiplication. -// The result is 64-vector of 14-bit unsigned. +// The result is 64-vector of 14-bit unsigned. x3 <- vector_matrix_mult(x2, M) // Truncate all values to 4 most significant bits. diff --git a/bip-0064.mediawiki b/bip-0064.mediawiki index 82a6cfdc84..02c4c2a8ea 100644 --- a/bip-0064.mediawiki +++ b/bip-0064.mediawiki @@ -86,7 +86,7 @@ If the requesting client is looking up outputs for a signed transaction that the client can partly verify the returned output by running the input scripts with it. Currently this verifies only that the script is correct. A future version of the Bitcoin protocol is likely to also allow the value to be checked in this way. It does not show that the output is really unspent or was -ever actually created in the block chain however. Additionally, the form of the provided scriptPubKey +ever actually created in the block chain however. Additionally, the form of the provided scriptPubKey should be checked before execution to ensure the remote peer doesn't just set the script to OP_TRUE. If the requesting client has a mapping of chain heights to block hashes in the best chain e.g. diff --git a/bip-0065.mediawiki b/bip-0065.mediawiki index 15dca78419..db10c0ca9f 100644 --- a/bip-0065.mediawiki +++ b/bip-0065.mediawiki @@ -205,19 +205,19 @@ transaction output ''can'' be spent. Refer to the reference implementation, reproduced below, for the precise semantics and detailed rationale for those semantics. - + case OP_NOP2: { // CHECKLOCKTIMEVERIFY // // (nLockTime -- nLockTime ) - + if (!(flags & SCRIPT_VERIFY_CHECKLOCKTIMEVERIFY)) break; // not enabled; treat as a NOP - + if (stack.size() < 1) return false; - + // Note that elsewhere numeric opcodes are limited to // operands in the range -2**31+1 to 2**31-1, however it is // legal for opcodes to produce results exceeding that @@ -233,13 +233,13 @@ semantics and detailed rationale for those semantics. // to 5-byte bignums, which are good until 2**32-1, the // same limit as the nLockTime field itself. const CScriptNum nLockTime(stacktop(-1), 5); - + // In the rare event that the argument may be < 0 due to // some arithmetic being done first, you can always use // 0 MAX CHECKLOCKTIMEVERIFY. if (nLockTime < 0) return false; - + // There are two types of nLockTime: lock-by-blockheight // and lock-by-blocktime, distinguished by whether // nLockTime < LOCKTIME_THRESHOLD. @@ -252,12 +252,12 @@ semantics and detailed rationale for those semantics. (txTo.nLockTime >= LOCKTIME_THRESHOLD && nLockTime >= LOCKTIME_THRESHOLD) )) return false; - + // Now that we know we're comparing apples-to-apples, the // comparison is a simple numeric one. if (nLockTime > (int64_t)txTo.nLockTime) return false; - + // Finally the nLockTime feature can be disabled and thus // CHECKLOCKTIMEVERIFY bypassed if every txin has been // finalized by setting nSequence to maxint. The @@ -270,9 +270,9 @@ semantics and detailed rationale for those semantics. // required to prove correct CHECKLOCKTIMEVERIFY execution. if (txTo.vin[nIn].IsFinal()) return false; - + break; - + } https://github.com/petertodd/bitcoin/commit/ab0f54f38e08ee1e50ff72f801680ee84d0f1bf4 diff --git a/bip-0066.mediawiki b/bip-0066.mediawiki index 936d50754e..53289f5521 100644 --- a/bip-0066.mediawiki +++ b/bip-0066.mediawiki @@ -75,7 +75,7 @@ bool static IsValidSignatureEncoding(const std::vector &sig) { // Verify that the length of the signature matches the sum of the length // of the elements. if ((size_t)(lenR + lenS + 7) != sig.size()) return false; - + // Check whether the R element is an integer. if (sig[2] != 0x02) return false; @@ -140,7 +140,7 @@ An implementation for the reference client is available at https://github.com/bi ==Acknowledgements== -This document is extracted from the previous BIP62 proposal, which had input from various people, in particular Greg Maxwell and Peter Todd, who gave feedback about this document as well. +This document is extracted from the previous BIP62 proposal, which had input from various people, in particular Greg Maxwell and Peter Todd, who gave feedback about this document as well. ==Disclosures== diff --git a/bip-0067.mediawiki b/bip-0067.mediawiki index a31cc3d0ca..94153d376a 100644 --- a/bip-0067.mediawiki +++ b/bip-0067.mediawiki @@ -19,7 +19,7 @@ This BIP describes a method to deterministically generate multi-signature pay-to ==Motivation== -Pay-to-script-hash (BIP-0011[https://github.com/bitcoin/bips/blob/master/bip-0011.mediawiki BIP-0011]) is a transaction type that allows funding of arbitrary scripts, where the recipient carries the cost of fee's associated with using longer, more complex scripts. +Pay-to-script-hash (BIP-0011[https://github.com/bitcoin/bips/blob/master/bip-0011.mediawiki BIP-0011]) is a transaction type that allows funding of arbitrary scripts, where the recipient carries the cost of fee's associated with using longer, more complex scripts. Multi-signature pay-to-script-hash transactions are defined in BIP-0016[https://github.com/bitcoin/bips/blob/master/bip-0016.mediawiki BIP-0016]. The redeem script does not require a particular ordering or encoding for public keys. This means that for a given set of keys and number of required signatures, there are as many as 2(n!) possible standard redeem scripts, each with its separate P2SH address. Adhering to an ordering and key encoding would ensure that a multi-signature “account” (set of public keys and required signature count) has a canonical P2SH address. @@ -27,31 +27,31 @@ By adopting a sorting and encoding standard, compliant wallets will always produ While most web wallets do not presently facilitate the setup of multisignature accounts with users of a different service, conventions which ensure cross-compatibility should make it easier to achieve this. -Many wallet as a service providers use a 2of3 multi-signature schema where the user stores 1 of the keys (offline) as backup while using the other key for daily use and letting the service cosign his transactions. +Many wallet as a service providers use a 2of3 multi-signature schema where the user stores 1 of the keys (offline) as backup while using the other key for daily use and letting the service cosign his transactions. This standard will help in enabling a party other than the service provider to recover the wallet without any help from the service provider. ==Specification== For a set of public keys, ensure that they have been received in compressed form: - + 022df8750480ad5b26950b25c7ba79d3e37d75f640f8e5d9bcd5b150a0f85014da - 03e3818b65bcc73a7d64064106a859cc1a5a728c4345ff0b641209fba0d90de6e9 + 03e3818b65bcc73a7d64064106a859cc1a5a728c4345ff0b641209fba0d90de6e9 021f2f6e1e50cb6a953935c3601284925decd3fd21bc445712576873fb8c6ebc18 - -Sort them lexicographically according to their binary representation: - + +Sort them lexicographically according to their binary representation: + 021f2f6e1e50cb6a953935c3601284925decd3fd21bc445712576873fb8c6ebc18 022df8750480ad5b26950b25c7ba79d3e37d75f640f8e5d9bcd5b150a0f85014da 03e3818b65bcc73a7d64064106a859cc1a5a728c4345ff0b641209fba0d90de6e9 -..before using the resulting list of keys in a standard multisig redeem script: - +..before using the resulting list of keys in a standard multisig redeem script: + OP_2 021f2f6e1e50cb6a953935c3601284925decd3fd21bc445712576873fb8c6ebc18 022df8750480ad5b26950b25c7ba79d3e37d75f640f8e5d9bcd5b150a0f85014da 03e3818b65bcc73a7d64064106a859cc1a5a728c4345ff0b641209fba0d90de6e9 OP_3 OP_CHECKMULTISIG Hash the redeem script according to BIP-0016 to get the P2SH address. - + 3Q4sF6tv9wsdqu2NtARzNCpQgwifm2rAba - + ==Compatibility== * Uncompressed keys are incompatible with this specification. A compatible implementation should not automatically compress keys. Receiving an uncompressed key from a multisig participant should be interpreted as a sign that the user has an incompatible implementation. * P2SH addresses do not reveal information about the script that is receiving the funds. For this reason it is not technically possible to enforce this BIP as a rule on the network. Also, it would cause a hard fork. @@ -75,11 +75,11 @@ Vector 1 ** 39bgKC7RFbpoCRbtD5KEdkYKtNyhpsNa3Z Vector 2 (Already sorted, no action required) -* List: +* List: ** 02632b12f4ac5b1d1b72b2a3b508c19172de44f6f46bcee50ba33f3f9291e47ed0 ** 027735a29bae7780a9755fae7a1c4374c656ac6a69ea9f3697fda61bb99a4f3e77 ** 02e2cc6bd5f45edd43bebe7cb9b675f0ce9ed3efe613b177588290ad188d11b404 -* Sorted: +* Sorted: ** 02632b12f4ac5b1d1b72b2a3b508c19172de44f6f46bcee50ba33f3f9291e47ed0 ** 027735a29bae7780a9755fae7a1c4374c656ac6a69ea9f3697fda61bb99a4f3e77 ** 02e2cc6bd5f45edd43bebe7cb9b675f0ce9ed3efe613b177588290ad188d11b404 @@ -89,12 +89,12 @@ Vector 2 (Already sorted, no action required) ** 3CKHTjBKxCARLzwABMu9yD85kvtm7WnMfH Vector 3: -* List: +* List: ** 030000000000000000000000000000000000004141414141414141414141414141 ** 020000000000000000000000000000000000004141414141414141414141414141 ** 020000000000000000000000000000000000004141414141414141414141414140 ** 030000000000000000000000000000000000004141414141414141414141414140 -* Sorted: +* Sorted: ** 020000000000000000000000000000000000004141414141414141414141414140 ** 020000000000000000000000000000000000004141414141414141414141414141 ** 030000000000000000000000000000000000004141414141414141414141414140 @@ -105,11 +105,11 @@ Vector 3: ** 32V85igBri9zcfBRVupVvwK18NFtS37FuD Vector 4: (from bitcore) -* List: +* List: ** 022df8750480ad5b26950b25c7ba79d3e37d75f640f8e5d9bcd5b150a0f85014da -** 03e3818b65bcc73a7d64064106a859cc1a5a728c4345ff0b641209fba0d90de6e9 +** 03e3818b65bcc73a7d64064106a859cc1a5a728c4345ff0b641209fba0d90de6e9 ** 021f2f6e1e50cb6a953935c3601284925decd3fd21bc445712576873fb8c6ebc18 -* Sorted: +* Sorted: ** 021f2f6e1e50cb6a953935c3601284925decd3fd21bc445712576873fb8c6ebc18 ** 022df8750480ad5b26950b25c7ba79d3e37d75f640f8e5d9bcd5b150a0f85014da ** 03e3818b65bcc73a7d64064106a859cc1a5a728c4345ff0b641209fba0d90de6e9 @@ -119,13 +119,13 @@ Vector 4: (from bitcore) ** 3Q4sF6tv9wsdqu2NtARzNCpQgwifm2rAba ==Acknowledgements== -The authors wish to thank BtcDrak and Luke-Jr for their involvement & contributions in the early discussions of this BIP. +The authors wish to thank BtcDrak and Luke-Jr for their involvement & contributions in the early discussions of this BIP. -==Usage & Implementations== -* [[https://github.com/bitcoin/bips/blob/master/bip-0045.mediawiki#address-generation-procedure|BIP-0045]] - Structure for Deterministic P2SH Multisignature Wallets -* [[https://github.com/bitpay/bitcore/blob/50a868cb8cdf2be04bb1c5bf4bcc064cc06f5888/lib/script/script.js#L541|Bitcore]] +==Usage & Implementations== +* [[https://github.com/bitcoin/bips/blob/master/bip-0045.mediawiki#address-generation-procedure|BIP-0045]] - Structure for Deterministic P2SH Multisignature Wallets +* [[https://github.com/bitpay/bitcore/blob/50a868cb8cdf2be04bb1c5bf4bcc064cc06f5888/lib/script/script.js#L541|Bitcore]] * [[https://github.com/haskoin/haskoin-core/blob/b41b1deb0989334a7ead6fc993fb8b02f0c00810/haskoin-core/Network/Haskoin/Script/Parser.hs#L112-L122|Haskoin]] - Bitcoin implementation in Haskell -* [[https://github.com/etotheipi/BitcoinArmory/blob/268db0f3fa20c989057bd43343a43b2edbe89aeb/armoryengine/ArmoryUtils.py#L1441|Armory]] +* [[https://github.com/etotheipi/BitcoinArmory/blob/268db0f3fa20c989057bd43343a43b2edbe89aeb/armoryengine/ArmoryUtils.py#L1441|Armory]] * [[https://github.com/bitcoinj/bitcoinj/blob/master/core/src/main/java/org/bitcoinj/script/ScriptBuilder.java#L331|BitcoinJ]] == References == diff --git a/bip-0068.mediawiki b/bip-0068.mediawiki index ea0761d5b2..a84fce7cc4 100644 --- a/bip-0068.mediawiki +++ b/bip-0068.mediawiki @@ -33,7 +33,7 @@ If bit (1 << 31) of the sequence number is set, then no consensus meaning is app If bit (1 << 31) of the sequence number is not set, then the sequence number is interpreted as an encoded relative lock-time. -The sequence number encoding is interpreted as follows: +The sequence number encoding is interpreted as follows: Bit (1 << 22) determines if the relative lock-time is time-based or block based: If the bit is set, the relative lock-time specifies a timespan in units of 512 seconds granularity. The timespan starts from the median-time-past of the output’s previous block, and ends at the MTP of the previous block. If the bit is not set, the relative lock-time specifies a number of blocks. @@ -65,7 +65,7 @@ enum { /* Interpret sequence numbers as relative lock-time constraints. */ LOCKTIME_VERIFY_SEQUENCE = (1 << 0), }; - + /* Setting nSequence to this value for every input in a transaction * disables nLockTime. */ static const uint32_t SEQUENCE_FINAL = 0xffffffff; @@ -245,7 +245,7 @@ The most efficient way to calculate sequence number from relative lock-time is w // 0 <= nHeight < 65,535 blocks (1.25 years) nSequence = nHeight; nHeight = nSequence & 0x0000ffff; - + // 0 <= nTime < 33,554,431 seconds (1.06 years) nSequence = (1 << 22) | (nTime >> 9); nTime = (nSequence & 0x0000ffff) << 9; diff --git a/bip-0072.mediawiki b/bip-0072.mediawiki index d5e295e189..ab9c32d098 100644 --- a/bip-0072.mediawiki +++ b/bip-0072.mediawiki @@ -69,4 +69,4 @@ bitcoin:?r=https://merchant.com/pay.php?h%3D2a8628fc2fbe ==References== -[[http://www.w3.org/Protocols/rfc2616/rfc2616.html|RFC 2616]] : Hypertext Transfer Protocol -- HTTP/1.1 +[[http://www.w3.org/Protocols/rfc2616/rfc2616.html|RFC 2616]] : Hypertext Transfer Protocol -- HTTP/1.1 diff --git a/bip-0075.mediawiki b/bip-0075.mediawiki index 8c49645d19..ebd5b37d9a 100644 --- a/bip-0075.mediawiki +++ b/bip-0075.mediawiki @@ -18,11 +18,11 @@ This BIP is an extension to BIP 70 that provides two enhancements to the existing Payment Protocol. -# It allows the requester (Sender) of a PaymentRequest to voluntarily sign the original request and provide a certificate to allow the payee to know the identity of who they are transacting with. +# It allows the requester (Sender) of a PaymentRequest to voluntarily sign the original request and provide a certificate to allow the payee to know the identity of who they are transacting with. # It encrypts the PaymentRequest that is returned, before handing it off to the SSL/TLS layer to prevent man in the middle viewing of the Payment Request details. -The key words "MUST", "MUST NOT", "REQUIRED", "SHALL", "SHALL NOT", "SHOULD", "SHOULD NOT", "RECOMMENDED", "MAY", and +The key words "MUST", "MUST NOT", "REQUIRED", "SHALL", "SHALL NOT", "SHOULD", "SHOULD NOT", "RECOMMENDED", "MAY", and "OPTIONAL" in this document are to be interpreted as described in RFC 2119. ==Copyright== @@ -217,9 +217,9 @@ message EncryptedProtocolMessage { |} ==Payment Protocol Process with InvoiceRequests== -The full process overview for using '''InvoiceRequests''' in the Payment Protocol is defined below. +The full process overview for using '''InvoiceRequests''' in the Payment Protocol is defined below.

-All Payment Protocol messages MUST be encapsulated in either a [[#ProtocolMessage|ProtocolMessage]] or [[#EncryptedProcotolMessage|EncryptedProtocolMessage]]. Once the process begins using [[#EncryptedProtocolMessage|EncryptedProtocolMessage]] messages, all subsequent communications MUST use [[#EncryptedProtocolMessage|EncryptedProtocolMessages]]. +All Payment Protocol messages MUST be encapsulated in either a [[#ProtocolMessage|ProtocolMessage]] or [[#EncryptedProcotolMessage|EncryptedProtocolMessage]]. Once the process begins using [[#EncryptedProtocolMessage|EncryptedProtocolMessage]] messages, all subsequent communications MUST use [[#EncryptedProtocolMessage|EncryptedProtocolMessages]].

All Payment Protocol messages SHOULD be communicated using [[#EncryptedProtocolMessage|EncryptedProtocolMessage]] encapsulating messages with the exception that an [[#InvoiceRequest|InvoiceRequest]] MAY be communicated using the [[#ProtocolMessage|ProtocolMessage]] if the receiver's public key is unknown.

@@ -257,14 +257,14 @@ When communicated via '''HTTP''', the listed messages MUST be transmitted via TL ===Payment Protocol Status Communication=== -Every [[#ProtocolMessage|ProtocolMessage]] or [[#EncryptedProtocolMessage|EncryptedProtocolMessage]] MUST include a status code which conveys information about the last message received, if any (for the first message sent, use a status of 1 "OK" even though there was no previous message). In the case of an error that causes the Payment Protocol process to be stopped or requires that message be retried, a ProtocolMessage or EncryptedProtocolMessage SHOULD be returned by the party generating the error. The content of the message MUST contain the same '''serialized_message''' or '''encrypted_message''' and identifier (if present) and MUST have the status_code set appropriately. +Every [[#ProtocolMessage|ProtocolMessage]] or [[#EncryptedProtocolMessage|EncryptedProtocolMessage]] MUST include a status code which conveys information about the last message received, if any (for the first message sent, use a status of 1 "OK" even though there was no previous message). In the case of an error that causes the Payment Protocol process to be stopped or requires that message be retried, a ProtocolMessage or EncryptedProtocolMessage SHOULD be returned by the party generating the error. The content of the message MUST contain the same '''serialized_message''' or '''encrypted_message''' and identifier (if present) and MUST have the status_code set appropriately.

The status_message value SHOULD be set with a human readable explanation of the status code. ====Payment Protocol Status Codes==== {| class="wikitable" ! Status Code !! Description -|- +|- | 1 || OK |- | 2 || Cancel @@ -324,7 +324,7 @@ For the following we assume the Sender already knows the Receiver's public key, ** Set '''signature''' value to the computed signature ===InvoiceRequest Validation=== -* Validate '''sender_public_key''' is a valid EC public key +* Validate '''sender_public_key''' is a valid EC public key * Validate '''notification_url''', if set, contains characters deemed valid for a URL (avoiding XSS related characters, etc). * If '''pki_type''' is None, [[#InvoiceRequest|InvoiceRequest]] is VALID * If '''pki_type''' is x509+sha256 and '''signature''' is valid for the serialized [[#InvoiceRequest|InvoiceRequest]] where signature is set to "", [[#InvoiceRequest|InvoiceRequest]] is VALID @@ -366,7 +366,7 @@ For the following we assume the Sender already knows the Receiver's public key, The 16 byte authentication tag resulting from the AES-GCM encrypt operation MUST be prefixed to the returned ciphertext. The decrypt operation will use the first 16 bytes of the ciphertext as the GCM authentication tag and the remainder of the ciphertext as the ciphertext in the decrypt operation. ====AES-256 GCM Additional Authenticated Data==== -When either '''status_code''' OR '''status_message''' are present, the AES-256 GCM authenticated data used in both the encrypt and decrypt operations MUST be: STRING(status_code) || status_message. Otherwise, there is no additional authenticated data. This provides that, while not encrypted, the status_code and status_message are authenticated. +When either '''status_code''' OR '''status_message''' are present, the AES-256 GCM authenticated data used in both the encrypt and decrypt operations MUST be: STRING(status_code) || status_message. Otherwise, there is no additional authenticated data. This provides that, while not encrypted, the status_code and status_message are authenticated. ===Initial Public Key Retrieval for InvoiceRequest Encryption=== Initial public key retrieval for [[#InvoiceRequest|InvoiceRequest]] encryption via [[#EncryptedProtocolMessage|EncryptedProtocolMessage]] encapsulation can be done in a number of ways including, but not limited to, the following: @@ -387,7 +387,7 @@ Clients SHOULD keep in mind Receivers can broadcast a transaction without return ==Public Key & Signature Encoding== * All x.509 certificates included in any message defined in this BIP MUST be DER [ITU.X690.1994] encoded. -* All EC public keys ('''sender_public_key''', '''receiver_public_key''') in any message defined in this BIP MUST be [[SECP256k1|http://www.secg.org/sec2-v2.pdf]] ECDSA Public Key ECPoints encoded using [[SEC 2.3.3 Encoding|http://www.secg.org/sec1-v2.pdf]]. Encoding MAY be compressed. +* All EC public keys ('''sender_public_key''', '''receiver_public_key''') in any message defined in this BIP MUST be [[SECP256k1|http://www.secg.org/sec2-v2.pdf]] ECDSA Public Key ECPoints encoded using [[SEC 2.3.3 Encoding|http://www.secg.org/sec1-v2.pdf]]. Encoding MAY be compressed. * All ECC signatures included in any message defined in this BIP MUST use the SHA-256 hashing algorithm and MUST be DER [ITU.X690.1994] encoded. * All OpenPGP certificates must follow [[https://tools.ietf.org/html/rfc4880|RFC4880]], sections 5.5 and 12.1. diff --git a/bip-0083.mediawiki b/bip-0083.mediawiki index c6690015be..8c6f4443f7 100644 --- a/bip-0083.mediawiki +++ b/bip-0083.mediawiki @@ -83,7 +83,7 @@ We can continue creating subaccounts indefinitely using this scheme. In order to create a bidirectional payment channel, it is necessary that previous commitments be revokable. In order to revoke previous commitments, each party reveals a secret to the other that would allow them to steal the funds in the channel if a transaction for a previous commitment is inserted into the blockchain. -By allowing for arbitrary nesting of sublevels, we can construct decision trees of arbitrary depth and revoke an entire branch by revealing a parent node used to derive all the children. +By allowing for arbitrary nesting of sublevels, we can construct decision trees of arbitrary depth and revoke an entire branch by revealing a parent node used to derive all the children. ==References== diff --git a/bip-0088.mediawiki b/bip-0088.mediawiki index db21835e2e..c4c02e79ff 100644 --- a/bip-0088.mediawiki +++ b/bip-0088.mediawiki @@ -89,7 +89,7 @@ installation of malicious or incorrect profiles, though. ==Specification== -The format for the template was chosen to make it easy to read, convenient and visually unambiguous. +The format for the template was chosen to make it easy to read, convenient and visually unambiguous. Template starts with optional prefix m/, and then one or more sections delimited by the slash character (/). diff --git a/bip-0090.mediawiki b/bip-0090.mediawiki index 4c96698683..48d415194b 100644 --- a/bip-0090.mediawiki +++ b/bip-0090.mediawiki @@ -82,7 +82,7 @@ https://github.com/bitcoin/bitcoin/pull/8391. ==References== -[https://github.com/bitcoin/bips/blob/master/bip-0034.mediawiki BIP34 Block v2, Height in Coinbase] +[https://github.com/bitcoin/bips/blob/master/bip-0034.mediawiki BIP34 Block v2, Height in Coinbase] [https://github.com/bitcoin/bips/blob/master/bip-0066.mediawiki BIP66 Strict DER signatures] diff --git a/bip-0099.mediawiki b/bip-0099.mediawiki index 156eec02c5..5368b5370a 100644 --- a/bip-0099.mediawiki +++ b/bip-0099.mediawiki @@ -23,7 +23,7 @@ not always well-understood, and the best upgrade mechanisms to the consensus validation rules may vary depending on the type of change being deployed. Discussing such changes without a uniform view on the deployment paths often leads to misunderstandings and unnecessarily delays the -deployment of changes. +deployment of changes. ==Definitions== @@ -43,7 +43,7 @@ deployment of changes. : a theoretical piece of software that contains the specifications that define the validity of a block for a given state and chain parameters (ie it may act differently on, for example, regtest). ;Libbitcoinconsensus -: the existing implementation is a library that is compiled by default with Bitcoin Core master and exposes a single C function named bitcoinconsensus_verify_script(). Although it has a deterministic build and implements the most complex rules (most of the cryptography, which is itself heavily based on libsecp256k1 after #REPLACE_libsecp256k1_PR), it is still not a complete specification of the consensus rules. Since libconsensus doesn't manage the current state but only the validation of the next block given that state, it is known that this long effort of encapsulation and decoupling will eventually finish, and that the person who moves the last line +: the existing implementation is a library that is compiled by default with Bitcoin Core master and exposes a single C function named bitcoinconsensus_verify_script(). Although it has a deterministic build and implements the most complex rules (most of the cryptography, which is itself heavily based on libsecp256k1 after #REPLACE_libsecp256k1_PR), it is still not a complete specification of the consensus rules. Since libconsensus doesn't manage the current state but only the validation of the next block given that state, it is known that this long effort of encapsulation and decoupling will eventually finish, and that the person who moves the last line ==Taxonomy of consensus forks== @@ -76,14 +76,14 @@ without burdening them with specific design choices made by Bitcoin Core. It is to be noted that sharing the same code for consensus validation doesn't prevent alternative implementations from independently changing their consensus rules: they can always fork -the libbitcoinconsensus project (once it is in a separate repository). +the libbitcoinconsensus project (once it is in a separate repository). Hopefully libbitcoinconsensus will remove this type of consensus fork which - being accidental - obviously doesn't need a deployment plan. ====11/12 March 2013 Chain Fork==== -There is a precedent of an accidental consensus fork at height 225430. +There is a precedent of an accidental consensus fork at height 225430. Without entering into much detail (see [2]), the situation was different from what's being described from the alternative implementation risks (today alternative implementation still usually rely in different degrees on Bitcoin Core trusted proxies, which @@ -104,7 +104,7 @@ rapidly by the whole worldwide community and nobody is unhappy about the solution. But there's some philosophical disagreements on the terms of what the -solution was: we can add a pedantic note on that. +solution was: we can add a pedantic note on that. If "the implementation is the specification", then those levelDB-specific limitations were part of the consensus rules. Then additional rules were necessary and any alternative @@ -126,7 +126,7 @@ another consensus fork to remove them. Two theoretical consensus forks instead of one but the first one deployed practically for free. The practical result would have been identical and only the definitions change. This means discussing something that went uncontroversially -well further is "philosophical bike-shed" (TM). +well further is "philosophical bike-shed" (TM). ===Unilateral softforks=== @@ -157,17 +157,17 @@ that this must always be the case. While 2 chains cohexist, they can be considered two different currencies. We could say that bitcoin becomes bitcoinA and bitcoinB. The implications for market -capitalization are completely unpredictable, +capitalization are completely unpredictable, -maybe mc(bitcoinA) = mc(bitcoinB) = mc(old_bitcoin), +maybe mc(bitcoinA) = mc(bitcoinB) = mc(old_bitcoin), -maybe mc(bitcoinA) + mc(bitcoinB) = mc(old_bitcoin), +maybe mc(bitcoinA) + mc(bitcoinB) = mc(old_bitcoin), maybe mc(bitcoinA) + mc(bitcoinB) = 1000 * mc(old_bitcoin), maybe mc(bitcoinA) + mc(bitcoinB) = 0, -... +... Schism hardforks have been compared to one type of altcoins called "spinoffs"[spinoffs] that distribute all or part of its initial seigniorage to @@ -224,7 +224,7 @@ Let's imagine BIP66 had a crypto backdoor that nobody noticed and allows an evil developer cabal to steal everyone's coins. The users and non-evil developers could join, fork libconsensus and use the forked version in their respective bitcoin -implementations. +implementations. Should miner's "vote" be required to express their consent? What if some miners are part of the cabal? In the unlikely event that most miners are part of such an evil cabal, changing the pow function may be @@ -268,7 +268,7 @@ that's why the voting mechanism and first used for BIP30 and BIP66. The current voting threshold for softfork enforcement is 95%. There's also a 75% threshold for miners to activate it as a policy rule, but it should be safe for miners to activate such a policy from the start -or later than 75%, as long as they enforce it as consensus rule after 95%. +or later than 75%, as long as they enforce it as consensus rule after 95%. The current miners' voting mechanism can be modified to allow for changes to be deployed in parallel, the rejection of a concrete @@ -355,12 +355,12 @@ worth of blocks). [5] Original references: https://bitcointalk.org/index.php?topic=114751.0 https://bitcointalk.org/index.php?topic=43692.msg521772#msg521772 -Rebased patch: +Rebased patch: https://github.com/freicoin/freicoin/commit/beb2fa54745180d755949470466cbffd1cd6ff14 ==Attribution== -Incorporated corrections and suggestions from: Andy Chase, Bryan Bishop, +Incorporated corrections and suggestions from: Andy Chase, Bryan Bishop, Btcdrak, Gavin Andresen, Gregory Sanders, Luke Dashjr, Marco Falke. ==Copyright== diff --git a/bip-0104.mediawiki b/bip-0104.mediawiki index 1244b3e420..4d81110af7 100644 --- a/bip-0104.mediawiki +++ b/bip-0104.mediawiki @@ -65,7 +65,7 @@ A hardcoded increase to max block size (2MB, 8MB, etc.), rejected because: Allow miners to vote for max block size, rejected because: * overly complex and political * human involvement makes this slow to respond to changing transaction volumes -* focuses power over max block size to a relatively small group of people +* focuses power over max block size to a relatively small group of people * unpredictable transaction fees caused by this would create uncertainty in the ecosystem ==Backward Compatibility== diff --git a/bip-0105.mediawiki b/bip-0105.mediawiki index 3643562ef8..af416910df 100644 --- a/bip-0105.mediawiki +++ b/bip-0105.mediawiki @@ -13,21 +13,21 @@ ==Abstract== -A method of altering the maximum allowed block size of the Bitcoin protocol +A method of altering the maximum allowed block size of the Bitcoin protocol using a consensus based approach. ==Motivation== -There is a belief that Bitcoin cannot easily respond to raising the -blocksize limit if popularity was to suddenly increase due to a mass adoption -curve, because co-ordinating a hard fork takes considerable time, and being -unable to respond in a timely manner would irreparably harm the credibility of +There is a belief that Bitcoin cannot easily respond to raising the +blocksize limit if popularity was to suddenly increase due to a mass adoption +curve, because co-ordinating a hard fork takes considerable time, and being +unable to respond in a timely manner would irreparably harm the credibility of bitcoin. Additionally, predetermined block size increases are problematic because they -attempt to predict the future, and if too large could have unintended -consequences like damaging the possibility for a fee market to develop -as block subsidy decreases substantially over the next 9 years; introducing +attempt to predict the future, and if too large could have unintended +consequences like damaging the possibility for a fee market to develop +as block subsidy decreases substantially over the next 9 years; introducing or exacerbating mining attack vectors; or somehow affect the network in unknown or unpredicted ways. Since fixed changes are hard to deploy, the damage could be extensive. @@ -36,14 +36,14 @@ Dynamic block size adjustments also suffer from the potential to be gamed by the larger hash power. Free voting as suggested by BIP100 allows miners to sell their votes out of band -at no risk, and enable the sponsor the ability to manipulate the blocksize. +at no risk, and enable the sponsor the ability to manipulate the blocksize. It also provides a cost free method or the larger pools to vote in ways to manipulate the blocksize such to disadvantage or attack smaller pools. ==Rationale== -By introducing a cost to increase the block size ensures the mining community +By introducing a cost to increase the block size ensures the mining community will collude to increase it only when there is a clear necessity, and reduce it when it is unnecessary. Larger miners cannot force their wishes so easily because not only will they have to pay extra a difficulty target, then can be @@ -63,7 +63,7 @@ honest. The initial block size limit shall be 1MB. Each time a miner creates a block, they may vote to increase or decrease the -blocksize by a maximum of 10% of the current block size limit. These votes will +blocksize by a maximum of 10% of the current block size limit. These votes will be used to recalculate the new block size limit every 2016 blocks. Votes are cast using the block's coinbase transaction scriptSig. @@ -77,7 +77,7 @@ If a miner votes for an increase, the block hash must meet a difficulty target which is proportionally larger than the standard difficulty target based on the percentage increase they voted for. -Votes proposing decreasing the block size limit do not need to meet a higher +Votes proposing decreasing the block size limit do not need to meet a higher difficulty target. Miners can vote for no change by voting for the current block size. diff --git a/bip-0106.mediawiki b/bip-0106.mediawiki index 193d4cd8a6..84b04980f2 100644 --- a/bip-0106.mediawiki +++ b/bip-0106.mediawiki @@ -36,13 +36,13 @@ https://blockchain.info/charts/avg-block-size?timespan=all&showDataPoints=false& Keep the same MaxBlockSize ===Proposal 2 : Depending on previous block size calculation and previous Tx fee collected by miners=== - + TotalBlockSizeInLastButOneDifficulty = Sum of all Block size of first 2008 blocks in last 2 difficulty period TotalBlockSizeInLastDifficulty = Sum of all Block size of second 2008 blocks in last 2 difficulty period (This actually includes 8 blocks from last but one difficulty) - + TotalTxFeeInLastButOneDifficulty = Sum of all Tx fees of first 2008 blocks in last 2 difficulty period TotalTxFeeInLastDifficulty = Sum of all Tx fees of second 2008 blocks in last 2 difficulty period (This actually includes 8 blocks from last but one difficulty) - + If ( ( (Sum of first 4016 block size in last 2 difficulty period)/4016 > 50% MaxBlockSize) AND (TotalTxFeeInLastDifficulty > TotalTxFeeInLastButOneDifficulty) AND (TotalBlockSizeInLastDifficulty > TotalBlockSizeInLastButOneDifficulty) ) MaxBlockSize = TotalBlockSizeInLastDifficulty * MaxBlockSize / TotalBlockSizeInLastButOneDifficulty Else If ( ( (Sum of first 4016 block size in last 2 difficulty period)/4016 < 50% MaxBlockSize) AND (TotalTxFeeInLastDifficulty < TotalTxFeeInLastButOneDifficulty) AND (TotalBlockSizeInLastDifficulty < TotalBlockSizeInLastButOneDifficulty) ) diff --git a/bip-0107.mediawiki b/bip-0107.mediawiki index b82db614f7..915657aa70 100644 --- a/bip-0107.mediawiki +++ b/bip-0107.mediawiki @@ -24,7 +24,7 @@ Over the next few years, large infrastructure investments will be made into: # Layer 2 services and networks for off-chain transactions # General efficiency improvements to transactions and the blockchain -* While there is a consensus between Bitcoin developers, miners, businesses and users that the block size needs to be increased, there is a lingering concern over the potential unintended consequences that may augment the trend towards network and mining centralization (largely driven by mining hardware such as ASICs) and thereby threaten the security of the network. +* While there is a consensus between Bitcoin developers, miners, businesses and users that the block size needs to be increased, there is a lingering concern over the potential unintended consequences that may augment the trend towards network and mining centralization (largely driven by mining hardware such as ASICs) and thereby threaten the security of the network. * In contrast, failing to respond to elevated on-chain transaction volume may lead to a consumer-failure of Bitcoin, where ordinary users - having enjoyed over 6 years of submitting transactions on-chain at relatively low cost - will be priced out of blockchain with the emergence of a prohibitive 'fee market'. * These two concerns must be delicately balanced so that all users can benefit from a robust, scalable, and neutral network. @@ -40,7 +40,7 @@ Over the next few years, large infrastructure investments will be made into: * '''Phase 2''' ** In 2020, the maximum block size will be increased dynamically according to sustained increases in transaction volume ** Every 4032 blocks (~4 weeks), a CHECK will be performed to determine if a raise in the maximum block size should occur -*** This calculates to a theoretical maximum of 13 increases per year +*** This calculates to a theoretical maximum of 13 increases per year ** IF of the last >= 3025 blocks were >=60% full, the maximum block size will be increased by 10% ** The maximum block size can only ever be increased, not decreased * The default limitfreerelay will also be raised in proportion to maximum block size increases @@ -49,8 +49,8 @@ Over the next few years, large infrastructure investments will be made into: For example: * When the dynamic rules for increasing the block size go live on January 1st 2020, the starting maximum block size will be 6 MB -* IF >=3025 blocks are >= 3.6 MB, the new maximum block size become 6.6 MB. -* The theoretical maximum block size at the end of 2020 would be ~20.7 MB, assuming all 13 increases are triggered every 4 weeks by the end of the year. +* IF >=3025 blocks are >= 3.6 MB, the new maximum block size become 6.6 MB. +* The theoretical maximum block size at the end of 2020 would be ~20.7 MB, assuming all 13 increases are triggered every 4 weeks by the end of the year. ==Rationale== @@ -63,19 +63,19 @@ For example: *** Setting the parameter too high may set the trigger sensitivity too low, causing transaction delays that are trying to be avoided in the first place *** Between September 2013-2015, the standard deviation measured from average block size (n=730 data points from blockchain.info) was ~ 0.13 MB or 13% of the maximum block size **** If blocks needed to be 90% full before an increase were triggered, normal variance in the average block size would mean some blocks would be full before an increase could be triggered -*** Therefore, we need a ''safe distance'' away from the maximum block size to avoid normal block size variance hitting the limit. The 60% level represents a 3 standard deviation distance from the limit. +*** Therefore, we need a ''safe distance'' away from the maximum block size to avoid normal block size variance hitting the limit. The 60% level represents a 3 standard deviation distance from the limit. ** Why 3025 blocks? *** The assessment period is 4032 blocks or ~ 4 weeks, with the threshold set as 4032 blocks/0.75 + 1 *** Increases in the maximum block size should only occur after a sustained trend can be observed in order to: ***# Demonstrate a market-driven secular elevation in the transaction volume -***# Increase the cost to trigger an increase by spam attacks or miner collusion with zero fee transactions +***# Increase the cost to trigger an increase by spam attacks or miner collusion with zero fee transactions *** In other words, increases to the maximum block size must be conservative but meaningful to relieve transaction volume pressure in response to true market demand ** Why 10% increase in the block size? *** Increases in the block size are designed to be conservative and in balance with the number of theoretical opportunities to increase the block size per year -*** Makes any resources spent for spam attacks or miner collusion relatively expensive to achieve a minor increase in the block size. A sustained attack would need to be launched that may be too costly, and ideally detectable by the community +*** Makes any resources spent for spam attacks or miner collusion relatively expensive to achieve a minor increase in the block size. A sustained attack would need to be launched that may be too costly, and ideally detectable by the community ==Deployment== -Similar deployment model to BIP101: +Similar deployment model to BIP101:
Activation is achieved when 750 of 1,000 consecutive blocks in the best chain have a version number with the first, second, third, and thirtieth bits set (0x20000007 in hex). The activation time will be the timestamp of the 750'th block plus a two week (1,209,600 second) grace period to give any remaining miners or services time to upgrade to support larger blocks.
==Acknowledgements== diff --git a/bip-0109.mediawiki b/bip-0109.mediawiki index 4822d4a25d..ec1d7e5bc6 100644 --- a/bip-0109.mediawiki +++ b/bip-0109.mediawiki @@ -65,7 +65,7 @@ SPV (simple payment validation) wallets are compatible with this change. ==Rationale== -In the short term, an increase is needed to handle increasing transaction volume. +In the short term, an increase is needed to handle increasing transaction volume. The limits on signature operations and amount of signature hashing done prevent possible CPU exhaustion attacks by "rogue miners" producing very expensive-to-validate two megabyte blocks. The signature hashing limit is chosen to be impossible to reach with any non-attack transaction or block, to minimize the impact on existing mining or wallet software. diff --git a/bip-0112.mediawiki b/bip-0112.mediawiki index d6ed546025..f38fa15d83 100644 --- a/bip-0112.mediawiki +++ b/bip-0112.mediawiki @@ -69,13 +69,13 @@ address with the following redeemscript. CHECKSIG ENDIF -At any time funds can be spent using signatures from any two of Alice, +At any time funds can be spent using signatures from any two of Alice, Bob or the Escrow. After 30 days Alice can sign alone. The clock does not start ticking until the payment to the escrow address -confirms. +confirms. ===Retroactive Invalidation=== @@ -230,7 +230,7 @@ The 2-way pegged sidechain requires a new REORGPROOFVERIFY opcode, the semantics ==Specification== -Refer to the reference implementation, reproduced below, for the precise +Refer to the reference implementation, reproduced below, for the precise semantics and detailed rationale for those semantics.
@@ -247,7 +247,7 @@ static const uint32_t SEQUENCE_LOCKTIME_TYPE_FLAG = (1 << 22);
 /* If CTxIn::nSequence encodes a relative lock-time, this mask is
  * applied to extract that lock-time from the sequence field. */
 static const uint32_t SEQUENCE_LOCKTIME_MASK = 0x0000ffff;
-   
+
 case OP_NOP3:
 {
     if (!(flags & SCRIPT_VERIFY_CHECKSEQUENCEVERIFY)) {
@@ -290,7 +290,7 @@ case OP_NOP3:
 
     break;
 }
-    
+
 bool TransactionSignatureChecker::CheckSequence(const CScriptNum& nSequence) const
 {
     // Relative lock times are supported by comparing the passed
diff --git a/bip-0113.mediawiki b/bip-0113.mediawiki
index 368677715b..d736280931 100644
--- a/bip-0113.mediawiki
+++ b/bip-0113.mediawiki
@@ -45,13 +45,13 @@ BIP68 (sequence numbers) and BIP112 (CHECKSEQUENCEVERIFY).
 
 ==Specification==
 
-The values for transaction locktime remain unchanged. The difference is only in 
-the calculation determining whether a transaction can be included. Instead of 
-an unreliable timestamp, the following function is used to determine the current 
+The values for transaction locktime remain unchanged. The difference is only in
+the calculation determining whether a transaction can be included. Instead of
+an unreliable timestamp, the following function is used to determine the current
 block time for the purpose of checking lock-time constraints:
 
     enum { nMedianTimeSpan=11 };
-    
+
     int64_t GetMedianTimePast(const CBlockIndex* pindex)
     {
         int64_t pmedian[nMedianTimeSpan];
diff --git a/bip-0120.mediawiki b/bip-0120.mediawiki
index b951e93eaf..c9c11e549f 100644
--- a/bip-0120.mediawiki
+++ b/bip-0120.mediawiki
@@ -52,7 +52,7 @@ A proof of payment for a transaction T, here called PoP(T), is used to prove tha
 
  OP_RETURN   
 
-{|        
+{|
 ! Field        !! Size [B] !! Description
 |-
 | <version> || 2        || Version, little endian, currently 0x01 0x00
@@ -77,7 +77,7 @@ An illustration of the PoP data structure and its original payment is shown belo
  |input2 4,ffffffff     | 1,pay to B              |
  |                      | 4,pay to C              |
  +------------------------------------------------+
- 
+
   PoP(T)
  +-------------------------------------------------------------+
  | inputs               | outputs                              |
diff --git a/bip-0122.mediawiki b/bip-0122.mediawiki
index 3fb5df870c..6243c64fef 100644
--- a/bip-0122.mediawiki
+++ b/bip-0122.mediawiki
@@ -43,7 +43,7 @@ Where:
 | rowspan="3" | type
 | tx
 | for transactions.
-| rowspan="3" | required 
+| rowspan="3" | required
 |-
 | block
 | for blocks (supports both hash or height).
@@ -75,9 +75,9 @@ The '''chain ID''' of a chain is the block hash of the corresponding genesis blo
 
 So, for example:
 
-Bitcoin main   : 000000000019d6689c085ae165831e934ff763ae46a2a6c172b3f1b60a8ce26f 
+Bitcoin main   : 000000000019d6689c085ae165831e934ff763ae46a2a6c172b3f1b60a8ce26f
 Bitcoin test   : 000000000933ea01ad0ee984209779baaec3ced90fa3f408719526f8d77f4943
-Bitcoin regtest: 0f9188f13cb7b2c71f2a335e3a4fc328bf5beb436012afca590b1a11466e2206 
+Bitcoin regtest: 0f9188f13cb7b2c71f2a335e3a4fc328bf5beb436012afca590b1a11466e2206
 
An example of forked chain (Feathercoin, that forked Litecoin): @@ -87,7 +87,7 @@ An example of forked chain (Feathercoin, that forked Litecoin):
 Litecoin   : 12a765e31ffd4059bada1e25190f6e98c99d9714d334efa41a195a7e7e04bfe2
 Feathercoin: fdbe99b90c90bae7505796461471d89ae8388ab953997aa06a355bbda8d915cb
-
+
==Examples== diff --git a/bip-0123.mediawiki b/bip-0123.mediawiki index 2404937b8e..a0dfd2ce05 100644 --- a/bip-0123.mediawiki +++ b/bip-0123.mediawiki @@ -72,7 +72,7 @@ There's room at this layer to allow for competing standards without breaking bas ===4. Applications Layer=== -The applications layer specifies high level structures, abstractions, and conventions that allow different applications to support similar features and share data. +The applications layer specifies high level structures, abstractions, and conventions that allow different applications to support similar features and share data. ==Classification of existing BIPs== diff --git a/bip-0129.mediawiki b/bip-0129.mediawiki index b5dfae82c7..1eaf55d68c 100644 --- a/bip-0129.mediawiki +++ b/bip-0129.mediawiki @@ -95,7 +95,7 @@ The Signer is any software or hardware that controls the private keys and can si * The Coordinator verifies that the included SIG is valid given the KEY. * If all key records look good, the Coordinator fills in all necessary information to generate a descriptor record. * The first line in the descriptor record must be the specification version (BSMS 1.0 as of this writing). The second line must be a descriptor or a descriptor template. The third line must be a comma-separated list of derivation path restrictions. The paths must start with / and use non-hardened derivation. If there are no template or restrictions, it must say No path restrictions. The fourth line must be the wallet's first address. If there are path restrictions, use the first address from the first path restriction. -* The Coordinator calculates the MAC for the record. The first 16 bytes of the MAC serves as the IV for the encryption.. +* The Coordinator calculates the MAC for the record. The first 16 bytes of the MAC serves as the IV for the encryption.. * The Coordinator encrypts the descriptor record with the ENCRYPTION_KEY and IV. * The Coordinator encodes the MAC and the ciphertext into hexadecimal format, then concatenates the results: (MAC || ciphertext). * The Coordinator sends the encrypted descriptor record to all participating Signers. @@ -110,7 +110,7 @@ The Signer is any software or hardware that controls the private keys and can si * The Signer checks that its KEY is included in the descriptor or descriptor template, using path and fingerprint information provided. The check must perform an exact match on the KEYs and not using shortcuts such as matching fingerprints, which is trivial to spoof. * The Signer verifies that it is compatible with the derivation path restrictions. * The Signer verifies that the wallet's first address is valid. -* For confirmation, the Signer must display to the user the wallet's first address and policy parameters, including, but not limited to: the derivation path restrictions, M, N, and the position(s) of the Signer's own KEY in the policy script. The total number of Signers, N, is important to prevent a KEY insertion attack. The position is important for scripts where KEY order matters. When applicable, all positions of the KEY must be displayed. The full descriptor or descriptor template must also be available for review upon user request. +* For confirmation, the Signer must display to the user the wallet's first address and policy parameters, including, but not limited to: the derivation path restrictions, M, N, and the position(s) of the Signer's own KEY in the policy script. The total number of Signers, N, is important to prevent a KEY insertion attack. The position is important for scripts where KEY order matters. When applicable, all positions of the KEY must be displayed. The full descriptor or descriptor template must also be available for review upon user request. * Parties must check with each other that all Signers have the same confirmation (except for the KEY positions). * If all checks pass, the Signer must persist the descriptor record in its storage. @@ -126,8 +126,8 @@ We define three modes of encryption. # EXTENDED : the TOKEN is a 128-bit nonce. The TOKEN can be converted to one of these formats: -* A decimal number (recommended). The number must not exceed the maximum value of the nonce. -* A mnemonic phrase using [https://github.com/bitcoin/bips/blob/master/bip-0039.mediawiki BIP-0039] word list. This would be 6 words in STANDARD mode. This encoding is not recommended in EXTENDED mode as it can result in potential confusion between seed mnemonics and TOKEN mnemonics. +* A decimal number (recommended). The number must not exceed the maximum value of the nonce. +* A mnemonic phrase using [https://github.com/bitcoin/bips/blob/master/bip-0039.mediawiki BIP-0039] word list. This would be 6 words in STANDARD mode. This encoding is not recommended in EXTENDED mode as it can result in potential confusion between seed mnemonics and TOKEN mnemonics. * A QR code. * Other formats. diff --git a/bip-0132.mediawiki b/bip-0132.mediawiki index 173c919818..2b2b26c367 100644 --- a/bip-0132.mediawiki +++ b/bip-0132.mediawiki @@ -83,7 +83,7 @@ The author doesn't believe this is a problem because a BIP cannot be forced on c ** User communities * A person may be represented by any number of segments, but a committee cannot re-use the same resource as another committee in the same segment. -'''Committee Declarations.''' +'''Committee Declarations.''' * At any point, a Committee Declaration can be posted. * This Declaration must contain details about: ** The segment the Committee is representing diff --git a/bip-0134.mediawiki b/bip-0134.mediawiki index b7c33cf91c..4af4844eaf 100644 --- a/bip-0134.mediawiki +++ b/bip-0134.mediawiki @@ -58,7 +58,7 @@ various decades ago with the XML format. The idea is that we give each field a name and this means that new fields can be added or optional fields can be omitted from individual transactions. Some other ideas are the standardization of data-formats (like integer and string encoding) so -we create a more consistent system. +we create a more consistent system. One thing we shall not inherit from XML is its text-based format. Instead we use the [https://github.com/bitcoinclassic/documentation/blob/master/spec/compactmessageformat.md Compact Message Format] (CMF) which is optimized to keep the size small and fast to parse. diff --git a/bip-0141.mediawiki b/bip-0141.mediawiki index 117ca59df6..4ba6798426 100644 --- a/bip-0141.mediawiki +++ b/bip-0141.mediawiki @@ -43,13 +43,13 @@ By removing this data from the transaction structure committed to the transactio A new data structure, witness, is defined. Each transaction will have 2 IDs. Definition of txid remains unchanged: the double SHA256 of the traditional serialization format: - + [nVersion][txins][txouts][nLockTime] - + A new wtxid is defined: the double SHA256 of the new serialization with witness data: - + [nVersion][marker][flag][txins][txouts][witness][nLockTime] - + Format of nVersion, txins, txouts, and nLockTime are same as traditional serialization. The marker MUST be a 1-byte zero value: 0x00. @@ -67,14 +67,14 @@ A new block rule is added which requires a commitment to the wtxid. A witness root hash is calculated with all those wtxid as leaves, in a way similar to the hashMerkleRoot in the block header. The commitment is recorded in a scriptPubKey of the coinbase transaction. It must be at least 38 bytes, with the first 6-byte of 0x6a24aa21a9ed, that is: - + 1-byte - OP_RETURN (0x6a) 1-byte - Push the following 36 bytes (0x24) 4-byte - Commitment header (0xaa21a9ed) 32-byte - Commitment hash: Double-SHA256(witness root hash|witness reserved value) - + 39th byte onwards: Optional data with no consensus meaning - + and the coinbase's input's witness must consist of a single 32-byte array for the witness reserved value. If there are more than one scriptPubKey matching the pattern, the one with highest output index is assumed to be the commitment. diff --git a/bip-0142.mediawiki b/bip-0142.mediawiki index b11095b8b1..49ed8dca94 100644 --- a/bip-0142.mediawiki +++ b/bip-0142.mediawiki @@ -24,14 +24,14 @@ To define standard payment address for native segregated witness (segwit) transa The new Bitcoin address format defined is for the Pay-to-Witness-Public-Key-Hash (P2WPKH) and Pay-to-Witness-Script-Hash (P2WSH) transaction described in segregated witness soft fork (BIP141). The scriptPubKey is an OP_0 followed by a push of 20-byte-hash (P2WPKH) or 32-byte hash (P2WSH). The new address is encoded in a way similar to existing address formats: - + base58-encode: [1-byte address version] [1-byte witness program version] [0x00] [20/32-byte-hash] [4-byte checksum] - + For P2WPKH address, the address version is 6 (0x06) for a main-network address or 3 (0x03) for a testnet address. For P2WSH address, the address version is 10 (0x0A) for a main-network address or 40 (0x28) for a testnet address. @@ -123,25 +123,25 @@ This proposal is forward-compatible with future versions of witness programs of == Example == The following public key, - + 0450863AD64A87AE8A2FE83C1AF1A8403CB53F53E486D8511DAD8A04887E5B23522CD470243453A299FA9E77237716103ABC11A1DF38855ED6F2EE187E9C582BA6 - + when encoded as a P2PKH template, would become: - + DUP HASH160 <010966776006953D5567439E5E39F86A0D273BEE> EQUALVERIFY CHECKSIG With the corresponding version 1 Bitcoin address being: - + 16UwLL9Risc3QfPqBUvKofHmBQ7wMtjvM - -When the same public key is encoded as P2WPKH, the scriptPubKey becomes: - + +When the same public key is encoded as P2WPKH, the scriptPubKey becomes: + OP_0 <010966776006953D5567439E5E39F86A0D273BEE> Using 0x06 as address version, followed by 0x00 as witness program version, and a 0x00 padding, the equivalent P2WPKH address is: - + p2xtZoXeX5X8BP8JfFhQK2nD3emtjch7UeFm - + == Reference implementation == https://github.com/theuni/bitcoin/commit/ede1b57058ac8efdefe61f67395affb48f2c0d80 diff --git a/bip-0143.mediawiki b/bip-0143.mediawiki index d7e514e0fb..3146b5ffd4 100644 --- a/bip-0143.mediawiki +++ b/bip-0143.mediawiki @@ -31,7 +31,7 @@ A new transaction digest algorithm is defined, but only applicable to sigops in 1. nVersion of the transaction (4-byte little endian) 2. hashPrevouts (32-byte hash) 3. hashSequence (32-byte hash) - 4. outpoint (32-byte hash + 4-byte little endian) + 4. outpoint (32-byte hash + 4-byte little endian) 5. scriptCode of the input (serialized as scripts inside CTxOuts) 6. value of the output spent by this input (8-byte little endian) 7. nSequence of the input (4-byte little endian) @@ -77,7 +77,7 @@ Refer to the reference implementation, reproduced below, for the precise algorit uint256 hashPrevouts; uint256 hashSequence; uint256 hashOutputs; - + if (!(nHashType & SIGHASH_ANYONECANPAY)) { CHashWriter ss(SER_GETHASH, 0); for (unsigned int n = 0; n < txTo.vin.size(); n++) { @@ -85,7 +85,7 @@ Refer to the reference implementation, reproduced below, for the precise algorit } hashPrevouts = ss.GetHash(); } - + if (!(nHashType & SIGHASH_ANYONECANPAY) && (nHashType & 0x1f) != SIGHASH_SINGLE && (nHashType & 0x1f) != SIGHASH_NONE) { CHashWriter ss(SER_GETHASH, 0); for (unsigned int n = 0; n < txTo.vin.size(); n++) { @@ -93,7 +93,7 @@ Refer to the reference implementation, reproduced below, for the precise algorit } hashSequence = ss.GetHash(); } - + if ((nHashType & 0x1f) != SIGHASH_SINGLE && (nHashType & 0x1f) != SIGHASH_NONE) { CHashWriter ss(SER_GETHASH, 0); for (unsigned int n = 0; n < txTo.vout.size(); n++) { @@ -105,7 +105,7 @@ Refer to the reference implementation, reproduced below, for the precise algorit ss << txTo.vout[nIn]; hashOutputs = ss.GetHash(); } - + CHashWriter ss(SER_GETHASH, 0); // Version ss << txTo.nVersion; @@ -125,7 +125,7 @@ Refer to the reference implementation, reproduced below, for the precise algorit ss << txTo.nLockTime; // Sighash type ss << nHashType; - + return ss.GetHash(); @@ -139,42 +139,42 @@ Since this policy is preparation for a future softfork proposal, to avoid potent To ensure consistency in consensus-critical behaviour, developers should test their implementations against all the tests below. More tests related to this proposal could be found under https://github.com/bitcoin/bitcoin/tree/master/src/test/data . === Native P2WPKH === - + The following is an unsigned transaction: 0100000002fff7f7881a8099afa6940d42d1e7f6362bec38171ea3edf433541db4e4ad969f0000000000eeffffffef51e1b804cc89d182d279655c3aa89e815b1b309fe287d9b2b55d57b90ec68a0100000000ffffffff02202cb206000000001976a9148280b37df378db99f66f85c95a783a76ac7a6d5988ac9093510d000000001976a9143bde42dbee7e4dbe6a21b2d50ce2f0167faa815988ac11000000 - + nVersion: 01000000 txin: 02 fff7f7881a8099afa6940d42d1e7f6362bec38171ea3edf433541db4e4ad969f 00000000 00 eeffffff ef51e1b804cc89d182d279655c3aa89e815b1b309fe287d9b2b55d57b90ec68a 01000000 00 ffffffff txout: 02 202cb20600000000 1976a9148280b37df378db99f66f85c95a783a76ac7a6d5988ac 9093510d00000000 1976a9143bde42dbee7e4dbe6a21b2d50ce2f0167faa815988ac nLockTime: 11000000 - + The first input comes from an ordinary P2PK: scriptPubKey : 2103c9f4836b9a4f77fc0d81f7bcb01b7f1b35916864b9476c241ce9fc198bd25432ac value: 6.25 private key : bbc27228ddcb9209d7fd6f36b02f7dfa6252af40bb2f1cbc7a557da8027ff866 - + The second input comes from a P2WPKH witness program: scriptPubKey : 00141d0f172a0ecb48aee1be1f2687d2963ae33f71a1, value: 6 private key : 619c335025c7f4012e556c2a58b2506e30b8511b53ade95ea316fd8c3286feb9 public key : 025476c2e83188368da1ff3e292e7acafcdb3566bb0ad253f62fc70f07aeee6357 - + To sign it with a nHashType of 1 (SIGHASH_ALL): - + hashPrevouts: dSHA256(fff7f7881a8099afa6940d42d1e7f6362bec38171ea3edf433541db4e4ad969f00000000ef51e1b804cc89d182d279655c3aa89e815b1b309fe287d9b2b55d57b90ec68a01000000) = 96b827c8483d4e9b96712b6713a7b68d6e8003a781feba36c31143470b4efd37 - + hashSequence: dSHA256(eeffffffffffffff) = 52b0a642eea2fb7ae638c36f6252b6750293dbe574a806984b8e4d8548339a3b - + hashOutputs: dSHA256(202cb206000000001976a9148280b37df378db99f66f85c95a783a76ac7a6d5988ac9093510d000000001976a9143bde42dbee7e4dbe6a21b2d50ce2f0167faa815988ac) = 863ef3e1a92afbfdb97f31ad0fc7683ee943e9abcf2501590ff8f6551f47e5e5 - + hash preimage: 0100000096b827c8483d4e9b96712b6713a7b68d6e8003a781feba36c31143470b4efd3752b0a642eea2fb7ae638c36f6252b6750293dbe574a806984b8e4d8548339a3bef51e1b804cc89d182d279655c3aa89e815b1b309fe287d9b2b55d57b90ec68a010000001976a9141d0f172a0ecb48aee1be1f2687d2963ae33f71a188ac0046c32300000000ffffffff863ef3e1a92afbfdb97f31ad0fc7683ee943e9abcf2501590ff8f6551f47e5e51100000001000000 - + nVersion: 01000000 hashPrevouts: 96b827c8483d4e9b96712b6713a7b68d6e8003a781feba36c31143470b4efd37 hashSequence: 52b0a642eea2fb7ae638c36f6252b6750293dbe574a806984b8e4d8548339a3b @@ -185,12 +185,12 @@ To ensure consistency in consensus-critical behaviour, developers should test th hashOutputs: 863ef3e1a92afbfdb97f31ad0fc7683ee943e9abcf2501590ff8f6551f47e5e5 nLockTime: 11000000 nHashType: 01000000 - + sigHash: c37af31116d1b27caf68aae9e3ac82f1477929014d5b917657d0eb49478cb670 signature: 304402203609e17b84f6a7d30c80bfa610b5b4542f32a8a0d5447a12fb1366d7f01cc44a0220573a954c4518331561406f90300e8f3358f51928d43c212a8caed02de67eebee01 - + The serialized signed transaction is: 01000000000102fff7f7881a8099afa6940d42d1e7f6362bec38171ea3edf433541db4e4ad969f00000000494830450221008b9d1dc26ba6a9cb62127b02742fa9d754cd3bebf337f7a55d114c8e5cdd30be022040529b194ba3f9281a99f2b1c0a19c0489bc22ede944ccf4ecbab4cc618ef3ed01eeffffffef51e1b804cc89d182d279655c3aa89e815b1b309fe287d9b2b55d57b90ec68a0100000000ffffffff02202cb206000000001976a9148280b37df378db99f66f85c95a783a76ac7a6d5988ac9093510d000000001976a9143bde42dbee7e4dbe6a21b2d50ce2f0167faa815988ac000247304402203609e17b84f6a7d30c80bfa610b5b4542f32a8a0d5447a12fb1366d7f01cc44a0220573a954c4518331561406f90300e8f3358f51928d43c212a8caed02de67eebee0121025476c2e83188368da1ff3e292e7acafcdb3566bb0ad253f62fc70f07aeee635711000000 - + nVersion: 01000000 marker: 00 flag: 01 @@ -203,38 +203,38 @@ To ensure consistency in consensus-critical behaviour, developers should test th nLockTime: 11000000 === P2SH-P2WPKH === - - + + The following is an unsigned transaction: 0100000001db6b1b20aa0fd7b23880be2ecbd4a98130974cf4748fb66092ac4d3ceb1a54770100000000feffffff02b8b4eb0b000000001976a914a457b684d7f0d539a46a45bbc043f35b59d0d96388ac0008af2f000000001976a914fd270b1ee6abcaea97fea7ad0402e8bd8ad6d77c88ac92040000 - + nVersion: 01000000 txin: 01 db6b1b20aa0fd7b23880be2ecbd4a98130974cf4748fb66092ac4d3ceb1a5477 01000000 00 feffffff txout: 02 b8b4eb0b00000000 1976a914a457b684d7f0d539a46a45bbc043f35b59d0d96388ac 0008af2f00000000 1976a914fd270b1ee6abcaea97fea7ad0402e8bd8ad6d77c88ac nLockTime: 92040000 - + The input comes from a P2SH-P2WPKH witness program: scriptPubKey : a9144733f37cf4db86fbc2efed2500b4f4e49f31202387, value: 10 redeemScript : 001479091972186c449eb1ded22b78e40d009bdf0089 private key : eb696a065ef48a2192da5b28b694f87544b30fae8327c4510137a922f32c6dcf public key : 03ad1d8e89212f0b92c74d23bb710c00662ad1470198ac48c43f7d6f93a2a26873 - + To sign it with a nHashType of 1 (SIGHASH_ALL): - + hashPrevouts: dSHA256(db6b1b20aa0fd7b23880be2ecbd4a98130974cf4748fb66092ac4d3ceb1a547701000000) = b0287b4a252ac05af83d2dcef00ba313af78a3e9c329afa216eb3aa2a7b4613a - + hashSequence: dSHA256(feffffff) = 18606b350cd8bf565266bc352f0caddcf01e8fa789dd8a15386327cf8cabe198 - + hashOutputs: dSHA256(b8b4eb0b000000001976a914a457b684d7f0d539a46a45bbc043f35b59d0d96388ac0008af2f000000001976a914fd270b1ee6abcaea97fea7ad0402e8bd8ad6d77c88ac) = de984f44532e2173ca0d64314fcefe6d30da6f8cf27bafa706da61df8a226c83 - + hash preimage: 01000000b0287b4a252ac05af83d2dcef00ba313af78a3e9c329afa216eb3aa2a7b4613a18606b350cd8bf565266bc352f0caddcf01e8fa789dd8a15386327cf8cabe198db6b1b20aa0fd7b23880be2ecbd4a98130974cf4748fb66092ac4d3ceb1a5477010000001976a91479091972186c449eb1ded22b78e40d009bdf008988ac00ca9a3b00000000feffffffde984f44532e2173ca0d64314fcefe6d30da6f8cf27bafa706da61df8a226c839204000001000000 - + nVersion: 01000000 hashPrevouts: b0287b4a252ac05af83d2dcef00ba313af78a3e9c329afa216eb3aa2a7b4613a hashSequence: 18606b350cd8bf565266bc352f0caddcf01e8fa789dd8a15386327cf8cabe198 @@ -245,10 +245,10 @@ To ensure consistency in consensus-critical behaviour, developers should test th hashOutputs: de984f44532e2173ca0d64314fcefe6d30da6f8cf27bafa706da61df8a226c83 nLockTime: 92040000 nHashType: 01000000 - + sigHash: 64f3b0f4dd2bb3aa1ce8566d220cc74dda9df97d8490cc81d89d735c92e59fb6 signature: 3044022047ac8e878352d3ebbde1c94ce3a10d057c24175747116f8288e5d794d12d482f0220217f36a485cae903c713331d877c1f64677e3622ad4010726870540656fe9dcb01 - + The serialized signed transaction is: 01000000000101db6b1b20aa0fd7b23880be2ecbd4a98130974cf4748fb66092ac4d3ceb1a5477010000001716001479091972186c449eb1ded22b78e40d009bdf0089feffffff02b8b4eb0b000000001976a914a457b684d7f0d539a46a45bbc043f35b59d0d96388ac0008af2f000000001976a914fd270b1ee6abcaea97fea7ad0402e8bd8ad6d77c88ac02473044022047ac8e878352d3ebbde1c94ce3a10d057c24175747116f8288e5d794d12d482f0220217f36a485cae903c713331d877c1f64677e3622ad4010726870540656fe9dcb012103ad1d8e89212f0b92c74d23bb710c00662ad1470198ac48c43f7d6f93a2a2687392040000 nVersion: 01000000 marker: 00 @@ -263,33 +263,33 @@ To ensure consistency in consensus-critical behaviour, developers should test th This example shows how OP_CODESEPARATOR and out-of-range SIGHASH_SINGLE are processed: - - + + The following is an unsigned transaction: 0100000002fe3dc9208094f3ffd12645477b3dc56f60ec4fa8e6f5d67c565d1c6b9216b36e0000000000ffffffff0815cf020f013ed6cf91d29f4202e8a58726b1ac6c79da47c23d1bee0a6925f80000000000ffffffff0100f2052a010000001976a914a30741f8145e5acadf23f751864167f32e0963f788ac00000000 - + nVersion: 01000000 txin: 02 fe3dc9208094f3ffd12645477b3dc56f60ec4fa8e6f5d67c565d1c6b9216b36e 00000000 00 ffffffff 0815cf020f013ed6cf91d29f4202e8a58726b1ac6c79da47c23d1bee0a6925f8 00000000 00 ffffffff txout: 01 00f2052a01000000 1976a914a30741f8145e5acadf23f751864167f32e0963f788ac nLockTime: 00000000 - + The first input comes from an ordinary P2PK: scriptPubKey: 21036d5c20fa14fb2f635474c1dc4ef5909d4568e5569b79fc94d3448486e14685f8ac value: 1.5625 private key: b8f28a772fccbf9b4f58a4f027e07dc2e35e7cd80529975e292ea34f84c4580c signature: 304402200af4e47c9b9629dbecc21f73af989bdaa911f7e6f6c2e9394588a3aa68f81e9902204f3fcf6ade7e5abb1295b6774c8e0abd94ae62217367096bc02ee5e435b67da201 (SIGHASH_ALL) - + The second input comes from a native P2WSH witness program: scriptPubKey : 00205d1b56b63d714eebe542309525f484b7e9d6f686b3781b6f61ef925d66d6f6a0, value: 49 witnessScript: 21026dccc749adc2a9d0d89497ac511f760f45c47dc5ed9cf352a58ac706453880aeadab210255a9626aebf5e29c0e6538428ba0d1dcf6ca98ffdf086aa8ced5e0d0215ea465ac <026dccc749adc2a9d0d89497ac511f760f45c47dc5ed9cf352a58ac706453880ae> CHECKSIGVERIFY CODESEPARATOR <0255a9626aebf5e29c0e6538428ba0d1dcf6ca98ffdf086aa8ced5e0d0215ea465> CHECKSIG - + To sign it with a nHashType of 3 (SIGHASH_SINGLE): - + hashPrevouts: dSHA256(fe3dc9208094f3ffd12645477b3dc56f60ec4fa8e6f5d67c565d1c6b9216b36e000000000815cf020f013ed6cf91d29f4202e8a58726b1ac6c79da47c23d1bee0a6925f800000000) = ef546acf4a020de3898d1b8956176bb507e6211b5ed3619cd08b6ea7e2a09d41 - + nVersion: 01000000 hashPrevouts: ef546acf4a020de3898d1b8956176bb507e6211b5ed3619cd08b6ea7e2a09d41 hashSequence: 0000000000000000000000000000000000000000000000000000000000000000 @@ -300,7 +300,7 @@ This example shows how OP_CODESEPARATOR and out-of-range SIGH hashOutputs: 0000000000000000000000000000000000000000000000000000000000000000 (this is the second input but there is only one output) nLockTime: 00000000 nHashType: 03000000 - + scriptCode: 4721026dccc749adc2a9d0d89497ac511f760f45c47dc5ed9cf352a58ac706453880aeadab210255a9626aebf5e29c0e6538428ba0d1dcf6ca98ffdf086aa8ced5e0d0215ea465ac ^^ (please note that the not-yet-executed OP_CODESEPARATOR is not removed from the scriptCode) @@ -309,7 +309,7 @@ This example shows how OP_CODESEPARATOR and out-of-range SIGH public key: 026dccc749adc2a9d0d89497ac511f760f45c47dc5ed9cf352a58ac706453880ae private key: 8e02b539b1500aa7c81cf3fed177448a546f19d2be416c0c61ff28e577d8d0cd signature: 3044022027dc95ad6b740fe5129e7e62a75dd00f291a2aeb1200b84b09d9e3789406b6c002201a9ecd315dd6a0e632ab20bbb98948bc0c6fb204f2c286963bb48517a7058e2703 - + scriptCode: 23210255a9626aebf5e29c0e6538428ba0d1dcf6ca98ffdf086aa8ced5e0d0215ea465ac (everything up to the last executed OP_CODESEPARATOR, including that OP_CODESEPARATOR, are removed) preimage: 01000000ef546acf4a020de3898d1b8956176bb507e6211b5ed3619cd08b6ea7e2a09d4100000000000000000000000000000000000000000000000000000000000000000815cf020f013ed6cf91d29f4202e8a58726b1ac6c79da47c23d1bee0a6925f80000000023210255a9626aebf5e29c0e6538428ba0d1dcf6ca98ffdf086aa8ced5e0d0215ea465ac0011102401000000ffffffff00000000000000000000000000000000000000000000000000000000000000000000000003000000 @@ -317,36 +317,36 @@ This example shows how OP_CODESEPARATOR and out-of-range SIGH public key: 0255a9626aebf5e29c0e6538428ba0d1dcf6ca98ffdf086aa8ced5e0d0215ea465 private key: 86bf2ed75935a0cbef03b89d72034bb4c189d381037a5ac121a70016db8896ec signature: 304402200de66acf4527789bfda55fc5459e214fa6083f936b430a762c629656216805ac0220396f550692cd347171cbc1ef1f51e15282e837bb2b30860dc77c8f78bc8501e503 - + The serialized signed transaction is: 01000000000102fe3dc9208094f3ffd12645477b3dc56f60ec4fa8e6f5d67c565d1c6b9216b36e000000004847304402200af4e47c9b9629dbecc21f73af989bdaa911f7e6f6c2e9394588a3aa68f81e9902204f3fcf6ade7e5abb1295b6774c8e0abd94ae62217367096bc02ee5e435b67da201ffffffff0815cf020f013ed6cf91d29f4202e8a58726b1ac6c79da47c23d1bee0a6925f80000000000ffffffff0100f2052a010000001976a914a30741f8145e5acadf23f751864167f32e0963f788ac000347304402200de66acf4527789bfda55fc5459e214fa6083f936b430a762c629656216805ac0220396f550692cd347171cbc1ef1f51e15282e837bb2b30860dc77c8f78bc8501e503473044022027dc95ad6b740fe5129e7e62a75dd00f291a2aeb1200b84b09d9e3789406b6c002201a9ecd315dd6a0e632ab20bbb98948bc0c6fb204f2c286963bb48517a7058e27034721026dccc749adc2a9d0d89497ac511f760f45c47dc5ed9cf352a58ac706453880aeadab210255a9626aebf5e29c0e6538428ba0d1dcf6ca98ffdf086aa8ced5e0d0215ea465ac00000000 This example shows how unexecuted OP_CODESEPARATOR is processed, and SINGLE|ANYONECANPAY does not commit to the input index: - - + + The following is an unsigned transaction: 0100000002e9b542c5176808107ff1df906f46bb1f2583b16112b95ee5380665ba7fcfc0010000000000ffffffff80e68831516392fcd100d186b3c2c7b95c80b53c77e77c35ba03a66b429a2a1b0000000000ffffffff0280969800000000001976a914de4b231626ef508c9a74a8517e6783c0546d6b2888ac80969800000000001976a9146648a8cd4531e1ec47f35916de8e259237294d1e88ac00000000 - + nVersion: 01000000 txin: 02 e9b542c5176808107ff1df906f46bb1f2583b16112b95ee5380665ba7fcfc001 00000000 00 ffffffff 80e68831516392fcd100d186b3c2c7b95c80b53c77e77c35ba03a66b429a2a1b 00000000 00 ffffffff txout: 02 8096980000000000 1976a914de4b231626ef508c9a74a8517e6783c0546d6b2888ac 8096980000000000 1976a9146648a8cd4531e1ec47f35916de8e259237294d1e88ac nLockTime: 00000000 - + The first input comes from a native P2WSH witness program: scriptPubKey: 0020ba468eea561b26301e4cf69fa34bde4ad60c81e70f059f045ca9a79931004a4d value: 0.16777215 witnessScript:0063ab68210392972e2eb617b2388771abe27235fd5ac44af8e61693261550447a4c3e39da98ac 0 IF CODESEPARATOR ENDIF <0392972e2eb617b2388771abe27235fd5ac44af8e61693261550447a4c3e39da98> CHECKSIG - + The second input comes from a native P2WSH witness program: scriptPubKey: 0020d9bbfbe56af7c4b7f960a70d7ea107156913d9e5a26b0a71429df5e097ca6537 value: 0.16777215 witnessScript:5163ab68210392972e2eb617b2388771abe27235fd5ac44af8e61693261550447a4c3e39da98ac 1 IF CODESEPARATOR ENDIF <0392972e2eb617b2388771abe27235fd5ac44af8e61693261550447a4c3e39da98> CHECKSIG - + To sign it with a nHashType of 0x83 (SINGLE|ANYONECANPAY): - + nVersion: 01000000 hashPrevouts: 0000000000000000000000000000000000000000000000000000000000000000 hashSequence: 0000000000000000000000000000000000000000000000000000000000000000 @@ -357,7 +357,7 @@ This example shows how unexecuted OP_CODESEPARATOR is processed, an hashOutputs: (see below) nLockTime: 00000000 nHashType: 83000000 - + outpoint: e9b542c5176808107ff1df906f46bb1f2583b16112b95ee5380665ba7fcfc00100000000 scriptCode: 270063ab68210392972e2eb617b2388771abe27235fd5ac44af8e61693261550447a4c3e39da98ac (since the OP_CODESEPARATOR is not executed, nothing is removed from the scriptCode) @@ -367,7 +367,7 @@ This example shows how unexecuted OP_CODESEPARATOR is processed, an public key: 0392972e2eb617b2388771abe27235fd5ac44af8e61693261550447a4c3e39da98 private key: f52b3484edd96598e02a9c89c4492e9c1e2031f471c49fd721fe68b3ce37780d signature: 3045022100f6a10b8604e6dc910194b79ccfc93e1bc0ec7c03453caaa8987f7d6c3413566002206216229ede9b4d6ec2d325be245c5b508ff0339bf1794078e20bfe0babc7ffe683 - + outpoint: 80e68831516392fcd100d186b3c2c7b95c80b53c77e77c35ba03a66b429a2a1b00000000 scriptCode: 2468210392972e2eb617b2388771abe27235fd5ac44af8e61693261550447a4c3e39da98ac (everything up to the last executed OP_CODESEPARATOR, including that OP_CODESEPARATOR, are removed) @@ -377,7 +377,7 @@ This example shows how unexecuted OP_CODESEPARATOR is processed, an public key: 0392972e2eb617b2388771abe27235fd5ac44af8e61693261550447a4c3e39da98 private key: f52b3484edd96598e02a9c89c4492e9c1e2031f471c49fd721fe68b3ce37780d signature: 30440220032521802a76ad7bf74d0e2c218b72cf0cbc867066e2e53db905ba37f130397e02207709e2188ed7f08f4c952d9d13986da504502b8c3be59617e043552f506c46ff83 - + The serialized signed transaction is: 01000000000102e9b542c5176808107ff1df906f46bb1f2583b16112b95ee5380665ba7fcfc0010000000000ffffffff80e68831516392fcd100d186b3c2c7b95c80b53c77e77c35ba03a66b429a2a1b0000000000ffffffff0280969800000000001976a914de4b231626ef508c9a74a8517e6783c0546d6b2888ac80969800000000001976a9146648a8cd4531e1ec47f35916de8e259237294d1e88ac02483045022100f6a10b8604e6dc910194b79ccfc93e1bc0ec7c03453caaa8987f7d6c3413566002206216229ede9b4d6ec2d325be245c5b508ff0339bf1794078e20bfe0babc7ffe683270063ab68210392972e2eb617b2388771abe27235fd5ac44af8e61693261550447a4c3e39da98ac024730440220032521802a76ad7bf74d0e2c218b72cf0cbc867066e2e53db905ba37f130397e02207709e2188ed7f08f4c952d9d13986da504502b8c3be59617e043552f506c46ff83275163ab68210392972e2eb617b2388771abe27235fd5ac44af8e61693261550447a4c3e39da98ac00000000 nVersion: 01000000 @@ -390,7 +390,7 @@ This example shows how unexecuted OP_CODESEPARATOR is processed, an witness 02 483045022100f6a10b8604e6dc910194b79ccfc93e1bc0ec7c03453caaa8987f7d6c3413566002206216229ede9b4d6ec2d325be245c5b508ff0339bf1794078e20bfe0babc7ffe683 270063ab68210392972e2eb617b2388771abe27235fd5ac44af8e61693261550447a4c3e39da98ac 02 4730440220032521802a76ad7bf74d0e2c218b72cf0cbc867066e2e53db905ba37f130397e02207709e2188ed7f08f4c952d9d13986da504502b8c3be59617e043552f506c46ff83 275163ab68210392972e2eb617b2388771abe27235fd5ac44af8e61693261550447a4c3e39da98ac nLockTime: 00000000 - + Since SINGLE|ANYONECANPAY does not commit to the input index, the signatures are still valid when the input-output pairs are swapped: 0100000000010280e68831516392fcd100d186b3c2c7b95c80b53c77e77c35ba03a66b429a2a1b0000000000ffffffffe9b542c5176808107ff1df906f46bb1f2583b16112b95ee5380665ba7fcfc0010000000000ffffffff0280969800000000001976a9146648a8cd4531e1ec47f35916de8e259237294d1e88ac80969800000000001976a914de4b231626ef508c9a74a8517e6783c0546d6b2888ac024730440220032521802a76ad7bf74d0e2c218b72cf0cbc867066e2e53db905ba37f130397e02207709e2188ed7f08f4c952d9d13986da504502b8c3be59617e043552f506c46ff83275163ab68210392972e2eb617b2388771abe27235fd5ac44af8e61693261550447a4c3e39da98ac02483045022100f6a10b8604e6dc910194b79ccfc93e1bc0ec7c03453caaa8987f7d6c3413566002206216229ede9b4d6ec2d325be245c5b508ff0339bf1794078e20bfe0babc7ffe683270063ab68210392972e2eb617b2388771abe27235fd5ac44af8e61693261550447a4c3e39da98ac00000000 nVersion: 01000000 @@ -408,37 +408,37 @@ This example shows how unexecuted OP_CODESEPARATOR is processed, an This example is a P2SH-P2WSH 6-of-6 multisig witness program signed with 6 different SIGHASH types. - - + + The following is an unsigned transaction: 010000000136641869ca081e70f394c6948e8af409e18b619df2ed74aa106c1ca29787b96e0100000000ffffffff0200e9a435000000001976a914389ffce9cd9ae88dcc0631e88a821ffdbe9bfe2688acc0832f05000000001976a9147480a33f950689af511e6e84c138dbbd3c3ee41588ac00000000 - + nVersion: 01000000 txin: 01 36641869ca081e70f394c6948e8af409e18b619df2ed74aa106c1ca29787b96e 01000000 00 ffffffff txout: 02 00e9a43500000000 1976a914389ffce9cd9ae88dcc0631e88a821ffdbe9bfe2688ac c0832f0500000000 1976a9147480a33f950689af511e6e84c138dbbd3c3ee41588ac nLockTime: 00000000 - + The input comes from a P2SH-P2WSH 6-of-6 multisig witness program: scriptPubKey : a9149993a429037b5d912407a71c252019287b8d27a587, value: 9.87654321 redeemScript : 0020a16b5755f7f6f96dbd65f5f0d6ab9418b89af4b1f14a1bb8a09062c35f0dcb54 witnessScript: 56210307b8ae49ac90a048e9b53357a2354b3334e9c8bee813ecb98e99a7e07e8c3ba32103b28f0c28bfab54554ae8c658ac5c3e0ce6e79ad336331f78c428dd43eea8449b21034b8113d703413d57761b8b9781957b8c0ac1dfe69f492580ca4195f50376ba4a21033400f6afecb833092a9a21cfdf1ed1376e58c5d1f47de74683123987e967a8f42103a6d48b1131e94ba04d9737d61acdaa1322008af9602b3b14862c07a1789aac162102d8b661b0b3302ee2f162b09e07a55ad5dfbe673a9f01d9f0c19617681024306b56ae - + hashPrevouts: dSHA256(36641869ca081e70f394c6948e8af409e18b619df2ed74aa106c1ca29787b96e01000000) = 74afdc312af5183c4198a40ca3c1a275b485496dd3929bca388c4b5e31f7aaa0 - + hashSequence: dSHA256(ffffffff) = 3bb13029ce7b1f559ef5e747fcac439f1455a2ec7c5f09b72290795e70665044 - + hashOutputs for ALL: dSHA256(00e9a435000000001976a914389ffce9cd9ae88dcc0631e88a821ffdbe9bfe2688acc0832f05000000001976a9147480a33f950689af511e6e84c138dbbd3c3ee41588ac) = bc4d309071414bed932f98832b27b4d76dad7e6c1346f487a8fdbb8eb90307cc - + hashOutputs for SINGLE: dSHA256(00e9a435000000001976a914389ffce9cd9ae88dcc0631e88a821ffdbe9bfe2688ac) = 9efe0c13a6b16c14a41b04ebe6a63f419bdacb2f8705b494a43063ca3cd4f708 - + hash preimage for ALL: 0100000074afdc312af5183c4198a40ca3c1a275b485496dd3929bca388c4b5e31f7aaa03bb13029ce7b1f559ef5e747fcac439f1455a2ec7c5f09b72290795e7066504436641869ca081e70f394c6948e8af409e18b619df2ed74aa106c1ca29787b96e01000000cf56210307b8ae49ac90a048e9b53357a2354b3334e9c8bee813ecb98e99a7e07e8c3ba32103b28f0c28bfab54554ae8c658ac5c3e0ce6e79ad336331f78c428dd43eea8449b21034b8113d703413d57761b8b9781957b8c0ac1dfe69f492580ca4195f50376ba4a21033400f6afecb833092a9a21cfdf1ed1376e58c5d1f47de74683123987e967a8f42103a6d48b1131e94ba04d9737d61acdaa1322008af9602b3b14862c07a1789aac162102d8b661b0b3302ee2f162b09e07a55ad5dfbe673a9f01d9f0c19617681024306b56aeb168de3a00000000ffffffffbc4d309071414bed932f98832b27b4d76dad7e6c1346f487a8fdbb8eb90307cc0000000001000000 nVersion: 01000000 hashPrevouts: 74afdc312af5183c4198a40ca3c1a275b485496dd3929bca388c4b5e31f7aaa0 @@ -454,7 +454,7 @@ This example is a P2SH-P2WSH 6-of-6 multisig witness program signed with 6 diffe public key: 0307b8ae49ac90a048e9b53357a2354b3334e9c8bee813ecb98e99a7e07e8c3ba3 private key: 730fff80e1413068a05b57d6a58261f07551163369787f349438ea38ca80fac6 signature: 304402206ac44d672dac41f9b00e28f4df20c52eeb087207e8d758d76d92c6fab3b73e2b0220367750dbbe19290069cba53d096f44530e4f98acaa594810388cf7409a1870ce01 - + hash preimage for NONE: 0100000074afdc312af5183c4198a40ca3c1a275b485496dd3929bca388c4b5e31f7aaa0000000000000000000000000000000000000000000000000000000000000000036641869ca081e70f394c6948e8af409e18b619df2ed74aa106c1ca29787b96e01000000cf56210307b8ae49ac90a048e9b53357a2354b3334e9c8bee813ecb98e99a7e07e8c3ba32103b28f0c28bfab54554ae8c658ac5c3e0ce6e79ad336331f78c428dd43eea8449b21034b8113d703413d57761b8b9781957b8c0ac1dfe69f492580ca4195f50376ba4a21033400f6afecb833092a9a21cfdf1ed1376e58c5d1f47de74683123987e967a8f42103a6d48b1131e94ba04d9737d61acdaa1322008af9602b3b14862c07a1789aac162102d8b661b0b3302ee2f162b09e07a55ad5dfbe673a9f01d9f0c19617681024306b56aeb168de3a00000000ffffffff00000000000000000000000000000000000000000000000000000000000000000000000002000000 nVersion: 01000000 hashPrevouts: 74afdc312af5183c4198a40ca3c1a275b485496dd3929bca388c4b5e31f7aaa0 @@ -470,7 +470,7 @@ This example is a P2SH-P2WSH 6-of-6 multisig witness program signed with 6 diffe public key: 03b28f0c28bfab54554ae8c658ac5c3e0ce6e79ad336331f78c428dd43eea8449b private key: 11fa3d25a17cbc22b29c44a484ba552b5a53149d106d3d853e22fdd05a2d8bb3 signature: 3044022068c7946a43232757cbdf9176f009a928e1cd9a1a8c212f15c1e11ac9f2925d9002205b75f937ff2f9f3c1246e547e54f62e027f64eefa2695578cc6432cdabce271502 - + hash preimage for SINGLE: 0100000074afdc312af5183c4198a40ca3c1a275b485496dd3929bca388c4b5e31f7aaa0000000000000000000000000000000000000000000000000000000000000000036641869ca081e70f394c6948e8af409e18b619df2ed74aa106c1ca29787b96e01000000cf56210307b8ae49ac90a048e9b53357a2354b3334e9c8bee813ecb98e99a7e07e8c3ba32103b28f0c28bfab54554ae8c658ac5c3e0ce6e79ad336331f78c428dd43eea8449b21034b8113d703413d57761b8b9781957b8c0ac1dfe69f492580ca4195f50376ba4a21033400f6afecb833092a9a21cfdf1ed1376e58c5d1f47de74683123987e967a8f42103a6d48b1131e94ba04d9737d61acdaa1322008af9602b3b14862c07a1789aac162102d8b661b0b3302ee2f162b09e07a55ad5dfbe673a9f01d9f0c19617681024306b56aeb168de3a00000000ffffffff9efe0c13a6b16c14a41b04ebe6a63f419bdacb2f8705b494a43063ca3cd4f7080000000003000000 nVersion: 01000000 hashPrevouts: 74afdc312af5183c4198a40ca3c1a275b485496dd3929bca388c4b5e31f7aaa0 @@ -486,7 +486,7 @@ This example is a P2SH-P2WSH 6-of-6 multisig witness program signed with 6 diffe public key: 034b8113d703413d57761b8b9781957b8c0ac1dfe69f492580ca4195f50376ba4a private key: 77bf4141a87d55bdd7f3cd0bdccf6e9e642935fec45f2f30047be7b799120661 signature: 3044022059ebf56d98010a932cf8ecfec54c48e6139ed6adb0728c09cbe1e4fa0915302e022007cd986c8fa870ff5d2b3a89139c9fe7e499259875357e20fcbb15571c76795403 - + hash preimage for ALL|ANYONECANPAY: 010000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000036641869ca081e70f394c6948e8af409e18b619df2ed74aa106c1ca29787b96e01000000cf56210307b8ae49ac90a048e9b53357a2354b3334e9c8bee813ecb98e99a7e07e8c3ba32103b28f0c28bfab54554ae8c658ac5c3e0ce6e79ad336331f78c428dd43eea8449b21034b8113d703413d57761b8b9781957b8c0ac1dfe69f492580ca4195f50376ba4a21033400f6afecb833092a9a21cfdf1ed1376e58c5d1f47de74683123987e967a8f42103a6d48b1131e94ba04d9737d61acdaa1322008af9602b3b14862c07a1789aac162102d8b661b0b3302ee2f162b09e07a55ad5dfbe673a9f01d9f0c19617681024306b56aeb168de3a00000000ffffffffbc4d309071414bed932f98832b27b4d76dad7e6c1346f487a8fdbb8eb90307cc0000000081000000 nVersion: 01000000 hashPrevouts: 0000000000000000000000000000000000000000000000000000000000000000 @@ -502,7 +502,7 @@ This example is a P2SH-P2WSH 6-of-6 multisig witness program signed with 6 diffe public key: 033400f6afecb833092a9a21cfdf1ed1376e58c5d1f47de74683123987e967a8f4 private key: 14af36970f5025ea3e8b5542c0f8ebe7763e674838d08808896b63c3351ffe49 signature: 3045022100fbefd94bd0a488d50b79102b5dad4ab6ced30c4069f1eaa69a4b5a763414067e02203156c6a5c9cf88f91265f5a942e96213afae16d83321c8b31bb342142a14d16381 - + hash preimage for NONE|ANYONECANPAY: 010000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000036641869ca081e70f394c6948e8af409e18b619df2ed74aa106c1ca29787b96e01000000cf56210307b8ae49ac90a048e9b53357a2354b3334e9c8bee813ecb98e99a7e07e8c3ba32103b28f0c28bfab54554ae8c658ac5c3e0ce6e79ad336331f78c428dd43eea8449b21034b8113d703413d57761b8b9781957b8c0ac1dfe69f492580ca4195f50376ba4a21033400f6afecb833092a9a21cfdf1ed1376e58c5d1f47de74683123987e967a8f42103a6d48b1131e94ba04d9737d61acdaa1322008af9602b3b14862c07a1789aac162102d8b661b0b3302ee2f162b09e07a55ad5dfbe673a9f01d9f0c19617681024306b56aeb168de3a00000000ffffffff00000000000000000000000000000000000000000000000000000000000000000000000082000000 nVersion: 01000000 hashPrevouts: 0000000000000000000000000000000000000000000000000000000000000000 @@ -518,7 +518,7 @@ This example is a P2SH-P2WSH 6-of-6 multisig witness program signed with 6 diffe public key: 03a6d48b1131e94ba04d9737d61acdaa1322008af9602b3b14862c07a1789aac16 private key: fe9a95c19eef81dde2b95c1284ef39be497d128e2aa46916fb02d552485e0323 signature: 3045022100a5263ea0553ba89221984bd7f0b13613db16e7a70c549a86de0cc0444141a407022005c360ef0ae5a5d4f9f2f87a56c1546cc8268cab08c73501d6b3be2e1e1a8a0882 - + hash preimage for SINGLE|ANYONECANPAY: 010000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000036641869ca081e70f394c6948e8af409e18b619df2ed74aa106c1ca29787b96e01000000cf56210307b8ae49ac90a048e9b53357a2354b3334e9c8bee813ecb98e99a7e07e8c3ba32103b28f0c28bfab54554ae8c658ac5c3e0ce6e79ad336331f78c428dd43eea8449b21034b8113d703413d57761b8b9781957b8c0ac1dfe69f492580ca4195f50376ba4a21033400f6afecb833092a9a21cfdf1ed1376e58c5d1f47de74683123987e967a8f42103a6d48b1131e94ba04d9737d61acdaa1322008af9602b3b14862c07a1789aac162102d8b661b0b3302ee2f162b09e07a55ad5dfbe673a9f01d9f0c19617681024306b56aeb168de3a00000000ffffffff9efe0c13a6b16c14a41b04ebe6a63f419bdacb2f8705b494a43063ca3cd4f7080000000083000000 nVersion: 01000000 hashPrevouts: 0000000000000000000000000000000000000000000000000000000000000000 @@ -534,7 +534,7 @@ This example is a P2SH-P2WSH 6-of-6 multisig witness program signed with 6 diffe public key: 02d8b661b0b3302ee2f162b09e07a55ad5dfbe673a9f01d9f0c19617681024306b private key: 428a7aee9f0c2af0cd19af3cf1c78149951ea528726989b2e83e4778d2c3f890 signature: 30440220525406a1482936d5a21888260dc165497a90a15669636d8edca6b9fe490d309c022032af0c646a34a44d1f4576bf6a4a74b67940f8faa84c7df9abe12a01a11e2b4783 - + The serialized signed transaction is: 0100000000010136641869ca081e70f394c6948e8af409e18b619df2ed74aa106c1ca29787b96e0100000023220020a16b5755f7f6f96dbd65f5f0d6ab9418b89af4b1f14a1bb8a09062c35f0dcb54ffffffff0200e9a435000000001976a914389ffce9cd9ae88dcc0631e88a821ffdbe9bfe2688acc0832f05000000001976a9147480a33f950689af511e6e84c138dbbd3c3ee41588ac080047304402206ac44d672dac41f9b00e28f4df20c52eeb087207e8d758d76d92c6fab3b73e2b0220367750dbbe19290069cba53d096f44530e4f98acaa594810388cf7409a1870ce01473044022068c7946a43232757cbdf9176f009a928e1cd9a1a8c212f15c1e11ac9f2925d9002205b75f937ff2f9f3c1246e547e54f62e027f64eefa2695578cc6432cdabce271502473044022059ebf56d98010a932cf8ecfec54c48e6139ed6adb0728c09cbe1e4fa0915302e022007cd986c8fa870ff5d2b3a89139c9fe7e499259875357e20fcbb15571c76795403483045022100fbefd94bd0a488d50b79102b5dad4ab6ced30c4069f1eaa69a4b5a763414067e02203156c6a5c9cf88f91265f5a942e96213afae16d83321c8b31bb342142a14d16381483045022100a5263ea0553ba89221984bd7f0b13613db16e7a70c549a86de0cc0444141a407022005c360ef0ae5a5d4f9f2f87a56c1546cc8268cab08c73501d6b3be2e1e1a8a08824730440220525406a1482936d5a21888260dc165497a90a15669636d8edca6b9fe490d309c022032af0c646a34a44d1f4576bf6a4a74b67940f8faa84c7df9abe12a01a11e2b4783cf56210307b8ae49ac90a048e9b53357a2354b3334e9c8bee813ecb98e99a7e07e8c3ba32103b28f0c28bfab54554ae8c658ac5c3e0ce6e79ad336331f78c428dd43eea8449b21034b8113d703413d57761b8b9781957b8c0ac1dfe69f492580ca4195f50376ba4a21033400f6afecb833092a9a21cfdf1ed1376e58c5d1f47de74683123987e967a8f42103a6d48b1131e94ba04d9737d61acdaa1322008af9602b3b14862c07a1789aac162102d8b661b0b3302ee2f162b09e07a55ad5dfbe673a9f01d9f0c19617681024306b56ae00000000 @@ -542,35 +542,35 @@ This example is a P2SH-P2WSH 6-of-6 multisig witness program signed with 6 diffe These examples show that FindAndDelete for the signature is not applied. The transactions are generated in an unconventional way. Instead of signing using a private key, the signatures are pre-determined as part of witnessScript. The public keys are generated with key recovery, using the fixed signatures and the sighash defined in this proposal. Therefore, the private keys are unknown. - + The following is an unsigned transaction: 010000000169c12106097dc2e0526493ef67f21269fe888ef05c7a3a5dacab38e1ac8387f14c1d000000ffffffff0101000000000000000000000000 - + nVersion: 01000000 txin: 01 69c12106097dc2e0526493ef67f21269fe888ef05c7a3a5dacab38e1ac8387f1 4c1d0000 00 ffffffff txout: 01 0100000000000000 00 nLockTime: 00000000 - + The input comes from a P2WSH witness program: scriptPubKey : 00209e1be07558ea5cc8e02ed1d80c0911048afad949affa36d5c3951e3159dbea19, value: 0.00200000 redeemScript : OP_CHECKSIGVERIFY <0x30450220487fb382c4974de3f7d834c1b617fe15860828c7f96454490edd6d891556dcc9022100baf95feb48f845d5bfc9882eb6aeefa1bc3790e39f59eaa46ff7f15ae626c53e01> ad4830450220487fb382c4974de3f7d834c1b617fe15860828c7f96454490edd6d891556dcc9022100baf95feb48f845d5bfc9882eb6aeefa1bc3790e39f59eaa46ff7f15ae626c53e01 - + To sign it with a nHashType of 1 (SIGHASH_ALL): - + hashPrevouts: dSHA256(69c12106097dc2e0526493ef67f21269fe888ef05c7a3a5dacab38e1ac8387f14c1d0000) = b67c76d200c6ce72962d919dc107884b9d5d0e26f2aea7474b46a1904c53359f - + hashSequence: dSHA256(ffffffff) = 3bb13029ce7b1f559ef5e747fcac439f1455a2ec7c5f09b72290795e70665044 - + hashOutputs: dSHA256(010000000000000000) = e5d196bfb21caca9dbd654cafb3b4dc0c4882c8927d2eb300d9539dd0b934228 - + hash preimage: 01000000b67c76d200c6ce72962d919dc107884b9d5d0e26f2aea7474b46a1904c53359f3bb13029ce7b1f559ef5e747fcac439f1455a2ec7c5f09b72290795e7066504469c12106097dc2e0526493ef67f21269fe888ef05c7a3a5dacab38e1ac8387f14c1d00004aad4830450220487fb382c4974de3f7d834c1b617fe15860828c7f96454490edd6d891556dcc9022100baf95feb48f845d5bfc9882eb6aeefa1bc3790e39f59eaa46ff7f15ae626c53e01400d030000000000ffffffffe5d196bfb21caca9dbd654cafb3b4dc0c4882c8927d2eb300d9539dd0b9342280000000001000000 - + nVersion: 01000000 hashPrevouts: b67c76d200c6ce72962d919dc107884b9d5d0e26f2aea7474b46a1904c53359f hashSequence: 3bb13029ce7b1f559ef5e747fcac439f1455a2ec7c5f09b72290795e70665044 @@ -581,11 +581,11 @@ These examples show that FindAndDelete for the signature is not app hashOutputs: e5d196bfb21caca9dbd654cafb3b4dc0c4882c8927d2eb300d9539dd0b934228 nLockTime: 00000000 nHashType: 01000000 - + sigHash: 71c9cd9b2869b9c70b01b1f0360c148f42dee72297db312638df136f43311f23 signature: 30450220487fb382c4974de3f7d834c1b617fe15860828c7f96454490edd6d891556dcc9022100baf95feb48f845d5bfc9882eb6aeefa1bc3790e39f59eaa46ff7f15ae626c53e 01 pubkey: 02a9781d66b61fb5a7ef00ac5ad5bc6ffc78be7b44a566e3c87870e1079368df4c - + The serialized signed transaction is: 0100000000010169c12106097dc2e0526493ef67f21269fe888ef05c7a3a5dacab38e1ac8387f14c1d000000ffffffff01010000000000000000034830450220487fb382c4974de3f7d834c1b617fe15860828c7f96454490edd6d891556dcc9022100baf95feb48f845d5bfc9882eb6aeefa1bc3790e39f59eaa46ff7f15ae626c53e012102a9781d66b61fb5a7ef00ac5ad5bc6ffc78be7b44a566e3c87870e1079368df4c4aad4830450220487fb382c4974de3f7d834c1b617fe15860828c7f96454490edd6d891556dcc9022100baf95feb48f845d5bfc9882eb6aeefa1bc3790e39f59eaa46ff7f15ae626c53e0100000000 nVersion: 01000000 @@ -597,11 +597,11 @@ These examples show that FindAndDelete for the signature is not app 2102a9781d66b61fb5a7ef00ac5ad5bc6ffc78be7b44a566e3c87870e1079368df4c 4aad4830450220487fb382c4974de3f7d834c1b617fe15860828c7f96454490edd6d891556dcc9022100baf95feb48f845d5bfc9882eb6aeefa1bc3790e39f59eaa46ff7f15ae626c53e01 nLockTime: 00000000 - - + + The following transaction is a OP_CHECKMULTISIGVERIFY version of the FindAndDelete examples: 010000000001019275cb8d4a485ce95741c013f7c0d28722160008021bb469a11982d47a6628964c1d000000ffffffff0101000000000000000007004830450220487fb382c4974de3f7d834c1b617fe15860828c7f96454490edd6d891556dcc9022100baf95feb48f845d5bfc9882eb6aeefa1bc3790e39f59eaa46ff7f15ae626c53e0148304502205286f726690b2e9b0207f0345711e63fa7012045b9eb0f19c2458ce1db90cf43022100e89f17f86abc5b149eba4115d4f128bcf45d77fb3ecdd34f594091340c0395960101022102966f109c54e85d3aee8321301136cedeb9fc710fdef58a9de8a73942f8e567c021034ffc99dd9a79dd3cb31e2ab3e0b09e0e67db41ac068c625cd1f491576016c84e9552af4830450220487fb382c4974de3f7d834c1b617fe15860828c7f96454490edd6d891556dcc9022100baf95feb48f845d5bfc9882eb6aeefa1bc3790e39f59eaa46ff7f15ae626c53e0148304502205286f726690b2e9b0207f0345711e63fa7012045b9eb0f19c2458ce1db90cf43022100e89f17f86abc5b149eba4115d4f128bcf45d77fb3ecdd34f594091340c039596017500000000 - + redeemScript: OP_2 OP_CHECKMULTISIGVERIFY <30450220487fb382c4974de3f7d834c1b617fe15860828c7f96454490edd6d891556dcc9022100baf95feb48f845d5bfc9882eb6aeefa1bc3790e39f59eaa46ff7f15ae626c53e01> <304502205286f726690b2e9b0207f0345711e63fa7012045b9eb0f19c2458ce1db90cf43022100e89f17f86abc5b149eba4115d4f128bcf45d77fb3ecdd34f594091340c03959601> hash preimage: 0100000039283953eb1e26994dde57b7f9362a79a8c523e2f8deba943c27e826a005f1e63bb13029ce7b1f559ef5e747fcac439f1455a2ec7c5f09b72290795e706650449275cb8d4a485ce95741c013f7c0d28722160008021bb469a11982d47a6628964c1d00009552af4830450220487fb382c4974de3f7d834c1b617fe15860828c7f96454490edd6d891556dcc9022100baf95feb48f845d5bfc9882eb6aeefa1bc3790e39f59eaa46ff7f15ae626c53e0148304502205286f726690b2e9b0207f0345711e63fa7012045b9eb0f19c2458ce1db90cf43022100e89f17f86abc5b149eba4115d4f128bcf45d77fb3ecdd34f594091340c0395960175400d030000000000ffffffffe5d196bfb21caca9dbd654cafb3b4dc0c4882c8927d2eb300d9539dd0b9342280000000001000000 sighash: c1628a1e7c67f14ca0c27c06e4fdeec2e6d1a73c7a91d7c046ff83e835aebb72 @@ -618,7 +618,7 @@ The new serialization format is described in BIP144 [[bip-0144.mediawiki|BI == Deployment == -This proposal is deployed with Segregated Witness softfork (BIP 141) +This proposal is deployed with Segregated Witness softfork (BIP 141) == Backward compatibility == diff --git a/bip-0144.mediawiki b/bip-0144.mediawiki index 8ec2191c82..56e075a40f 100644 --- a/bip-0144.mediawiki +++ b/bip-0144.mediawiki @@ -79,7 +79,7 @@ The serialization has the following structure: Parsers supporting this BIP will be able to distinguish between the old serialization format (without the witness) and this one. The marker byte is set to zero so that this structure will never parse as a valid transaction in a parser that does not support this BIP. If parsing were to succeed, such a transaction would contain no inputs and a single output. -If the witness is empty, the old serialization format must be used. +If the witness is empty, the old serialization format must be used. Currently, the only witness objects type supported are script witnesses which consist of a stack of byte arrays. It is encoded as a var_int item count followed by each item encoded as a var_int length followed by a string of bytes. Each txin has its own script witness. The number of script witnesses is not explicitly encoded as it is implied by txin_count. Empty script witnesses are encoded as a zero byte. The order of the script witnesses follows the same order as the associated txins. diff --git a/bip-0154.mediawiki b/bip-0154.mediawiki index c1e4cdb5d4..cf8f9562db 100644 --- a/bip-0154.mediawiki +++ b/bip-0154.mediawiki @@ -71,7 +71,7 @@ solve the challenge and reconnect, or discard it and find a different peer (or w There are two POW identifiers currently. When a new identifier is introduced, it should be added with an increment of 1 to the last identifier in the list. When an identifier is deprecated, its status should be changed to Deprecated but it should -retain its place in the list indefinitely. +retain its place in the list indefinitely. {|class="wikitable" ! ID !! Algorithm Name !! Work !! Param size !! Solution size !! Provably Secure !! SPH Resistance !! Status @@ -173,7 +173,7 @@ Additional notes: There is only one Purpose Identifier currently. In the future, more Purpose Identifiers could be added for at-DoS-risk operations, such as bloom filters. When a new identifier is introduced, it should be added with an increment of 1 to the last identifier in the list. When an identifier is deprecated, its status should be changed to Deprecated but it should retain its place in -the list indefinitely. +the list indefinitely. {|class="wikitable" ! ID !! Purpose Name !! Description !! Status @@ -236,7 +236,7 @@ Normally mid-layer (all but the last) POW algorithms have a zero-length input. E |- | 1..4 || pow-id || 1 || sha256 |- -| 5 || pow-params (config_length) || 9 || +| 5 || pow-params (config_length) || 9 || |- | 6..9 || pow-params (target) || 0x207fffff || Resulting hash must be <= the compact hash 0x207fffff* |- @@ -248,7 +248,7 @@ Normally mid-layer (all but the last) POW algorithms have a zero-length input. E |- | 19..22 || pow-id || 2 || cuckoo-cycle |- -| 23 || pow-params (config_length) || 8 || +| 23 || pow-params (config_length) || 8 || |- | 24 || pow-params (sizeshift) || 28 |- diff --git a/bip-0155.mediawiki b/bip-0155.mediawiki index 0ec680194d..bef289a6e9 100644 --- a/bip-0155.mediawiki +++ b/bip-0155.mediawiki @@ -44,7 +44,7 @@ interpreted as described in RFC 2119[https://tools.ietf.org/html/rfc2119 RF The addrv2 message is defined as a message where pchCommand == "addrv2". It is serialized in the standard encoding for P2P messages. -Its format is similar to the current addr message format, with the difference that the +Its format is similar to the current addr message format, with the difference that the fixed 16-byte IP address is replaced by a network ID and a variable-length address, and the services format has been changed to [https://en.bitcoin.it/wiki/Protocol_documentation#Variable_length_integer CompactSize]. This means that the message contains a serialized std::vector of the following structure: diff --git a/bip-0156.mediawiki b/bip-0156.mediawiki index dcfed1f6b4..3fa486a259 100644 --- a/bip-0156.mediawiki +++ b/bip-0156.mediawiki @@ -109,7 +109,7 @@ Figure 3 To avoid this issue, we suggest "per-inbound-edge" routing. Each inbound peer is assigned a particular Dandelion destination. Each Dandelion transaction that -arrives via this peer is forwarded to the same Dandelion destination. +arrives via this peer is forwarded to the same Dandelion destination. Per-inbound-edge routing breaks the described attack by blocking an adversary's ability to construct useful fingerprints. Fingerprints arise when routing decisions are made independently per transaction at each node. In this case, two diff --git a/bip-0159.mediawiki b/bip-0159.mediawiki index 365aee163b..a659e726a1 100644 --- a/bip-0159.mediawiki +++ b/bip-0159.mediawiki @@ -50,7 +50,7 @@ Pruned peers following this BIP may consume more outbound bandwidth. Light clients (and such) who are not checking the nServiceFlags (service bits) from a relayed addr-message may unwillingly connect to a pruned peer and ask for (filtered) blocks at a depth below their pruned depth. Light clients should therefore check the service bits (and eventually connect to peers signaling NODE_NETWORK_LIMITED if they require [filtered] blocks around the tip). Light clients obtaining peer IPs though DNS seed should use the DNS filtering option. -== Compatibility == +== Compatibility == This proposal is backward compatible. diff --git a/bip-0174.mediawiki b/bip-0174.mediawiki index 94a52f2d0f..8509f97d93 100644 --- a/bip-0174.mediawiki +++ b/bip-0174.mediawiki @@ -881,7 +881,7 @@ If a field requires significant description as to its usage, it should be accomp The field must be added to the field listing tables in the Specification section. Although some PSBT version 0 implementations encode types as uint8_t rather than compact size, it is still safe to add >0xFD fields to PSBT 0, because these old parsers ignore -unknown fields, and is prefixed by its length. +unknown fields, and is prefixed by its length. ===Procedure For New Versions=== diff --git a/bip-0176.mediawiki b/bip-0176.mediawiki index 2f5ee9f9d6..bfce9a22cb 100644 --- a/bip-0176.mediawiki +++ b/bip-0176.mediawiki @@ -48,7 +48,7 @@ The term "bit" has many different definitions, but the ones of particular note a * bit meaning some amount of data (e.g., the first bit of the version field is 0) * bit meaning strength of a cryptographic algorithm (e.g., 256-bit ECDSA is used in Bitcoin) -The first is a bit dated and isn't likely to confuse people dealing with Bitcoin. The second and third are computer science terms and context should be sufficient to figure out what the user of the word means. +The first is a bit dated and isn't likely to confuse people dealing with Bitcoin. The second and third are computer science terms and context should be sufficient to figure out what the user of the word means. == Copyright == This BIP is licensed under the BSD 2-clause license. diff --git a/bip-0199.mediawiki b/bip-0199.mediawiki index e463c7f7bd..04a1d0ae61 100644 --- a/bip-0199.mediawiki +++ b/bip-0199.mediawiki @@ -19,13 +19,13 @@ This BIP describes a script for generalized off-chain contract negotiation. ==Summary== -A Hashed Time-Locked Contract (HTLC) is a script that permits a designated party (the "seller") to spend funds by disclosing the preimage of a hash. It also permits +A Hashed Time-Locked Contract (HTLC) is a script that permits a designated party (the "seller") to spend funds by disclosing the preimage of a hash. It also permits a second party (the "buyer") to spend the funds after a timeout is reached, in a refund situation. The script takes the following form: OP_IF - [HASHOP] OP_EQUALVERIFY OP_DUP OP_HASH160 + [HASHOP] OP_EQUALVERIFY OP_DUP OP_HASH160 OP_ELSE [TIMEOUTOP] OP_DROP OP_DUP OP_HASH160 OP_ENDIF @@ -44,28 +44,28 @@ The script takes the following form: ** Peggy spends the funds, and in doing so, reveals the preimage to Victor in the transaction; OR ** Victor recovers the funds after the timeout threshold. -Victor is interested in a lower timeout to reduce the amount of time that his funds are encumbered in the event that Peggy does not reveal the preimage. Peggy is -interested in a higher timeout to reduce the risk that she is unable to spend the funds before the threshold, or worse, that her transaction spending the funds does +Victor is interested in a lower timeout to reduce the amount of time that his funds are encumbered in the event that Peggy does not reveal the preimage. Peggy is +interested in a higher timeout to reduce the risk that she is unable to spend the funds before the threshold, or worse, that her transaction spending the funds does not enter the blockchain before Victor's but does reveal the preimage to Victor anyway. ==Motivation== -In many off-chain protocols, secret disclosure is used as part of a settlement mechanism. In some others, the secrets themselves are valuable. HTLC transactions are -a safe and cheap method of exchanging secrets for money over the blockchain, due to the ability to recover funds from an uncooperative counterparty, and the +In many off-chain protocols, secret disclosure is used as part of a settlement mechanism. In some others, the secrets themselves are valuable. HTLC transactions are +a safe and cheap method of exchanging secrets for money over the blockchain, due to the ability to recover funds from an uncooperative counterparty, and the opportunity that the possessor of a secret has to receive the funds before such a refund can occur. ===Lightning network=== In the lightning network, HTLC scripts are used to perform atomic swaps between payment channels. -Alice constructs K and hashes it to produce L. She sends an HTLC payment to Bob for the preimage of L. Bob sends an HTLC payment to Carol for the same preimage and -amount. Only when Alice releases the preimage K does any exchange of value occur, and because the secret is divulged for each hop, all parties are compensated. If +Alice constructs K and hashes it to produce L. She sends an HTLC payment to Bob for the preimage of L. Bob sends an HTLC payment to Carol for the same preimage and +amount. Only when Alice releases the preimage K does any exchange of value occur, and because the secret is divulged for each hop, all parties are compensated. If at any point some parties become uncooperative, the process can be aborted via the refund conditions. ===Zero-knowledge contingent payments=== -Various practical zero-knowledge proving systems exist which can be used to guarantee that a hash preimage derives valuable information. As an example, a -zero-knowledge proof can be used to prove that a hash preimage acts as a decryption key for an encrypted sudoku puzzle solution. (See +Various practical zero-knowledge proving systems exist which can be used to guarantee that a hash preimage derives valuable information. As an example, a +zero-knowledge proof can be used to prove that a hash preimage acts as a decryption key for an encrypted sudoku puzzle solution. (See [https://github.com/zcash/pay-to-sudoku pay-to-sudoku] for a concrete example of such a protocol.) HTLC transactions can be used to exchange such decryption keys for money without risk, and they do not require large or expensive-to-validate transactions. diff --git a/bip-0300.mediawiki b/bip-0300.mediawiki index e5048e75b2..fb2070ac9b 100644 --- a/bip-0300.mediawiki +++ b/bip-0300.mediawiki @@ -213,7 +213,7 @@ M2 is invalid if: * An M2 is already in this block. * It tries to ACK two different M1s for the same slot. -Otherwise: +Otherwise: * The sidechain is "ACK"ed and does NOT get a "fail" for this block. (As it otherwise would.) @@ -242,7 +242,7 @@ Sidechain withdrawals take the form of "Bundles" -- named because they "bundle u Sidechain full nodes aggregate the withdrawal-requests into a big set. The sidechain calculates what M6 would have to look like, to pay all of these withdrawal-requests out. Finally, the sidechain calculates what the hash of this M6 would be. This 32-byte hash identifies the Bundle. -This 32-byte hash is what miners will be slowly ACKing over 3-6 months, not the M6 itself (nor any sidechain data, of course). +This 32-byte hash is what miners will be slowly ACKing over 3-6 months, not the M6 itself (nor any sidechain data, of course). A bundle either pays all its withdrawals out (via M6), or else it fails (and pays nothing out). @@ -283,7 +283,7 @@ M4 is a coinbase OP Return output containing the following: 1-byte - Version n-byte - The "upvote vector" -- describes which bundle-choice is "upvoted", for each sidechain. -The upvote vector will code "abstain" as 0xFF (or 0xFFFF); it will code "alarm" as 0xFE (or 0xFFFE). Otherwise it simply indicates which withdrawal-bundle in the list, is the one to be "upvoted". +The upvote vector will code "abstain" as 0xFF (or 0xFFFF); it will code "alarm" as 0xFE (or 0xFFFE). Otherwise it simply indicates which withdrawal-bundle in the list, is the one to be "upvoted". For example: if there are two sidechains, and we wish to upvote the 7th bundle on sidechain #1 plus the 4th bundle on sidechain #2, then the upvote vector would be { 07, 04 }. And M4 would be [0x6A,D77D1776,00,0006,0003]. @@ -313,7 +313,7 @@ Important: Within a sidechain-group, upvoting one Bundle ("+1") automatically do For example: -{| class="wikitable" +{| class="wikitable" |- ! SC# ! Bundle Hash @@ -350,7 +350,7 @@ For example: ...in block 900,000 could become... -{| class="wikitable" +{| class="wikitable" |- ! SC# ! Bundle Hash @@ -414,7 +414,7 @@ M6 is invalid if: * The txn fee of M6 is NOT exactly equal to the amount of the previous bullet point. * There are additional OP_DRIVECHAIN outputs after the first one. -Else, M6 is valid. +Else, M6 is valid. (The point of the latter two bullet points, is to allow the bundle hash to cover the L1 transaction fee.) @@ -485,7 +485,7 @@ As a soft fork, older software will continue to operate without modification. No ==Deployment== -This BIP will be deployed via UASF-style block height activation. Block height TBD. +This BIP will be deployed via UASF-style block height activation. Block height TBD. ==Reference Implementation== diff --git a/bip-0301.mediawiki b/bip-0301.mediawiki index 966db25a4b..dc3eb15e60 100644 --- a/bip-0301.mediawiki +++ b/bip-0301.mediawiki @@ -89,7 +89,7 @@ So we will discuss: === h* === -h* ("h star") is the sidechain's Merkle Root hash. +h* ("h star") is the sidechain's Merkle Root hash. In Bip301, a sidechain's coinbase txn acts as a header (it contains the hash of the previous side:block, and previous main:block). Thus, the MerkleRoot contains everything important. diff --git a/bip-0329.mediawiki b/bip-0329.mediawiki index fc5da4253c..13b332b0cc 100644 --- a/bip-0329.mediawiki +++ b/bip-0329.mediawiki @@ -39,8 +39,8 @@ The Electrum wallet imports and exports address and transaction labels in a JSON ==Specification== -In order to be lightweight, human readable and well structured, this BIP uses a JSON format. -Further, the JSON Lines format is used (also called newline-delimited JSON)[https://jsonlines.org/ jsonlines.org]. +In order to be lightweight, human readable and well structured, this BIP uses a JSON format. +Further, the JSON Lines format is used (also called newline-delimited JSON)[https://jsonlines.org/ jsonlines.org]. This allows a document to be split, streamed, or incrementally added to, and limits the potential for formatting errors to invalidate an entire import. It is also a convenient format for command-line processing, which is often line-oriented. @@ -48,7 +48,7 @@ Further to the JSON Lines specification, an export of labels from a wallet must Lines are separated by \n. Multiline values are not permitted. Each JSON object must contain 3 or 4 key/value pairs, defined as follows: -{| class="wikitable" +{| class="wikitable" |- ! Key ! Description @@ -71,7 +71,7 @@ Each JSON object must contain 3 or 4 key/value pairs, defined as follows: The reference is defined for each type as follows: -{| class="wikitable" +{| class="wikitable" |- ! Type ! Description @@ -107,7 +107,7 @@ Each JSON object must contain both type and ref properties. Th If present, the optional origin property must contain an abbreviated output descriptor (as defined by BIP380[https://github.com/bitcoin/bips/blob/master/bip-0380.mediawiki BIP-0380]) describing a BIP32 compatible originating wallet, including all key origin information but excluding any actual keys, any child path elements, or a checksum. This property should be used to disambiguate transaction labels from different wallets contained in the same export, particularly when exporting multiple accounts derived from the same seed. -Care should be taken when exporting due to the privacy sensitive nature of the data. +Care should be taken when exporting due to the privacy sensitive nature of the data. Encryption in transit over untrusted networks is highly recommended, and encryption at rest should also be considered. Unencrypted exports should be deleted as soon as possible. For security reasons no private key types are defined. @@ -120,7 +120,7 @@ For security reasons no private key types are defined. ==Backwards Compatibility== -The nature of this format makes it naturally extensible to handle other record types. +The nature of this format makes it naturally extensible to handle other record types. However, importing wallets complying to this specification may ignore types not defined here. ==Test Vectors== diff --git a/bip-0340.mediawiki b/bip-0340.mediawiki index 85b7bac4dc..d26f8b44c4 100644 --- a/bip-0340.mediawiki +++ b/bip-0340.mediawiki @@ -58,7 +58,7 @@ encodings and operations. # Signatures are pairs ''(e, s)'' that satisfy ''e = hash(s⋅G - e⋅P || m)''. This variant avoids minor complexity introduced by the encoding of the point ''R'' in the signature (see paragraphs "Encoding R and public key point P" and "Implicit Y coordinates" further below in this subsection). Moreover, revealing ''e'' instead of ''R'' allows for potentially shorter signatures: Whereas an encoding of ''R'' inherently needs about 32 bytes, the hash ''e'' can be tuned to be shorter than 32 bytes, and [http://www.neven.org/papers/schnorr.pdf a short hash of only 16 bytes suffices to provide SUF-CMA security at the target security level of 128 bits]. However, a major drawback of this optimization is that finding collisions in a short hash function is easy. This complicates the implementation of secure signing protocols in scenarios in which a group of mutually distrusting signers work together to produce a single joint signature (see Applications below). In these scenarios, which are not captured by the SUF-CMA model due its assumption of a single honest signer, a promising attack strategy for malicious co-signers is to find a collision in the hash function in order to obtain a valid signature on a message that an honest co-signer did not intend to sign. # Signatures are pairs ''(R, s)'' that satisfy ''s⋅G = R + hash(R || m)⋅P''. This supports batch verification, as there are no elliptic curve operations inside the hashes. Batch verification enables significant speedups.The speedup that results from batch verification can be demonstrated with the cryptography library [https://github.com/jonasnick/secp256k1/blob/schnorrsig-batch-verify/doc/speedup-batch.md libsecp256k1]. -Since we would like to avoid the fragility that comes with short hashes, the ''e'' variant does not provide significant advantages. We choose the ''R''-option, which supports batch verification. +Since we would like to avoid the fragility that comes with short hashes, the ''e'' variant does not provide significant advantages. We choose the ''R''-option, which supports batch verification. '''Key prefixing''' Using the verification rule above directly makes Schnorr signatures vulnerable to "related-key attacks" in which a third party can convert a signature ''(R, s)'' for public key ''P'' into a signature ''(R, s + a⋅hash(R || m))'' for public key ''P + a⋅G'' and the same message ''m'', for any given additive tweak ''a'' to the signing key. This would render signatures insecure when keys are generated using [[bip-0032.mediawiki#public-parent-key--public-child-key|BIP32's unhardened derivation]] and other methods that rely on additive tweaks to existing keys such as Taproot. diff --git a/bip-0343.mediawiki b/bip-0343.mediawiki index a47edc05f2..cab5cb707f 100644 --- a/bip-0343.mediawiki +++ b/bip-0343.mediawiki @@ -19,7 +19,7 @@ This document specifies a BIP8 (LOT=true) deployment to activate taproot. ==Motivation== -The Taproot soft fork upgrade has been assessed to have overwhelming community consensus and hence should attempt to be activated. Lessons have been learned from the BIP148 and BIP91 deployments in 2017 with regards to giving many months of advance warning before the mandatory signaling is attempted. The mandatory signaling is only required if miners have failed to meet the signaling threshold during the BIP8 deployment. It is important that mandatory signaling is included as without it miners would effectively have the ability to indefinitely block the activation of a soft fork with overwhelming consensus. +The Taproot soft fork upgrade has been assessed to have overwhelming community consensus and hence should attempt to be activated. Lessons have been learned from the BIP148 and BIP91 deployments in 2017 with regards to giving many months of advance warning before the mandatory signaling is attempted. The mandatory signaling is only required if miners have failed to meet the signaling threshold during the BIP8 deployment. It is important that mandatory signaling is included as without it miners would effectively have the ability to indefinitely block the activation of a soft fork with overwhelming consensus. ==Specification== diff --git a/bip-0345.mediawiki b/bip-0345.mediawiki index bc12f04776..12980c4711 100644 --- a/bip-0345.mediawiki +++ b/bip-0345.mediawiki @@ -52,23 +52,23 @@ A common configuration for an individual custodying Bitcoin is "single signature and passphrase" using a hardware wallet. A user with such a configuration might be concerned about the risk associated with relying on a single manufacturer for key management, as well as physical access to the -hardware. +hardware. This individual can use OP_VAULT to make use of a highly secure key as the unlikely recovery path, while using their existing signing procedure -as the withdrawal trigger key with a configured spend delay of e.g. 1 day. +as the withdrawal trigger key with a configured spend delay of e.g. 1 day. The recovery path key can be of a highly secure nature that might otherwise make it impractical for daily use. For example, the key could be generated in some analog fashion, or on an old computer that is then destroyed, with the private key replicated only in paper form. Or the key could be a 2-of-3 multisig using devices from different manufacturers. Perhaps the key is -geographically or socially distributed. +geographically or socially distributed. Since it can be any Bitcoin script policy, the recovery key can include a number of spending conditions, e.g. a time-delayed fallback to an "easier" recovery method, in case the highly secure key winds up being ''too'' highly -secure. +secure. The user can run software on their mobile device that monitors the blockchain for spends of the vault outpoints. If the vaulted coins move in an unexpected @@ -80,7 +80,7 @@ Institutional custodians of Bitcoin may use vaults in similar fashion. ===== Provable timelocks ===== -This proposal provides a mitigation to the +This proposal provides a mitigation to the [https://web.archive.org/web/20230210123933/https://xkcd.com/538/ "$5 wrench attack."] By setting the spend delay to, say, a week, and using as the recovery path a script that enforces a longer relative timelock, the owner of the vault can @@ -95,7 +95,7 @@ timelocked coins for perpetuity or relying on a trusted third party. Vaults in Bitcoin have been discussed formally since 2016 ([http://fc16.ifca.ai/bitcoin/papers/MES16.pdf MES16]) and informally since [https://web.archive.org/web/20160220215151/https://bitcointalk.org/index.php?topic=511881.0 2014]. The value of having a configurable delay period with recovery capability in light of an -unexpected spend has been widely recognized. +unexpected spend has been widely recognized. The only way to implement vaults given the existing consensus rules, aside from [https://github.com/revault emulating vaults with large multisig @@ -114,7 +114,7 @@ Unfortunately, this approach has a number of practical shortcomings: The deployment of a "precomputed" covenant mechanism like [https://github.com/bitcoin/bips/blob/master/bip-0119.mediawiki OP_CHECKTEMPLATEVERIFY] or -[https://github.com/bitcoin/bips/blob/master/bip-0118.mediawiki SIGHASH_ANYPREVOUT] +[https://github.com/bitcoin/bips/blob/master/bip-0118.mediawiki SIGHASH_ANYPREVOUT] would both remove the necessity to use an ephemeral key, since the covenant is enforced on-chain, and lessen the burden of sensitive data storage, since the necessary transactions can be generated from a set of compact @@ -141,7 +141,7 @@ operational overhead using a specialized covenant. The design goals of the proposal are: -* '''efficient reuse of an existing vault configuration.''''''Why does this support address reuse?''' The proposal doesn't rely on or encourage address reuse, but certain uses are unsafe if address reuse cannot be handled - for example, if a custodian gives its users a vault address to deposit to, it cannot enforce that those users make a single deposit for each address. A single vault configuration, whether the same literal scriptPubKey or not, should be able to “receive” multiple deposits. +* '''efficient reuse of an existing vault configuration.''''''Why does this support address reuse?''' The proposal doesn't rely on or encourage address reuse, but certain uses are unsafe if address reuse cannot be handled - for example, if a custodian gives its users a vault address to deposit to, it cannot enforce that those users make a single deposit for each address. A single vault configuration, whether the same literal scriptPubKey or not, should be able to “receive” multiple deposits. * '''batched operations''' for recovery and withdrawal to allow managing multiple vault coins efficiently. @@ -163,7 +163,7 @@ In typical usage, a vault is created by encumbering coins under a taptree [https://github.com/bitcoin/bips/blob/master/bip-0341.mediawiki (BIP-341)] containing at least two leaves: one with an OP_VAULT-containing script that facilitates the expected withdrawal process, and another leaf with -OP_VAULT_RECOVER which ensures the coins can be recovered +OP_VAULT_RECOVER which ensures the coins can be recovered at any time prior to withdrawal finalization. The rules of OP_VAULT ensure the timelocked, interruptible @@ -172,7 +172,7 @@ withdrawal by allowing a spending transaction to replace the some parameters to be set at spend (trigger) time. All other leaves in the taptree must be unchanged in the destination output, which preserves the recovery path as well as any other spending conditions originally included in the vault. This is similar to -the TAPLEAF_UPDATE_VERIFY design that was proposed +the TAPLEAF_UPDATE_VERIFY design that was proposed [https://lists.linuxfoundation.org/pipermail/bitcoin-dev/2021-September/019419.html in 2021]. These tapleaf replacement rules, described more precisely below, ensure a @@ -205,14 +205,14 @@ The vault has a number of stages, some of them optional: === Fee management === A primary consideration of this proposal is how fee management is handled. -Providing dynamic fee management is critical to the operation of a vault, since +Providing dynamic fee management is critical to the operation of a vault, since * precalculated fees are prone to making transactions unconfirmable in high fee environments, and * a fee wallet that is prespecified might be compromised or lost before use. But dynamic fee management can introduce [https://bitcoinops.org/en/topics/transaction-pinning/ pinning vectors]. Care -has been taken to avoid unnecessarily introducing these vectors when using the new +has been taken to avoid unnecessarily introducing these vectors when using the new destination-based spending policies that this proposal introduces. Originally, this proposal had a hard dependency on reformed transaction @@ -237,7 +237,7 @@ When evaluating OP_VAULT (OP_SUCCESS187, [ leaf-update script data items ... ] - + @@ -413,10 +413,10 @@ that contains a taptree of the form tr(, leaves = { - recover: + recover: OP_VAULT_RECOVER, - trigger: + trigger: OP_CHECKSIGVERIFY (i) 2 $leaf-update-script-body OP_VAULT, (ii) @@ -434,7 +434,7 @@ Typically, the internal key for the vault taproot output will be specified so that it is controlled by the same descriptor as the recovery path, which facilitates another (though probably unused) means of recovering the vault output to the recovery path. This has the potential advantage of recovering the -coin without ever revealing it was a vault. +coin without ever revealing it was a vault. Otherwise, the internal key can be chosen to be an unspendable NUMS point to force execution of the taptree contents. @@ -442,7 +442,7 @@ force execution of the taptree contents. === Triggering a withdrawal === To make use of the vault, and spend it towards some output, we construct a spend -of the above tr() output that simply replaces the "trigger" leaf with the +of the above tr() output that simply replaces the "trigger" leaf with the full leaf-update script (in this case, a timelocked CTV script): @@ -461,17 +461,17 @@ Output scripts: [ tr(, leaves = { - recover: + recover: OP_VAULT_RECOVER, <-- unchanged trigger: - - OP_CHECKSEQUENCEVERIFY OP_DROP OP_CHECKTEMPLATEVERIFY <-- changed per the + + OP_CHECKSEQUENCEVERIFY OP_DROP OP_CHECKTEMPLATEVERIFY <-- changed per the leaf-update rules of OP_VAULT ... [ possibly other leaves ] } - ), + ), [ optional revault output with the same sPK as the original vault output ], @@ -499,7 +499,7 @@ entails trade-offs. ==== Unauthorized recovery ==== -Unauthorized recovery simplifies vault use in that recovery never requires additional information aside from the location of the vault outpoints and the recovery path - the "authorization" is simply the reveal of the recovery path, i.e. the preimage of . +Unauthorized recovery simplifies vault use in that recovery never requires additional information aside from the location of the vault outpoints and the recovery path - the "authorization" is simply the reveal of the recovery path, i.e. the preimage of . But because this reveal is the only authorization necessary to spend the vault coins to recovery, the user must expect to recover all such vaults at once, since an observer can replay this recovery (provided they know the outpoints). @@ -513,7 +513,7 @@ These limitations are to avoid pinning attacks. ==== Authorized recovery ==== -With authorized recovery, the user must keep track of an additional piece of information: how to solve the recovery authorization script fragment when recovery is required. +With authorized recovery, the user must keep track of an additional piece of information: how to solve the recovery authorization script fragment when recovery is required. If this key is lost, the user will be unable to initiate the recovery process for their coins. If an attacker obtains the recovery key, they may grief the user during the recovery process by constructing a low fee rate recovery transaction and broadcasting it (though they will not be able to pin because of the replaceability requirement on recovery transactions). @@ -521,7 +521,7 @@ However, authorized recovery configurations have significant benefits. Batched r ==== Recommendation: use a simple, offline recovery authorization key seed ==== -The benefits of batching and fee management that authorized recovery provides are significant. If the recovery authorization key falls into the hands of an attacker, the outcome is not catastrophic, whereas if the user loses their recovery authorization key as well as their trigger key, the result is likely coin loss. Consequently, the author's recommendation is to use a simple seed for the recovery authorization key that can be written down offline and replicated. +The benefits of batching and fee management that authorized recovery provides are significant. If the recovery authorization key falls into the hands of an attacker, the outcome is not catastrophic, whereas if the user loses their recovery authorization key as well as their trigger key, the result is likely coin loss. Consequently, the author's recommendation is to use a simple seed for the recovery authorization key that can be written down offline and replicated. Note that the recovery authorization key '''is not''' the recovery path key, and this is '''much different''' than any recommendation on how to generate the @@ -542,7 +542,7 @@ the trigger authorization pubkeys. Note that when using unauthorized recovery, the reveal of the recovery scriptPubKey will allow any observer to initiate the recovery process for any vault with matching recovery params, provided they are able to locate -the vault outpoints. As a result, it is recommended to expect that +the vault outpoints. As a result, it is recommended to expect that '''all outputs sharing an identical unauthorized should be recovered together'''. This situation can be avoided with a comparable key management model by varying @@ -589,7 +589,7 @@ are essentially dependent on v3 transaction relay policy being deployed. OP_VAULT outputs with the same taptree, aside from slightly different trigger leaves, can be batched together in the same withdrawal -process. Two "trigger" leaves are compatible if they have the same +process. Two "trigger" leaves are compatible if they have the same OP_VAULT arguments. Note that this allows the trigger authorization -- the script prefixing the @@ -617,7 +617,7 @@ can be recovered into the same output. Recovery-incompatible vaults which have authorized recovery can be recovered in the same transaction, so long as each set (grouped by -) has an associated ''recoveryOut''. This allows +) has an associated ''recoveryOut''. This allows unrelated recoveries to share common fee management. === Watchtowers === diff --git a/bip-0347.mediawiki b/bip-0347.mediawiki index 981af8127b..930fce745c 100644 --- a/bip-0347.mediawiki +++ b/bip-0347.mediawiki @@ -44,7 +44,7 @@ OP_CAT aims to expand the toolbox of the tapscript developer with a simple, modu * Vaults M. Moser, I. Eyal, and E. G. Sirer, Bitcoin Covenants, http://fc16.ifca.ai/bitcoin/papers/MES16.pdf which are a specialized covenant that allows a user to block a malicious party who has compromised the user's secret key from stealing the funds in that output. As shown in A. Poelstra, "CAT and Schnorr Tricks II", 2021, https://www.wpsoftware.net/andrew/blog/cat-and-schnorr-tricks-ii.html OP_CAT is sufficient to build vaults in Bitcoin. * Replicating CheckSigFromStack A. Poelstra, "CAT and Schnorr Tricks I", 2021, https://medium.com/blockstream/cat-and-schnorr-tricks-i-faf1b59bd298 which would allow the creation of simple covenants and other advanced contracts without having to presign spending transactions, possibly reducing complexity and the amount of data that needs to be stored. Originally shown to work with Schnorr signatures, this result has been extended to ECDSA signatures R. Linus, "Covenants with CAT and ECDSA", 2023, https://gist.github.com/RobinLinus/9a69f5552be94d13170ec79bf34d5e85#file-covenants_cat_ecdsa-md. -OP_CAT was available in early versions of Bitcoin. +OP_CAT was available in early versions of Bitcoin. In 2010, a single commit disabled OP_CAT, along with another 15 opcodes. Folklore states that OP_CAT was removed in this commit because it enabled the construction of a script whose evaluation could have memory usage exponential in the size of the script. For example, a script that pushed a 1-byte value on the stack and then repeated the opcodes OP_DUP, OP_CAT 40 times would result in a stack element whose size was greater than 1 terabyte assuming no maximum stack element size. As Bitcoin at that time had a maximum stack element size of 5000 bytes, the effect of this expansion was limited to 5000 bytes. @@ -109,5 +109,5 @@ An alternative implementation of OP_CAT can be found in Elements Roose S., ==Acknowledgements== -We wish to acknowledge Dan Gould for encouraging and helping review this effort. We also want to thank Madars Virza, Jeremy Rubin, Andrew Poelstra, Bob Summerwill, +We wish to acknowledge Dan Gould for encouraging and helping review this effort. We also want to thank Madars Virza, Jeremy Rubin, Andrew Poelstra, Bob Summerwill, Tim Ruffing and Johan T. Halseth for their feedback, review and helpful comments. diff --git a/bip-0380.mediawiki b/bip-0380.mediawiki index 17e48e3249..eea5ce144e 100644 --- a/bip-0380.mediawiki +++ b/bip-0380.mediawiki @@ -212,7 +212,7 @@ The following tests cover the checksum and character set: * Error in checksum: raw(deedbeef)##9f8spxm * Invalid characters in payload: raw(Ü)#00000000 -The following tests cover key expressions: +The following tests cover key expressions: Valid expressions: From f085cc29221f0f28310804d4482b33bb1afd9e07 Mon Sep 17 00:00:00 2001 From: Orfeas Stefanos Thyfronitis Litos <18602747+OrfeasLitos@users.noreply.github.com> Date: Thu, 25 Jul 2024 19:50:08 +0100 Subject: [PATCH 337/454] Make link title more specific (#1652) --- bip-0341.mediawiki | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/bip-0341.mediawiki b/bip-0341.mediawiki index 639cec6cb6..bd45f3d92c 100644 --- a/bip-0341.mediawiki +++ b/bip-0341.mediawiki @@ -41,7 +41,7 @@ As a result we choose this combination of technologies: * '''Taproot''' on top of that lets us merge the traditionally separate pay-to-pubkey and pay-to-scripthash policies, making all outputs spendable by either a key or (optionally) a script, and indistinguishable from each other. As long as the key-based spending path is used for spending, it is not revealed whether a script path was permitted as well, resulting in space savings and an increase in scripting privacy at spending time. * Taproot's advantages become apparent under the assumption that most applications involve outputs that could be spent by all parties agreeing. That's where '''Schnorr''' signatures come in, as they permit [https://eprint.iacr.org/2018/068 key aggregation]: a public key can be constructed from multiple participant public keys, and which requires cooperation between all participants to sign for. Such multi-party public keys and signatures are indistinguishable from their single-party equivalents. This means that with taproot most applications can use the key-based spending path, which is both efficient and private. This can be generalized to arbitrary M-of-N policies, as Schnorr signatures support threshold signing, at the cost of more complex setup protocols. * As Schnorr signatures also permit '''batch validation''', allowing multiple signatures to be validated together more efficiently than validating each one independently, we make sure all parts of the design are compatible with this. -* Where unused bits appear as a result of the above changes, they are reserved for mechanisms for '''future extensions'''. As a result, every script in the Merkle tree has an associated version such that new script versions can be introduced with a soft fork while remaining compatible with BIP 341. Additionally, future soft forks can make use of the currently unused annex in the witness (see [[bip-0341.mediawiki#Rationale|BIP341]]). +* Where unused bits appear as a result of the above changes, they are reserved for mechanisms for '''future extensions'''. As a result, every script in the Merkle tree has an associated version such that new script versions can be introduced with a soft fork while remaining compatible with BIP 341. Additionally, future soft forks can make use of the currently unused annex in the witness (see [[bip-0341.mediawiki#rationale|Rationale]]). * While the core semantics of the '''signature hashing algorithm''' are not changed, a number of improvements are included in this proposal. The new signature hashing algorithm fixes the verification capabilities of offline signing devices by including amount and scriptPubKey in the signature message, avoids unnecessary hashing, uses '''tagged hashes''' and defines a default sighash byte. * The '''public key is directly included in the output''' in contrast to typical earlier constructions which store a hash of the public key or script in the output. This has the same cost for senders and is more space efficient overall if the key-based spending path is taken. '''Why is the public key directly included in the output?''' While typical earlier constructions store a hash of a script or a public key in the output, this is rather wasteful when a public key is always involved. To guarantee batch verifiability, the public key must be known to every verifier, and thus only revealing its hash as an output would imply adding an additional 32 bytes to the witness. Furthermore, to maintain [https://lists.linuxfoundation.org/pipermail/bitcoin-dev/2016-January/012198.html 128-bit collision security] for outputs, a 256-bit hash would be required anyway, which is comparable in size (and thus in cost for senders) to revealing the public key directly. While the usage of public key hashes is often said to protect against ECDLP breaks or quantum computers, this protection is very weak at best: transactions are not protected while being confirmed, and a very [https://twitter.com/pwuille/status/1108097835365339136 large portion] of the currency's supply is not under such protection regardless. Actual resistance to such systems can be introduced by relying on different cryptographic assumptions, but this proposal focuses on improvements that do not change the security model. From 0963e43860e2c8e41c0821e2bc442bdd337a0ded Mon Sep 17 00:00:00 2001 From: Eugene Siegel Date: Fri, 26 Jul 2024 11:46:37 -0400 Subject: [PATCH 338/454] BIP 324: fix python aad in complete_handshake --- bip-0324.mediawiki | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/bip-0324.mediawiki b/bip-0324.mediawiki index 2119a851b6..941d96e006 100644 --- a/bip-0324.mediawiki +++ b/bip-0324.mediawiki @@ -384,7 +384,7 @@ def complete_handshake(peer, initiating, decoy_content_lengths=[]): if received_garbage[-16:] == peer.recv_garbage_terminator: # Receive, decode, and ignore version packet. # This includes skipping decoys and authenticating the received garbage. - v2_receive_packet(peer, aad=received_garbage) + v2_receive_packet(peer, aad=received_garbage[:-16]) return else: received_garbage += recv(peer, 1) From c2655e0ab988ea2a43264186a368b7b4ec3734f9 Mon Sep 17 00:00:00 2001 From: Salvatore Ingala <6681844+bigspider@users.noreply.github.com> Date: Sat, 27 Jul 2024 19:36:08 +0200 Subject: [PATCH 339/454] More adjustments from PR review --- bip-0388.mediawiki | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/bip-0388.mediawiki b/bip-0388.mediawiki index fd28f0445d..7f0aab5964 100644 --- a/bip-0388.mediawiki +++ b/bip-0388.mediawiki @@ -14,7 +14,8 @@ == Abstract == -Software wallets and hardware signing devices sequester wallet uses into logically separate "accounts". +Software wallets and hardware signing devices typically partition funds into separate "accounts". When signing or visualizing transactions, this allows to show to the user aggregate in-flow or out-flow information for one or more involved accounts. + Wallet policies build on top of output script descriptors to represent such accounts in a compact, reviewable way. An account encompasses a logical group of receive and change addresses, and each wallet policy represents all descriptors necessary to describe an account in its entirety. @@ -67,7 +68,7 @@ Reusing keys across different UTXOs harms user privacy by allowing external part By constraining the derivation path patterns to have a uniform structure, wallet policies prevent key reuse among the same or different UTXOs of the same account. -It is strongly recommended to avoid key reuse across accounts. Distinct public keys per account can be guaranteed per hardened derivation paths. This specification does not mandate hardened derivation to maintain compatibility with existing deployments that do not adhere to this recommendation. +It is strongly recommended to avoid key reuse across accounts. Distinct public keys per account can be guaranteed by using distinct hardened derivation paths. This specification does not mandate hardened derivation in order to maintain compatibility with existing deployments that do not adhere to this recommendation. It is out of scope for this document to guarantee that users do not reuse extended public keys among different wallet accounts. This responsibility is left to the users and their software wallet. From eeaf21d882df2cda2b0434918f2f15a62db79590 Mon Sep 17 00:00:00 2001 From: Matt Corallo Date: Sun, 28 Jul 2024 17:30:57 +0000 Subject: [PATCH 340/454] Consistently refer to them as "human-readable names", not addresses It seems confusing to call BIP 353 names "addresses", and most of the BIP refers to them as "names", but a few "human-readable addresses" snuck in in a recent change, which are fixed here. --- bip-0353.mediawiki | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/bip-0353.mediawiki b/bip-0353.mediawiki index 9deba50b0b..43e424f8ec 100644 --- a/bip-0353.mediawiki +++ b/bip-0353.mediawiki @@ -70,9 +70,9 @@ Payment instructions which do contain on-chain addresses which will be re-used S === Display === -When displaying a verified human-readable address, wallets SHOULD prefix it with ₿, i.e. ₿`user`@`domain`. They SHOULD parse recipient information in both `user`@`domain` and ₿`user`@`domain` forms and resolve such entry into recipient information using the above record. For the avoidance of doubt, the ₿ is *not* included in the DNS label which is resolved. +When displaying a verified human-readable name, wallets SHOULD prefix it with ₿, i.e. ₿`user`@`domain`. They SHOULD parse recipient information in both `user`@`domain` and ₿`user`@`domain` forms and resolve such an entry into recipient information using the above record. For the avoidance of doubt, the ₿ is *not* included in the DNS label which is resolved. -Wallets providing the ability for users to "copy" their address information SHOULD copy the underlying URI directly, rather than the human-readable address. This avoids an additional DNS lookup by the application in which it is pasted. Wallets that nevertheless provide users the ability to copy their human-readable address, MUST include the ₿ prefix (i.e. copy it in the form ₿`user`@`domain`). +Wallets providing the ability for users to "copy" their address information SHOULD copy the underlying URI directly, rather than the human-readable name. This avoids an additional DNS lookup by the application in which it is pasted. Wallets that nevertheless provide users the ability to copy their human-readable name, MUST include the ₿ prefix (i.e. copy it in the form ₿`user`@`domain`). Wallets accepting payment information from external devices (e.g. hardware wallets) SHOULD accept RFC 9102-formatted proofs (as a series of unsorted `AuthenticationChain` records) and, if verification succeeds, SHOULD display the recipient in the form ₿`user`@`domain`. From a35650e14e5e3afce269efa0926233c30871b140 Mon Sep 17 00:00:00 2001 From: Fabian Jahr Date: Mon, 27 May 2024 23:23:06 +0200 Subject: [PATCH 341/454] Add BIP 94 - Testnet 4 --- README.mediawiki | 7 +++ bip-0094.mediawiki | 120 +++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 127 insertions(+) create mode 100644 bip-0094.mediawiki diff --git a/README.mediawiki b/README.mediawiki index 710e128e61..5c993a680c 100644 --- a/README.mediawiki +++ b/README.mediawiki @@ -491,6 +491,13 @@ Those proposing changes should consider that ultimately consent may rest with th | Informational | Draft |- +| [[bip-0094.mediawiki|94]] +| Applications +| Testnet 4 +| Fabian Jahr +| Standard +| Draft +|- | [[bip-0098.mediawiki|98]] | Consensus (soft fork) | Fast Merkle Trees diff --git a/bip-0094.mediawiki b/bip-0094.mediawiki new file mode 100644 index 0000000000..06f8f531f7 --- /dev/null +++ b/bip-0094.mediawiki @@ -0,0 +1,120 @@ +
+  BIP: 94
+  Layer: Applications
+  Title: Testnet 4
+  Author: Fabian Jahr 
+  Comments-Summary: No comments yet.
+  Comments-URI: https://github.com/bitcoin/bips/wiki/Comments:BIP-0094
+  Status: Draft
+  Type: Standards Track
+  Created: 2024-05-27
+  License: CC0-1.0
+  Post-History: https://gnusha.org/pi/bitcoindev/CADL_X_eXjbRFROuJU0b336vPVy5Q2RJvhcx64NSNPH-3fDCUfw@mail.gmail.com/
+                https://gnusha.org/pi/bitcoindev/a6e3VPsXJf9p3gt_FmNF_Up-wrFuNMKTN30-xCSDHBKXzXnSpVflIZIj2NQ8Wos4PhQCzI2mWEMvIms_FAEs7rQdL15MpC_Phmu_fnR9iTg=@protonmail.com/
+                https://github.com/bitcoin/bitcoin/pull/29775
+
+ +== Abstract == + +A new test network with the goal to replace Testnet 3. This network comes with small but important improvements of the consensus rules, that should make it impractical to attack the network using only CPU mining. + +== Motivation == + +Quoting the original mailing list post from Jameson Lopphttps://gnusha.org/pi/bitcoindev/CADL_X_eXjbRFROuJU0b336vPVy5Q2RJvhcx64NSNPH-3fDCUfw@mail.gmail.com/: + +
+Testnet3 has been running for 13 years. It's on block 2.5 million something and the block reward is down to ~0.014 TBTC, so mining is not doing a great job at distributing testnet coins anymore. + +The reason the block height is insanely high is due to a rather amusing edge case bug that causes the difficulty to regularly get reset to 1, which causes a bit of havoc. If you want a deep dive into the quirk: https://blog.lopp.net/the-block-storms-of-bitcoins-testnet/ + +Testnet3 is being actively used for scammy airdrops; those of us who tend to be generous with our testnet coins are getting hounded by non-developers chasing cheap gains. + +As a result, TBTC is being actively bought and sold; one could argue that the fundamental principle of testnet coins having no value has been broken. +
+ +Since then the issue with block storms has been further demonstrated on Testnet 3 when three years' worth of blocks were mined in a few weeks while rendering the network practically unusable at the same time. + +== Specification == + +Consensus of Testnet 4 follows the same rules as mainnet with the exception of the three rules detailed below. Additionally all soft forks that are active on mainnet as of May 2024 are enforced from genesis. + +=== 20-minute Exception === + +This rule was already previously implemented and active in Testnet 3https://github.com/bitcoin/bitcoin/pull/686. + +A block with a timestamp that is more than 20 minutes past the timestamp of the previous block must have a minimum difficulty of 1 (the network's minimum difficulty) instead of whatever the actual difficulty level currently is. This applies to all blocks in a difficulty period except for the first block. This means the blocks must change their nBits field from the actual difficulty level to the minimum difficulty value 0x1d00ffff. + +This rule also led to the block stormshttps://blog.lopp.net/the-block-storms-of-bitcoins-testnet/ which the following rule seeks to fix. + +=== Block Storm Fix === + +The work required for a new difficulty period is calculated as multiplication factor to the difficulty of the previous period (but no less than 1/4th and no more than 4x), depending on the duration of the previous difficulty period. On Mainnet and Testnet 3, this factor is applied to the difficulty value of the last block. + +Block storms happen organically whenever the 20-minute exception is applied to a difficulty period’s last block, causing the block to be mined at a difficulty of 1. The difficulty adjustment rules then limit the subsequent period’s difficulty to a value between 1 (the minimum) and 4. Blocks will be generated rapidly in the subsequent low-difficulty periods while the difficulty climbs back to an adequate range. An arbitrarily large number of blocks can be generated quickly by repeatedly using the 20-minute exception on every last block of difficulty periods. The block storm is then bounded only by miner hash rate, the need for last blocks to have a timestamp 20 minutes after the second to last block, the Median-Time-Past nTime rule, and the requirement that blocks can't be more than 2 hours in the future. Overall a sustained attack would eventually be limited to a maximum cadence of six blocks per second. + +A block storm does not require a time warp attack, but one can be used to amplifyA perpetual block storm attack with entire difficulty periods being authored in less than 3.5 days that resets the difficulty to the minimum in the last block of every difficulty period would adjust to a new actual difficulty of 4 every period. An attacker that additionally leverages a time warp attack would start their attack by holding back timestamps until the latest block’s timestamp is at least two weeks in the past, and then limiting their block rate to six blocks per second, incrementing the timestamp on every sixth block. Only on the last block they would use the current time, which both resets the difficulty to one per the 20-minute exception and would result in a difficulty adjustment keeping the difficulty at the minimum due to the elapsed time exceeding the target. This would allow lower the difficulty for all blocks to difficulty 1 instead of difficulty 4 it. + +The mitigation consists of no longer applying the adjustment factor to the last block of the previous difficulty period. Instead, the first block of the difficulty period is used as the base. + +The first block must contain the actual difficulty of the network and can therefore be used as the base for the calculation of the new difficulty level. Note that the first block in new difficulty period does not allow usage of the 20-minute exception (this is prior behavior). This means that in each difficulty period the first block should always have the actual difficulty even if all other blocks were mined with the 20-minute exception. + +=== Time Warp Fix === + +In addition to a time warp attack potentially exacerbating the perpetual block storm attack, a time warp attack provides an alternative way to increase the block production rate even if the unintended reset of the actual difficulty due to the 20-minute exception was mitigated. + +To protect against the time warp attack, the following rule proposed as part of The Great Consensus Cleanuphttps://github.com/TheBlueMatt/bips/blob/cleanup-softfork/bip-XXXX.mediawiki is enforced: "The nTime field of each block whose height, mod 2016, is 0 must be greater than or equal to the nTime field of the immediately prior block minus 600. For the avoidance of doubt, such blocks must still comply with existing Median-Time-Past nTime restrictions." + +== Rationale == + +The applied changes were the result of discussions on the mailing list and the PR. The selected changes try to strike a balance between minimal changes to the network (keeping it as close to mainnet as possible) while making it more robust against attackers that try to disrupt the network. Several alternative designs were considered: + +* For the block storm fix an alternative fix could have been to prevent the last block in a difficulty period from applying the existing difficulty exception. Both solutions were deemed acceptable and there was no clear preference among reviewers. +* Removal of the 20-minute exception was discussed but dismissed since several reviewers insisted that it was a useful feature allowing non-standard transactions to be mined with just a CPU. The 20-minute exception also allows CPU users to move the chain forward (except on the first block that needs to be mined at actual difficulty) in case a large amount of hash power suddenly leaves the network. This would allow the chain to recover to a normal difficulty level faster if left stranded at high difficulty. +* Increase of minimum difficulty was discussed but dismissed as it would categorically prevent participation in the network using a CPU miner (utilizing the 20-minute exception). +* Increase of the delay in the 20-minute exception was suggested but did not receive significant support. +* Re-enabling acceptnonstdtxn in bitcoin core by default was dismissed as it had led to confusion among layer-2s that had used testnet for transaction propagation tests and expected it to behave similar to mainnet. +* Motivating miners to re-org min difficulty blocks was suggested, but was considered out of scope for this BIP, since adoption of such a mining policy remains available after Testnet 4 is deployed. As 20-minute exception blocks only contribute work corresponding to difficulty one to the chaintip, and actual difficulty blocks should have a difficulty magnitudes higher, a block mined at actual difficulty could easily replace even multiple 20-minute exception blocks. +* Persisting the real difficulty in the version field was suggested to robustly prevent exploits of the 20-minute exception while allowing it to be used on any block, but did not receive a sufficient level of support to justify the more invasive change. + +One known downside of the chosen approach is that if the difficulty is gradually raised by a miner with significant hash rate, and this miner disappears, then each difficulty adjustment period requires one block at the actual difficulty. + +This would cause the network to stall once per difficulty adjustment period until the real difficulty is adjusted downwards enough for the remaining hash rate to find this block in reasonable time. + +== Network Parameters == + +=== Consensus Rules === + +All consensus rules active on mainnet at the time of this proposal are enforced from block 1, the newest of these rules being the Taproot softfork. + +=== Genesis Block === + +* Message: 03/May/2024 000000000000000000001ebd58c244970b3aa9d783bb001011fbe8ea8e98e00e +* Pubkey: 000000000000000000000000000000000000000000000000000000000000000000 +* Time stamp: 1714777860 +* Nonce: 393743547 +* Difficulty: 0x1d00ffff +* Version: 1 + +The resulting genesis block hash is 00000000da84f2bafbbc53dee25a72ae507ff4914b867c565be350b0da8bf043, and the block hex is 01000000010000000000000000000000000000000000000000000000000000000000000000ffffffff5504ffff001d01044c4c30332f4d61792f323032342030303030303030303030303030303030303030303165626435386332343439373062336161396437383362623030313031316662653865613865393865303065ffffffff0100f2052a010000002321000000000000000000000000000000000000000000000000000000000000000000ac00000000. + +=== Message Start === + +The message start is defined as 0x1c163f28. These four bytes were randomly generated and have no special meaning. + +== Backwards Compatibility == + +The rules used by Testnet 4 are backwards compatible to the rules of Testnet 3. Existing software that implements support for Testnet 3 would only require addition of the network parameters (magic number, genesis block, etc.) to be able to follow Testnet 4. + +However, implementations that only implement Testnet 3’s rules would accept a chain that violates Testnet 4’s rules and are therefore susceptible to being forked off. It is recommended that any implementations check blocks in regard to all the new rules of Testnet 4 and reject blocks that fail to comply. + +== Reference implementation == + +Pull request at https://github.com/bitcoin/bitcoin/pull/29775 + +== References == + + + +== Copyright == + +This document is licensed under the Creative Commons CC0 1.0 Universal license. From 00fbea5dcd5e90449f270a046ac3fcfdea100b65 Mon Sep 17 00:00:00 2001 From: Salvatore Ingala <6681844+bigspider@users.noreply.github.com> Date: Sat, 3 Aug 2024 17:05:46 +0200 Subject: [PATCH 342/454] Nit from PR review Co-authored-by: Mark "Murch" Erhardt --- bip-0388.mediawiki | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/bip-0388.mediawiki b/bip-0388.mediawiki index 7f0aab5964..6524441b36 100644 --- a/bip-0388.mediawiki +++ b/bip-0388.mediawiki @@ -62,7 +62,7 @@ This makes it impossible for an attacker to surreptitiously modify the policy, t ==== Avoiding key reuse ==== -Reusing public keys within a Script is a source of malleability when using miniscript policies, which has potential security implications. +Reusing public keys within a script is a source of malleability when using miniscript policies, which has potential security implications. Reusing keys across different UTXOs harms user privacy by allowing external parties to link these UTXOs to the same entity once they are spent. From 0c2a2172f76d05ecfdf55fed5650cc3ebaddb34a Mon Sep 17 00:00:00 2001 From: Fabian Jahr Date: Mon, 5 Aug 2024 23:05:30 +0200 Subject: [PATCH 343/454] Change BIP 94 timewarp delta to 7200 seconds --- bip-0094.mediawiki | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/bip-0094.mediawiki b/bip-0094.mediawiki index 06f8f531f7..bda96e12dc 100644 --- a/bip-0094.mediawiki +++ b/bip-0094.mediawiki @@ -62,7 +62,7 @@ The first block must contain the actual difficulty of the network and can theref In addition to a time warp attack potentially exacerbating the perpetual block storm attack, a time warp attack provides an alternative way to increase the block production rate even if the unintended reset of the actual difficulty due to the 20-minute exception was mitigated. -To protect against the time warp attack, the following rule proposed as part of The Great Consensus Cleanuphttps://github.com/TheBlueMatt/bips/blob/cleanup-softfork/bip-XXXX.mediawiki is enforced: "The nTime field of each block whose height, mod 2016, is 0 must be greater than or equal to the nTime field of the immediately prior block minus 600. For the avoidance of doubt, such blocks must still comply with existing Median-Time-Past nTime restrictions." +To protect against the time warp attack, the following rule proposed as part of The Great Consensus Cleanuphttps://github.com/TheBlueMatt/bips/blob/cleanup-softfork/bip-XXXX.mediawiki is enforced: "The nTime field of each block whose height, mod 2016, is 0 must be greater than or equal to the nTime field of the immediately prior block minus 7200. For the avoidance of doubt, such blocks must still comply with existing Median-Time-Past nTime restrictions." The originally proposed rule has been adapted to allow for a delta of 7200 seconds instead of only 600 seconds to allow honest miners to mine at the current time even if an attacking miner has postdated the timestamp up to the allowed 2 hours in the previous block. == Rationale == From b6bf97ba9ebb70cdd2943cf31f38592c91403ae2 Mon Sep 17 00:00:00 2001 From: Jose Storopoli Date: Thu, 25 Jul 2024 16:24:00 -0300 Subject: [PATCH 344/454] bip-46: fix typo --- bip-0046.mediawiki | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/bip-0046.mediawiki b/bip-0046.mediawiki index 1602f811a1..2bc4039ef6 100644 --- a/bip-0046.mediawiki +++ b/bip-0046.mediawiki @@ -107,7 +107,7 @@ A certificate message can be created by another application external to this sta Almost all wallets implementing this standard can use their already-existing "Sign Message" function to sign the certificate message. As the certificate message itself is always an ASCII string, the wallet may not need to specially implement this section at all but just rely on users copypasting their certificate message into the already-existing "Sign Message" user interface. This works as long as the wallet knows how to use the private key of the timelocked address for signing messages. -It is most important for wallet implementions of this standard to support creating the certificate signature. Verifying the certificate signature is less important. +It is most important for wallet implementations of this standard to support creating the certificate signature. Verifying the certificate signature is less important. == Test vectors == From c25032a3ff2bd0140c56ea6dbfaa885c7ee75bfb Mon Sep 17 00:00:00 2001 From: Jose Storopoli Date: Sat, 27 Jul 2024 22:58:20 -0300 Subject: [PATCH 345/454] bip-75: fix typo --- bip-0075.mediawiki | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/bip-0075.mediawiki b/bip-0075.mediawiki index ebd5b37d9a..5057206466 100644 --- a/bip-0075.mediawiki +++ b/bip-0075.mediawiki @@ -219,7 +219,7 @@ message EncryptedProtocolMessage { ==Payment Protocol Process with InvoiceRequests== The full process overview for using '''InvoiceRequests''' in the Payment Protocol is defined below.

-All Payment Protocol messages MUST be encapsulated in either a [[#ProtocolMessage|ProtocolMessage]] or [[#EncryptedProcotolMessage|EncryptedProtocolMessage]]. Once the process begins using [[#EncryptedProtocolMessage|EncryptedProtocolMessage]] messages, all subsequent communications MUST use [[#EncryptedProtocolMessage|EncryptedProtocolMessages]]. +All Payment Protocol messages MUST be encapsulated in either a [[#ProtocolMessage|ProtocolMessage]] or [[#EncryptedProtocolMessage|EncryptedProtocolMessage]]. Once the process begins using [[#EncryptedProtocolMessage|EncryptedProtocolMessage]] messages, all subsequent communications MUST use [[#EncryptedProtocolMessage|EncryptedProtocolMessages]].

All Payment Protocol messages SHOULD be communicated using [[#EncryptedProtocolMessage|EncryptedProtocolMessage]] encapsulating messages with the exception that an [[#InvoiceRequest|InvoiceRequest]] MAY be communicated using the [[#ProtocolMessage|ProtocolMessage]] if the receiver's public key is unknown.

From da1e3ad5456b800120a7f98a9816024465dc50d3 Mon Sep 17 00:00:00 2001 From: Jose Storopoli Date: Thu, 25 Jul 2024 16:24:55 -0300 Subject: [PATCH 346/454] bip-119: fix typo --- bip-0119.mediawiki | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/bip-0119.mediawiki b/bip-0119.mediawiki index be1f70cb45..6ca0adb5dd 100644 --- a/bip-0119.mediawiki +++ b/bip-0119.mediawiki @@ -392,7 +392,7 @@ transaction preimages. =====Using Non-Tagged Hashes===== The Taproot/Schnorr BIPs use Tagged Hashes -(`SHA256(SHA256(tag)||SHA256(tag)||msg)`) to prevent taproot leafs, branches, +(`SHA256(SHA256(tag)||SHA256(tag)||msg)`) to prevent taproot leaves, branches, tweaks, and signatures from overlapping in a way that might introduce a security [vulnerability https://lists.linuxfoundation.org/pipermail/bitcoin-dev/2018-June/016091.html]. @@ -494,7 +494,7 @@ The preimage argument passed to CHECKTEMPLATEVERIFY may be unknown or otherwise However, requiring knowledge that an address is spendable from is incompatible with sender's ability to spend to any address (especially, OP_RETURN). If a sender needs to know the template can be spent from before sending, they may request a signature of an provably non-transaction challenge string -from the leafs of the CHECKTEMPLATEVERIFY tree. +from the leaves of the CHECKTEMPLATEVERIFY tree. ====Forwarding Addresses==== From 498668026ed3527e8ccef3f6dfea7416607abe4a Mon Sep 17 00:00:00 2001 From: Jose Storopoli Date: Thu, 25 Jul 2024 16:25:15 -0300 Subject: [PATCH 347/454] bip-152: fix typo --- bip-0152.mediawiki | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/bip-0152.mediawiki b/bip-0152.mediawiki index fad17460fa..eb7d5450fe 100644 --- a/bip-0152.mediawiki +++ b/bip-0152.mediawiki @@ -209,7 +209,7 @@ There are several design goals for the Short ID calculation: * '''Space''' cmpctblock messages are never optional in this protocol, and contain a short ID for each non-prefilled transaction in the block. Thus, the size of short IDs is directly proportional to the maximum bandwidth savings possible. * '''Collision resistance''' It should be hard for network participants to create transactions that cause collisions. If an attacker were able to cause such collisions, filling mempools (and, thus, blocks) with them would cause poor network propagation of new (or non-attacker, in the case of a miner) blocks. -SipHash is a secure, fast, and simple 64-bit MAC designed for network traffic authentication and collision-resistant hash tables. We truncate the output from SipHash-2-4 to 48 bits (see next section) in order to minimize space. The resulting 48-bit hash is certainly not large enough to avoid intentionally created individual collisons, but by using the block hash as a key to SipHash, an attacker cannot predict what keys will be used once their transactions are actually included in a relayed block. We mix in a per-connection 64-bit nonce to obtain independent short IDs on every connection, so that even block creators cannot control where collisions occur, and random collisions only ever affect a small number of connections at any given time. The mixing is done using SHA256(block_header || nonce), which is slow compared to SipHash, but only done once per block. It also adds the ability for nodes to choose the nonce in a better than random way to minimize collisions, though that is not necessary for correct behaviour. Conversely, nodes can also abuse this ability to increase their ability to introduce collisions in the blocks they relay themselves. However, they can already cause more problems by simply refusing to relay blocks. That is inevitable, and this design only seeks to prevent network-wide misbehavior. +SipHash is a secure, fast, and simple 64-bit MAC designed for network traffic authentication and collision-resistant hash tables. We truncate the output from SipHash-2-4 to 48 bits (see next section) in order to minimize space. The resulting 48-bit hash is certainly not large enough to avoid intentionally created individual collisions, but by using the block hash as a key to SipHash, an attacker cannot predict what keys will be used once their transactions are actually included in a relayed block. We mix in a per-connection 64-bit nonce to obtain independent short IDs on every connection, so that even block creators cannot control where collisions occur, and random collisions only ever affect a small number of connections at any given time. The mixing is done using SHA256(block_header || nonce), which is slow compared to SipHash, but only done once per block. It also adds the ability for nodes to choose the nonce in a better than random way to minimize collisions, though that is not necessary for correct behaviour. Conversely, nodes can also abuse this ability to increase their ability to introduce collisions in the blocks they relay themselves. However, they can already cause more problems by simply refusing to relay blocks. That is inevitable, and this design only seeks to prevent network-wide misbehavior. ====Random collision probability==== From b87b21e7c1f7ee1a1ff17f610da96fd9f6cd7780 Mon Sep 17 00:00:00 2001 From: Jose Storopoli Date: Thu, 25 Jul 2024 16:25:27 -0300 Subject: [PATCH 348/454] bip-352: fix typo --- bip-0352.mediawiki | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/bip-0352.mediawiki b/bip-0352.mediawiki index 634e179a72..4462efcaf6 100644 --- a/bip-0352.mediawiki +++ b/bip-0352.mediawiki @@ -99,7 +99,7 @@ In our simplified example we have been referring to Alice's transactions as havi Alice performs the tweak with the sum of her input private keys in the following manner: * Let ''a = a1 + a2 + ... + an'' -* Let ''input_hash = hash(outpointL || (a·G))'', where ''outpointL'' is the smallest outpoint lexicographically'''Why use the lexicographically smallest outpoint for the hash?''' Recall that the purpose of including the input hash is so that the sender and receiver can both come up with a deterministic nonce that ensures that a unique address is generated each time, even when reusing the same scriptPubKey as an input. Choosing the smallest outpoint lexicographically satisifes this requirement, while also ensuring that the generated output is not dependent on the final ordering of inputs in the transaction. Using a single outpoint also works well with memory constrained devices (such as hardware signing devices) as it does not require the device to have the entire transaction in memory in order to generate the silent payment output. +* Let ''input_hash = hash(outpointL || (a·G))'', where ''outpointL'' is the smallest outpoint lexicographically'''Why use the lexicographically smallest outpoint for the hash?''' Recall that the purpose of including the input hash is so that the sender and receiver can both come up with a deterministic nonce that ensures that a unique address is generated each time, even when reusing the same scriptPubKey as an input. Choosing the smallest outpoint lexicographically satisfies this requirement, while also ensuring that the generated output is not dependent on the final ordering of inputs in the transaction. Using a single outpoint also works well with memory constrained devices (such as hardware signing devices) as it does not require the device to have the entire transaction in memory in order to generate the silent payment output. * Let ''P0 = B + hash(input_hash·a·B || 0)·G'' ''' Spend and Scan Key ''' From af9557b589df19508e1b6937346a4b9724bd90d8 Mon Sep 17 00:00:00 2001 From: azuchi Date: Sat, 10 Aug 2024 10:19:39 +0900 Subject: [PATCH 349/454] BIP-0094: fix block hex --- bip-0094.mediawiki | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/bip-0094.mediawiki b/bip-0094.mediawiki index bda96e12dc..24a6af5962 100644 --- a/bip-0094.mediawiki +++ b/bip-0094.mediawiki @@ -95,7 +95,7 @@ All consensus rules active on mainnet at the time of this proposal are enforced * Difficulty: 0x1d00ffff * Version: 1 -The resulting genesis block hash is 00000000da84f2bafbbc53dee25a72ae507ff4914b867c565be350b0da8bf043, and the block hex is 01000000010000000000000000000000000000000000000000000000000000000000000000ffffffff5504ffff001d01044c4c30332f4d61792f323032342030303030303030303030303030303030303030303165626435386332343439373062336161396437383362623030313031316662653865613865393865303065ffffffff0100f2052a010000002321000000000000000000000000000000000000000000000000000000000000000000ac00000000. +The resulting genesis block hash is 00000000da84f2bafbbc53dee25a72ae507ff4914b867c565be350b0da8bf043, and the block hex is 0100000000000000000000000000000000000000000000000000000000000000000000004e7b2b9128fe0291db0693af2ae418b767e657cd407e80cb1434221eaea7a07a046f3566ffff001dbb0c78170101000000010000000000000000000000000000000000000000000000000000000000000000ffffffff5504ffff001d01044c4c30332f4d61792f323032342030303030303030303030303030303030303030303165626435386332343439373062336161396437383362623030313031316662653865613865393865303065ffffffff0100f2052a010000002321000000000000000000000000000000000000000000000000000000000000000000ac00000000. === Message Start === From 52fdb00b6d5844f48cb30b5c39b6fe23708281e4 Mon Sep 17 00:00:00 2001 From: Jose Storopoli Date: Thu, 25 Jul 2024 16:20:55 -0300 Subject: [PATCH 350/454] ci: add typo checking typos is a powerful source code spell checker. Adds a CI job that runs on every PR and push to master (but can also be run manually with workflow_dispatch) that checks for typos. Adds a config file .typos.toml that deals with false positives and only checks for top-level/one-level .mediawiki and .md files. --- .github/workflows/github-action-checks.yml | 9 +++++ .typos.toml | 44 ++++++++++++++++++++++ CONTRIBUTING.md | 12 ++++++ 3 files changed, 65 insertions(+) create mode 100644 .typos.toml create mode 100644 CONTRIBUTING.md diff --git a/.github/workflows/github-action-checks.yml b/.github/workflows/github-action-checks.yml index 8a7d2ac84f..ad76317f96 100644 --- a/.github/workflows/github-action-checks.yml +++ b/.github/workflows/github-action-checks.yml @@ -20,3 +20,12 @@ jobs: with: fetch-depth: 2 - run: scripts/diffcheck.sh + Typo-Checks: + name: "Typo Checks" + runs-on: ubuntu-latest + steps: + - name: Checkout Actions Repository + uses: actions/checkout@v4 + + - name: Check spelling + uses: crate-ci/typos@master diff --git a/.typos.toml b/.typos.toml new file mode 100644 index 0000000000..15d831fa1e --- /dev/null +++ b/.typos.toml @@ -0,0 +1,44 @@ +[default] +extend-ignore-re = [ + # NOTE: use here for regex patterns + "xpub.*", + "xprv.*", + "3.*", # address + "5.*", # address + "private_key .*", + "privkey .*", + "tt.*", # tags + "code.*", # tags + "\\w*", # prefix for tags + "OP_SUCCESSx|\\d+", + "pay.*", + "ser.*", + "prefix.*", + "value: .*", +] + +[default.extend-words] +# NOTE: use here for false-positives +anc = "anc" +PSBT = "PSBT" +ser = "ser" +# Names +Atack = "Atack" +Meni = "Meni" +Ono = "Ono" + +[files] +extend-exclude = [ + "/*/*.csv", + "/*.d*", + "/*/*.d*", + "/*/*.go", + "/*/*.json", + "/*/*/*.json", + "/*/*.mod", + "/*/*.proto", + "/*/*.py", + "scripts", + "/*/*.s*", + "/*/*.t*", +] diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md new file mode 100644 index 0000000000..df6d947a5a --- /dev/null +++ b/CONTRIBUTING.md @@ -0,0 +1,12 @@ +# Contributing Guidelines + +Apart from following [BIP 2](./bip-0002.mediawiki), +we do CI checks to ensure that the proposed BIPs do not have common typos. +These checks are done using [`typos`](https://github.com/crate-ci/typos). +To check for typos locally, +install [`typos`](https://github.com/crate-ci/typos) +and then run in the root directory: + +```bash +typos +``` From 1811613e07f878a42ebeb57e714cdc93664082d3 Mon Sep 17 00:00:00 2001 From: Salvatore Ingala <6681844+bigspider@users.noreply.github.com> Date: Wed, 14 Aug 2024 15:07:55 +0200 Subject: [PATCH 351/454] Further improvements from PR review --- bip-0388.mediawiki | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/bip-0388.mediawiki b/bip-0388.mediawiki index 6524441b36..895e5a08e3 100644 --- a/bip-0388.mediawiki +++ b/bip-0388.mediawiki @@ -14,7 +14,7 @@ == Abstract == -Software wallets and hardware signing devices typically partition funds into separate "accounts". When signing or visualizing transactions, this allows to show to the user aggregate in-flow or out-flow information for one or more involved accounts. +Software wallets and hardware signing devices typically partition funds into separate "accounts". When signing or visualizing a transaction, aggregate flows of funds of all accounts affected by the transaction may (and should) be displayed to the user. Wallet policies build on top of output script descriptors to represent such accounts in a compact, reviewable way. An account encompasses a logical group of receive and change addresses, and each wallet policy represents all descriptors necessary to describe an account in its entirety. @@ -70,7 +70,7 @@ By constraining the derivation path patterns to have a uniform structure, wallet It is strongly recommended to avoid key reuse across accounts. Distinct public keys per account can be guaranteed by using distinct hardened derivation paths. This specification does not mandate hardened derivation in order to maintain compatibility with existing deployments that do not adhere to this recommendation. -It is out of scope for this document to guarantee that users do not reuse extended public keys among different wallet accounts. This responsibility is left to the users and their software wallet. +It is out of scope for this document to guarantee that users do not reuse extended public keys among different wallet accounts. This is still very important, but the responsibility is left to the users and their software wallet. ==== UX issues ==== From 2c259b85fd33593fd3028c5fdbc9abddea388fef Mon Sep 17 00:00:00 2001 From: Fabian Jahr Date: Thu, 15 Aug 2024 11:06:37 +0200 Subject: [PATCH 352/454] Revert "Change BIP 94 timewarp delta to 7200 seconds" This reverts commit 0c2a2172f76d05ecfdf55fed5650cc3ebaddb34a. --- bip-0094.mediawiki | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/bip-0094.mediawiki b/bip-0094.mediawiki index 24a6af5962..d7e436d56d 100644 --- a/bip-0094.mediawiki +++ b/bip-0094.mediawiki @@ -62,7 +62,7 @@ The first block must contain the actual difficulty of the network and can theref In addition to a time warp attack potentially exacerbating the perpetual block storm attack, a time warp attack provides an alternative way to increase the block production rate even if the unintended reset of the actual difficulty due to the 20-minute exception was mitigated. -To protect against the time warp attack, the following rule proposed as part of The Great Consensus Cleanuphttps://github.com/TheBlueMatt/bips/blob/cleanup-softfork/bip-XXXX.mediawiki is enforced: "The nTime field of each block whose height, mod 2016, is 0 must be greater than or equal to the nTime field of the immediately prior block minus 7200. For the avoidance of doubt, such blocks must still comply with existing Median-Time-Past nTime restrictions." The originally proposed rule has been adapted to allow for a delta of 7200 seconds instead of only 600 seconds to allow honest miners to mine at the current time even if an attacking miner has postdated the timestamp up to the allowed 2 hours in the previous block. +To protect against the time warp attack, the following rule proposed as part of The Great Consensus Cleanuphttps://github.com/TheBlueMatt/bips/blob/cleanup-softfork/bip-XXXX.mediawiki is enforced: "The nTime field of each block whose height, mod 2016, is 0 must be greater than or equal to the nTime field of the immediately prior block minus 600. For the avoidance of doubt, such blocks must still comply with existing Median-Time-Past nTime restrictions." == Rationale == From b0d5a0794333bfcf103c3642b168c4338320c48e Mon Sep 17 00:00:00 2001 From: Matt Corallo Date: Sun, 28 Jul 2024 18:34:22 +0000 Subject: [PATCH 353/454] Add a PSBT per-output field for BIP 353 DNSSEC Proofs When using BIP 353 for on-chain addresses (incl silent payments), it is useful to be able to include DNSSEC proof information in outputs of a PSBT, which we enable here by defining a standard field for it. --- bip-0174.mediawiki | 12 ++++++++++++ bip-0353.mediawiki | 27 +++++++++++++++++++++++++++ 2 files changed, 39 insertions(+) diff --git a/bip-0174.mediawiki b/bip-0174.mediawiki index 8509f97d93..5aeba5649b 100644 --- a/bip-0174.mediawiki +++ b/bip-0174.mediawiki @@ -659,6 +659,18 @@ required for aggregation. If sorting was done, then the keys must be in the sort | 0, 2 | [[bip-0373.mediawiki|373]] |- +| BIP 353 DNSSEC proof +| PSBT_OUT_DNSSEC_PROOF = 0x35 +| None +| No key data +| <1-byte-length-prefixed BIP 353 human-readable name> +| A BIP 353 human-readable name (without the ₿ prefix), prefixed by a 1-byte length. +Followed by an [[https://www.rfc-editor.org/rfc/rfc9102.html#name-dnssec-authentication-chain|RFC 9102 DNSSEC AuthenticationChain]] (i.e. a series of DNS Resource Records in no particular order) providing a DNSSEC proof to a BIP 353 DNS TXT record. +| +| +| 0, 2 +| [[bip-0353.mediawiki|353]] +|- | Proprietary Use Type | PSBT_OUT_PROPRIETARY = 0xFC | diff --git a/bip-0353.mediawiki b/bip-0353.mediawiki index 43e424f8ec..9c48f91140 100644 --- a/bip-0353.mediawiki +++ b/bip-0353.mediawiki @@ -76,6 +76,33 @@ Wallets providing the ability for users to "copy" their address information SHOU Wallets accepting payment information from external devices (e.g. hardware wallets) SHOULD accept RFC 9102-formatted proofs (as a series of unsorted `AuthenticationChain` records) and, if verification succeeds, SHOULD display the recipient in the form ₿`user`@`domain`. +=== PSBT types === + +Wallets accepting payment information from external devices (e.g. hardware wallets) MAY examine the following per-output PSBT fields to fetch RFC 9102-formatted proofs. Wallets creating PSBTs with recipient information derived from human-readable names SHOULD include the following fields. + +When validating the contained proof, clients MUST enforce the inception on all contained RRSigs is no later than the current time and that the expiry of all RRSigs is no earlier than an hour in the past. Clients MAY allow for an expiry up to an hour in the past to allow for delays between PSBT construction and signing only if such a delay is likely to occur in their intended usecase. + +{| +! Name +! +! +! +! Description +! Versions Requiring Inclusion +! Versions Requiring Exclusion +! Versions Allowing Inclusion +|- +| BIP 353 DNSSEC proof +| PSBT_OUT_DNSSEC_PROOF = 0x35 +| None +| <1-byte-length-prefixed BIP 353 human-readable name without the ₿ prefix> +| A BIP 353 human-readable name (without the ₿ prefix), prefixed by a 1-byte length. +Followed by an [[https://www.rfc-editor.org/rfc/rfc9102.html#name-dnssec-authentication-chain|RFC 9102 DNSSEC AuthenticationChain]] (i.e. a series of DNS Resource Records in no particular order) providing a DNSSEC proof to a BIP 353 DNS TXT record. +| +| +| 0, 2 +|} + == Rationale == === Display === From 3350d941a8eb0630511d4f6e7504a9cbcc88774b Mon Sep 17 00:00:00 2001 From: Ethan Heilman Date: Sun, 8 Sep 2024 14:34:30 -0400 Subject: [PATCH 354/454] Uses consistent source for "CAT and Schnorr Tricks" For "CAT and Schnorr Tricks I" we used https://medium.com/blockstream/cat-and-schnorr-tricks-i-faf1b59bd298 but for "CAT and Schnorr Tricks II" https://www.wpsoftware.net/andrew/blog/cat-and-schnorr-tricks-ii.html This commit changes this so that the original source wpsoftware is used for both links. --- bip-0347.mediawiki | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/bip-0347.mediawiki b/bip-0347.mediawiki index 930fce745c..0aed70db49 100644 --- a/bip-0347.mediawiki +++ b/bip-0347.mediawiki @@ -42,7 +42,7 @@ OP_CAT aims to expand the toolbox of the tapscript developer with a simple, modu * Post-Quantum Lamport signatures in Bitcoin transactions. Lamport signatures merely require the ability to hash and concatenate values on the stack. J. Rubin, "[bitcoin-dev] OP_CAT Makes Bitcoin Quantum Secure [was CheckSigFromStack for Arithmetic Values]", 2021, https://lists.linuxfoundation.org/pipermail/bitcoin-dev/2021-July/019233.html It has been proposed that if ECDSA is broken or a powerful computer was on the horizon, there might be an effort to protect ownership of bitcoins by allowing people to mark their taproot outputs as "script-path only" and then move their coins into such outputs with a leaf in the script tree requiring a Lamport signature. It is an open question if a tapscript commitment would preserve the quantum resistance of Lamport signatures. Beyond this question, the use of Lamport Signatures in taproot outputs is unlikely to be quantum resistant even if the script spend-path is made quantum resistant. This is because taproot outputs can also be spent with a key. An attacker with a sufficiently powerful quantum computer could bypass the taproot script spend-path by finding the discrete log of the taproot output and thus spending the output using the key spend-path. The use of "Nothing Up My Sleeve" (NUMS) points as described in [[bip-0341.mediawiki|BIP341]] to disable the key spend-path does not disable the key spend-path against a quantum attacker as NUMS relies on the hardness of finding discrete logs. We are not aware of any mechanism which could disable the key spend-path in a taproot output without a softfork change to taproot. * Non-equivocation contracts T. Ruffing, A. Kate, D. Schröder, "Liar, Liar, Coins on Fire: Penalizing Equivocation by Loss of Bitcoins", 2015, https://web.archive.org/web/20221023121048/https://publications.cispa.saarland/565/1/penalizing.pdf in tapscript provide a mechanism to punish equivocation/double spending in Bitcoin payment channels. OP_CAT enables this by enforcing rules on the spending transaction's nonce. The capability is a useful building block for payment channels and other Bitcoin protocols. * Vaults M. Moser, I. Eyal, and E. G. Sirer, Bitcoin Covenants, http://fc16.ifca.ai/bitcoin/papers/MES16.pdf which are a specialized covenant that allows a user to block a malicious party who has compromised the user's secret key from stealing the funds in that output. As shown in A. Poelstra, "CAT and Schnorr Tricks II", 2021, https://www.wpsoftware.net/andrew/blog/cat-and-schnorr-tricks-ii.html OP_CAT is sufficient to build vaults in Bitcoin. -* Replicating CheckSigFromStack A. Poelstra, "CAT and Schnorr Tricks I", 2021, https://medium.com/blockstream/cat-and-schnorr-tricks-i-faf1b59bd298 which would allow the creation of simple covenants and other advanced contracts without having to presign spending transactions, possibly reducing complexity and the amount of data that needs to be stored. Originally shown to work with Schnorr signatures, this result has been extended to ECDSA signatures R. Linus, "Covenants with CAT and ECDSA", 2023, https://gist.github.com/RobinLinus/9a69f5552be94d13170ec79bf34d5e85#file-covenants_cat_ecdsa-md. +* Replicating CheckSigFromStack A. Poelstra, "CAT and Schnorr Tricks I", 2021, https://www.wpsoftware.net/andrew/blog/cat-and-schnorr-tricks-i.html which would allow the creation of simple covenants and other advanced contracts without having to presign spending transactions, possibly reducing complexity and the amount of data that needs to be stored. Originally shown to work with Schnorr signatures, this result has been extended to ECDSA signatures R. Linus, "Covenants with CAT and ECDSA", 2023, https://gist.github.com/RobinLinus/9a69f5552be94d13170ec79bf34d5e85#file-covenants_cat_ecdsa-md. OP_CAT was available in early versions of Bitcoin. In 2010, a single commit disabled OP_CAT, along with another 15 opcodes. From 34db0e99fa4436aa3c4bdedc718c5bc94e10a659 Mon Sep 17 00:00:00 2001 From: Paul Sztorc Date: Mon, 23 Sep 2024 19:02:34 -0400 Subject: [PATCH 355/454] Link to latest code -- also shorter/better explanations (#1666) * Update to CUSF activation client +shorter +clearer * remove superfluous images * link to CUSF client, shorter and clearer BIP text --- bip-0300.mediawiki | 189 +++++++++++++------------------ bip-0301.mediawiki | 97 ++++++---------- bip-0301/images.txt | 1 - bip-0301/m1-gui.jpg | Bin 113155 -> 0 bytes bip-0301/sidechain-headers.png | Bin 42977 -> 0 bytes bip-0301/witness-vs-critical.png | Bin 268309 -> 0 bytes 6 files changed, 112 insertions(+), 175 deletions(-) delete mode 100644 bip-0301/images.txt delete mode 100644 bip-0301/m1-gui.jpg delete mode 100644 bip-0301/sidechain-headers.png delete mode 100644 bip-0301/witness-vs-critical.png diff --git a/bip-0300.mediawiki b/bip-0300.mediawiki index fb2070ac9b..9260cc6c29 100644 --- a/bip-0300.mediawiki +++ b/bip-0300.mediawiki @@ -15,31 +15,28 @@ ==Abstract== -In Bip300, txns are not signed via cryptographic key. Instead, they are "signed" by hashpower, over time. Like a big multisig, 13150-of-26300, where each block is a new "signature". +BIP-300 enables a new type of L2, where "withdrawals" (the L2-to-L1 txns) are governed by proof-of-work -- instead of a federation or fixed set of pubkeys. -Bip300 emphasizes slow, transparent, auditable transactions which are easy for honest users to get right and very hard for dishonest users to abuse. The chief design goal for Bip300 is ''partitioning'' -- users may safely ignore Bip300 txns if they want to (or Bip300 entirely). +BIP-300 emphasizes slow, transparent, and auditable withdrawals that are easy for honest users to get right and hard for dishonest miners to abuse. The main design goal for BIP-300 is ''partitioning'' -- users can ignore BIP-300 txns if they wish; it makes no difference to L1 if the user validates all, some, or none of them. The second design goal is ''security'' -- users of the L2 should feel confident that, [https://www.drivechain.info/blog/fees/ if the L2 network is paying a lot of fees], then miners will want to keep it around, and the withdrawals will therefore be processed accurately. -See [http://www.drivechain.info/ this site] for more information. +Once BIP-300 has established a "bridge" between L1 and these L2s, users can swap coins in and out instantly, only using BIP-300 for final settlement. This setup allows Bitcoin to process all the transactions in the world, of any shape or size, regardless of blocksize, node software, tech stack, or decentralization level -- all without altering L1 at all. ==Motivation== +BIP-300 allows us to achieve [https://www.truthcoin.info/blog/zside-meltcast/ strong privacy], [https://www.truthcoin.info/blog/thunder/ planetary scale], and [https://www.truthcoin.info/blog/all-world-txns/ hundreds of billions of dollars in annual mining revenues], all with a [https://www.drivechain.info/blog/fees/ security model] that is [https://x.com/Truthcoin/status/1701959339508965405 much stronger than] that of the [https://www.truthcoin.info/blog/ln-blackpill/ Lightning Network]. -As Reid Hoffman [https://blockstream.com/2015/01/13/en-reid-hoffman-on-the-future-of-the-bitcoin-ecosystem/ wrote in 2014]: "Sidechains allow developers to add features and functionality to the Bitcoin universe without actually modifying the Bitcoin Core code...Consequently, innovation can occur faster, in more flexible and distributed ways, without losing the synergies of a common platform with a single currency." +The original motivation stretches back to Reid Hoffman, who [https://blockstream.com/2015/01/13/en-reid-hoffman-on-the-future-of-the-bitcoin-ecosystem/ wrote in 2014]: "Sidechains allow developers to add features and functionality to the Bitcoin universe without actually modifying the Bitcoin Core code...Consequently, innovation can occur faster, in more flexible and distributed ways, without losing the synergies of a common platform with a single currency." -Today, coins such as Namecoin, Monero, ZCash, and Sia, offer features that Bitcoiners cannot access -- not without selling their BTC to invest in a rival monetary unit. According to [https://coinmarketcap.com/charts/#dominance-percentage coinmarketcap.com], there is now more value *outside* the BTC protocol than within it. According to [https://cryptofees.info/ cryptofees.info], 15x more txn fees are paid outside the BTC protocol, than within it. +See [http://www.drivechain.info/ drivechain.info] for more information. -Software improvements to Bitcoin rely on developer consensus -- BTC will pass on a good idea if it is even slightly controversial. Development is slow: we are now averaging one major feature every 5 years. -Sidechains allow for competitive "benevolent dictators" to create a new sidechain at any time. These dictators are accountable only to their users, and (crucially) they are protected from rival dictators. Users can move their BTC among these different pieces of software, as *they* see fit. - -BTC can copy every useful technology, as soon as it is invented; scamcoins lose their justification and become obsolete; and the community can be pro-creativity, knowing that Layer1 is protected from harmful changes. ==Specification== ===Overview=== -Bip300 allows for six new blockchain messages (these have consensus significance): +BIP-300 consists of six new blockchain messages: * M1. "Propose New Sidechain" * M2. "ACK Proposal" @@ -48,14 +45,15 @@ Bip300 allows for six new blockchain messages (these have consensus significance * M5. Deposit -- a transfer of BTC from-main-to-side * M6. Withdrawal -- a transfer of BTC from-side-to-main -Nodes organize those messages into two caches: -* D1. "The Sidechain List", which tracks the 256 Hashrate Escrows (Escrows are slots that a sidechain can live in). -* D2. "The Withdrawal List", which tracks the withdrawal-Bundles (coins leaving a Sidechain). +Nodes organize this data into [https://github.com/LayerTwo-Labs/bip300301_enforcer/blob/master/src/bip300.rs#L79-L96 a few caches], mainly these two: + +* D1. "The Sidechain List" +* D2. "The Withdrawal List" ==== D1 (The Sidechain List) ==== -D1 is a list of active sidechains. D1 is updated via M1 and M2. +D1 is a list of active sidechains. D1 is populated via M1 and M2. Fields #9 and #10 are updated via M5 and M6. {| class="wikitable" |- style="font-weight:bold; text-align:center; vertical-align:middle;" @@ -87,12 +85,12 @@ D1 is a list of active sidechains. D1 is updated via M1 and M2. | 5 | Hash1 - tarball hash | uint256 -| Intended as the sha256 hash of the tar.gz of the canonical sidechain software. (This is not enforced anywhere by Bip300, and is for human purposes only.) +| Intended as the sha256 hash of the tar.gz of the canonical sidechain software. (This is not enforced by BIP-300, and is for human purposes only.) |- style="vertical-align:middle;" | 6 | Hash2 - git commit hash | uint160 -| Intended as the git commit hash of the canonical sidechain node software. (This is not enforced anywhere by Bip300, and is for human purposes only.) +| Intended as the git commit hash of the canonical sidechain node software. (This is not enforced by BIP-300, and is for human purposes only.) |- | 7 | Active @@ -118,17 +116,17 @@ D1 is a list of active sidechains. D1 is updated via M1 and M2. ==== D2 (The Withdrawal List) ==== -D2 lists withdrawal-attempts. If these attempts succeed, they will pay coins "from" a Bip300-locked UTXO, to new UTXOs controlled by the withdrawing-user. Each attempt pays out many users, so we call these withdrawal-attempts "Bundles". +Withdrawals are transactions that remove coins "from" L2 (i.e., from the BIP-300 locked UTXO), and place them back on L1. Each BIP-300 withdrawal can pay out up to 6,000 withdrawals, and only one withdrawal can succeed at a time (per L2). Therefore, since all L2 users share the same large withdrawal-event, on L1 we call these withdrawals "bundles". D2 is driven by M3, M4, M5, and M6. Those messages enforce the following principles: -# The Bundles have a canonical order (first come first serve). +# The database has a canonical order (first come first serve). # From one block to the next, every "Blocks Remaining" field decreases by 1. -# When "Blocks Remaining" reaches zero the Bundle is removed. +# When "Blocks Remaining" reaches zero, the bundle is removed. # From one block to the next, the value in "ACKs" may either increase or decrease, by a maximum of 1 (see M4). -# If a Bundle's "ACKs" reach 13150 or greater, it "succeeds" and its corresponding M6 message can be included in a block. -# If the M6 of a Bundle is paid out, it is also removed. -# If a Bundle cannot possibly succeed ( 13150 - "ACKs" > "Blocks Remaining" ), it is removed immediately. +# If a bundle's "ACKs" reach 13150 or greater, it "succeeds" and its corresponding M6 message can be included in a block. +# If the M6 of a bundle is paid out, it is also removed. +# If a bundle cannot possibly succeed ( 13150 - "ACKs" > "Blocks Remaining" ), it is removed immediately. {| class="wikitable" @@ -145,7 +143,7 @@ D2 is driven by M3, M4, M5, and M6. Those messages enforce the following princip | 2 | Bundle Hash | uint256 -| A withdrawal attempt. Specifically, it is a "blinded transaction id" (ie, the double-Sha256 of a txn that has had two fields zeroed out, see M6) of a txn which could withdraw funds from a sidechain. +| A withdrawal attempt. Specifically, it is a "blinded transaction id" (i.e., the double-Sha256 of a txn that has had two fields zeroed out, see M6) of a txn which could withdraw funds from a sidechain. |- | 3 | Work Score (ACKs) @@ -158,20 +156,12 @@ D2 is driven by M3, M4, M5, and M6. Those messages enforce the following princip | How long this bundle has left to live (measured in blocks). Starts at 26,300 and counts down. |} -D1, with all 256 slots active, reaches a maximum size of: 256 * ( 1 (map index) + 36 (outpoint) + 8 (amount) ) = 11,520 bytes. - -D2, under normal conditions, would reach a size of: (38 bytes per withdrawal * 256 sidechains) = 9,728 bytes. -It is possible to spam D2. A miner can add the max M3s (256) every block, forever. This costs 9,728 on-chain bytes per block, an opportunity cost of about 43 txns. It results in no benefit to the miner whatsoever. D2 will eventually hit a ceiling at 124.5568 MB. (By comparison, the Bitcoin UTXO set is about 7,000 MB.) When the attacker stops, D2 will eventually shrink back down to 9,728 bytes. -=== The Six New Bip300 Messages === +=== M1 -- Propose Sidechain === -First, how are new sidechains created? - -They are first proposed (with M1), and later acked (with M2). This process resembles Bip9 soft fork activation. - -==== M1 -- Propose Sidechain ==== +New sidechains are proposed with M1, and ACKed with M2. M1 is a coinbase OP Return output containing the following: @@ -197,7 +187,7 @@ Otherwise: * A new entry is added to D1, whose initial Activation Status is (age=0, fails=0). -==== M2 -- ACK Sidechain Proposal ==== +=== M2 -- ACK Sidechain Proposal === M2 is a coinbase OP Return output containing the following: @@ -219,46 +209,32 @@ Otherwise: A sidechain fails to activate if: -* If the slot is unused: during the next 2016 blocks, it accumulates 201 fails. (Ie, 90% threshold). -* If the slot is in use: during the next 26,300 blocks, it accumulates 13,150 fails. (Ie, 50% threshold). +* If the slot is unused: during the next 2016 blocks, it accumulates 1008 fails (i.e., 50% hashrate threshold). +* If the slot is in use: during the next 26,300 blocks, it accumulates 13,150 fails (i.e., 50% hashrate threshold). -( Thus we can overwrite a used sidechain slot. Bip300 sidechains are already vulnerable to one catastrophe per 13150 blocks (the invalid withdrawal) so this slot-overwrite option does not change the security assumptions. ) +( Thus we can overwrite a used sidechain slot. BIP-300 sidechains are already vulnerable to one catastrophe per 13150 blocks (the invalid withdrawal), so this slot-overwrite option does not change the security assumptions. ) Otherwise, the sidechain activates (Active is set to TRUE). -In the block in which the sidechain activates, the coinbase MUST include at least one 0-valued OP_DRIVECHAIN output. This output becomes the initial CTIP for the sidechain. - - - -==== Notes on Withdrawing Coins ==== - -Bip300 withdrawals ("M6") are very significant. - -For an M6 to be valid, it must be first "prepped" by one M3 and then 13,150+ M4s. M3 and M4 are about "Bundles". - -===== What are Bundles? ===== - -Sidechain withdrawals take the form of "Bundles" -- named because they "bundle up" many individual withdrawal-requests into a single rare layer1 transaction. -Sidechain full nodes aggregate the withdrawal-requests into a big set. The sidechain calculates what M6 would have to look like, to pay all of these withdrawal-requests out. Finally, the sidechain calculates what the hash of this M6 would be. This 32-byte hash identifies the Bundle. +=== Withdrawing in Bundles === -This 32-byte hash is what miners will be slowly ACKing over 3-6 months, not the M6 itself (nor any sidechain data, of course). +Sidechain withdrawals take the form of "bundles" -- named because they "bundle up" many individual withdrawal-requests into a single rare L1 transaction. -A bundle either pays all its withdrawals out (via M6), or else it fails (and pays nothing out). +On the L2 side, individual withdrawal requests are periodically combined into a single CoinJoin-like withdrawal bundle. This bundle is hashed [https://github.com/LayerTwo-Labs/bip300301_messages/blob/master/src/lib.rs#L374C1-L419C2 in a particular way] (on both L2 and L1) -- this "blinded hash" commits to its own L1 fee, but (notably) it does not commit to its first tx-input (in that way, it is like [https://github.com/bitcoin/bips/blob/master/bip-0118.mediawiki BIP-118]). -===== Bundle Hash = Blinded TxID of M6 ===== +This hash is what L1 miners will slowly ACK over 3-6 months, not the M6 itself (nor any sidechain data, of course). -The Bundle hash is static as it is being ACKed. Unfortunately, the M6 TxID will be constantly changing -- as users deposit to the sidechain, the input to M6 will change. +A bundle will either pay all its withdrawals out (via M6), or fail (and pay nothing out for anyone). -To solve this problem, we do something conceptually similar to AnyPrevOut (BIP 118). We define a "blinded TxID" as a way of hashing a txn, in which some bytes are first overwritten with zeros. These are: the first input and the first output. Via the former, a sidechain can accept deposits, even if we are acking a TxID that spends from it later. Via the latter, we can force all of the non-withdrawn coins to be returned to the sidechain (even if we don't yet know how many coins this will be). -==== M3 -- Propose Bundle ==== +=== M3 -- Propose Bundle === M3 is a coinbase OP Return output containing the following: 1-byte - OP_RETURN (0x6a) 4-byte - Commitment header (0xD45AA943) - 32-byte - The Bundle hash, to populate a new D2 entry + 32-byte - The bundle hash, to populate a new D2 entry 1-byte - nSidechain (the slot number) M3 is ignored if it does not parse, or if it is for a sidechain that doesn't exist. @@ -272,9 +248,10 @@ M3 is invalid if: Otherwise: M3 adds an entry to D2, with initial ACK score = 1 and initial Blocks Remaining = 26,299. (Merely being added to D2, does count as your first upvote.) -Once a Bundle is in D2, how can we give it enough ACKs to make it valid? -==== M4 -- ACK Bundle(s) ==== +=== M4 -- ACK Bundle(s) === + +Once a bundle is in D2, how can we give it enough ACKs to make it valid? M4 is a coinbase OP Return output containing the following: @@ -283,35 +260,25 @@ M4 is a coinbase OP Return output containing the following: 1-byte - Version n-byte - The "upvote vector" -- describes which bundle-choice is "upvoted", for each sidechain. -The upvote vector will code "abstain" as 0xFF (or 0xFFFF); it will code "alarm" as 0xFE (or 0xFFFE). Otherwise it simply indicates which withdrawal-bundle in the list, is the one to be "upvoted". - -For example: if there are two sidechains, and we wish to upvote the 7th bundle on sidechain #1 plus the 4th bundle on sidechain #2, then the upvote vector would be { 07, 04 }. And M4 would be [0x6A,D77D1776,00,0006,0003]. - -The version number allows us to shrink the upvote vector in many cases. -Version 0x00 omits the upvote vector entirely (ie, 6 bytes for the whole M4) and sets this block's M4 equal to the previous block's M4. -Version 0x01 uses one byte per sidechain, and can be used while all ACKed withdrawals have an index under 256 (ie, 99.99%+ of the time). -Version 0x02 uses a full two bytes per sidechain (each encoded in little endian), but it always works no matter how many withdrawal proposals exist. -Version 0x03 omits the upvote vector, and instead upvotes only those withdrawals that are leading their rivals by at least 50 votes. - -If a sidechain has no pending bundles, then it is skipped over when M4 is created and parsed. +The M4 message will be invalid (and invalidate the block), if: -For example, an upvote vector of { 2 , N/A, 1 } would be represented as [0x6A,D77D1776,01,01,00]. It means: "upvote the second bundle in sidechain #1; and the first bundle in sidechain #3" (iff sidechains #2 has no bundles proposed). +* It tries to upvote a bundle that doesn't exist. (For example, trying to upvote the 7th bundle on sidechain #2, when sidechain #2 has only three bundles.) +* There are no bundles at all, from any sidechain. -An upvote vector of { N/A, N/A, 4 } would be [0x6A,D77D1776,01,03]. +If M4 is NOT present in a block, then it is treated as an "abstain" for all sidechains. +If M4 is present and valid: each withdrawal-bundle that is ACKed, will gain one upvote. -The M4 message will be invalid (and invalidate the block), if: +Each sidechain always has two "virtual bundles" -- an "abstain" bundle (0xFF), and an "alarm" bundle (0xFE). Abstain leaves the ACK count unchanged, and alarm reduces all ACK counts of all bundles by 1. -* It tries to upvote a Bundle that doesn't exist. (For example, trying to upvote the 7th bundle on sidechain #2, when sidechain #2 has only three bundles.) -* There are no Bundles at all, from any sidechain. +Any bundle which fails to receive a vote, is downvoted (and loses 1 ACK). If a sidechain has no pending bundles, then it is skipped over when M4 is created and parsed. -If M4 is NOT present in a block, then it is treated as "abstain". -If M4 is present and valid: each withdrawal-bundle that is ACKed, will gain one upvote. +==== Examples ==== -Important: Within a sidechain-group, upvoting one Bundle ("+1") automatically downvotes ("-1") all other Bundles in that group. However, the minimum ACK-counter is zero. While only one Bundle can be upvoted at once; the whole group can all be unchanged at once ("abstain"), and they can all be downvoted at once ("alarm"). +To upvote the 7th bundle on sidechain #1, and upvote the 4th bundle on sidechain #2, the upvote vector would be { 07, 04 }. And M4 would be [0x6A,D77D1776,00,0006,0003]. -For example: +If block 900,000 has D2 of... {| class="wikitable" |- @@ -347,7 +314,7 @@ For example: |} -...in block 900,000 could become... +...and then D2 wants to become: {| class="wikitable" @@ -383,18 +350,29 @@ For example: | 22,559 |} -...if M4 were [0x6A,D77D1776,00,0000,0001]. +... then M4 would have been [0x6A,D77D1776,00,0000,0001]. + +==== Saving Space ==== + +The version number allows us to shrink the upvote vector in many cases. +Version 0x00 omits the upvote vector entirely (i.e., 6 bytes for the whole M4) and sets this block's M4 equal to the previous block's M4. +Version 0x01 uses 1 byte per sidechain, and can be used while all ACKed withdrawals have an index <256 (i.e., 99.99%+ of the time). +Version 0x02 uses 2 bytes per sidechain, but it always works, even in astronomically unlikely cases (such as when >1 sidechains have >256 bundle candidates). +Version 0x03 omits the upvote vector, and instead upvotes only those withdrawals that are leading their rivals by at least 50 votes. + +For example, an upvote vector of { 2 , N/A, 1 } would be represented as [0x6A,D77D1776,01,01,00]. It means: "upvote the second bundle in sidechain #1; and the first bundle in sidechain #3" (iff sidechains #2 has no bundles proposed). + +An upvote vector of { N/A, N/A, 4 } would be [0x6A,D77D1776,01,03]. -Finally, we describe Deposits and Withdrawals. -==== M5 -- Deposit BTC to Sidechain ==== +=== M5 -- Deposit BTC (from L1 to L2) === -Each sidechain stores all its BTC in one UTXO, called the "CTIP". +Finally, we describe Deposits (M5) and Withdrawals (M6). These are not coinbase outputs, they are txns on L1. -By definition, an M5 is a transaction which spends the CTIP and '''increases''' the quantity of coins. An M6 is a transaction which spends the CTIP and '''decreases''' the quantity of coins in the CTIP. See [https://github.com/LayerTwo-Labs/mainchain/blob/391ab390adaa19f92871d769f8e120ca62c1cf14/src/validation.cpp#L688-L801 here]. +We call a transaction "M5" if it spends from the escrow output and '''increases''' the quantity of coins. Conversely, we call a transaction "M6" if it spends from the escrow output and '''decreases''' the quantity of coins. See [https://github.com/LayerTwo-Labs/bip300301_enforcer/blob/master/src/bip300.rs#L462C1-L462C47 here]. -Every time a deposit/withdrawal is made, the old CTIP is spent and a new one is created. (Deposits/Withdrawals never cause UTXO bloat.) At all times, the CTIP of each sidechain is cached in D1 (above). +Every time a deposit/withdrawal is made, the old UTXO is spent and a single new UTXO is created. (Deposits/Withdrawals never cause UTXO bloat.) At all times, the specific treasury UTXO ("CTIP") of each sidechain is cached in D1 (above). Every M5 is valid, as long as: @@ -402,19 +380,18 @@ Every M5 is valid, as long as: * The new CTIP has '''more''' coins in it, than before. -==== M6 -- Withdraw BTC from a Sidechain ==== +=== M6 -- Withdraw BTC (from L2 to L1) === -We come, finally, to the critical matter: where users can take their money *out* of the sidechain. M6 is invalid if: -* The blinded hash of M6 does NOT match one of the approved Bundle-hashes. (In other words: M6 must first be approved by 13,150 upvotes.) +* The blinded hash of M6 does NOT match one of the approved bundle-hashes. (In other words: M6 must first be approved by 13,150 upvotes.) * The first output of M6 is NOT an OP_DRIVECHAIN. (This OP_DRIVECHAIN becomes the new CTIP. In other words: all non-withdrawn coins are paid back to the sidechain.) * The second output is NOT a zero-value OP_RETURN script of exactly 10 bytes, of which 8 bytes are a serialized Bitcoin amount. * The txn fee of M6 is NOT exactly equal to the amount of the previous bullet point. * There are additional OP_DRIVECHAIN outputs after the first one. -Else, M6 is valid. +Else, M6 is valid -- and the funds are withdrawn. (The point of the latter two bullet points, is to allow the bundle hash to cover the L1 transaction fee.) @@ -429,6 +406,8 @@ without it, sidechain numbers 0 and 128 would cause the legacy script interprete If an OP_DRIVECHAIN input is spent, the additional rules for M5 or M6 (see above) must be enforced. + -==Backward compatibility== - -As a soft fork, older software will continue to operate without modification. Non-upgraded nodes will see a number of phenomena that they don't understand -- coinbase txns with non-txn data, value accumulating in anyone-can-spend UTXOs for months at a time, and then random amounts leaving these UTXOs in single, infrequent bursts. However, these phenomena don't affect them, or the validity of the money that they receive. - -( As a nice bonus, note that the sidechains themselves inherit a resistance to hard forks. The only way to guarantee that all different sidechain-nodes will always report the same Bundle, is to upgrade sidechains via soft forks of themselves. ) - -==Deployment== - -This BIP will be deployed via UASF-style block height activation. Block height TBD. +==Backward compatibility== -==Reference Implementation== +This soft fork can be deployed without modifying Bitcoin Core at all (i.e., via [https://bip300cusf.com/ CUSF]). -See: https://github.com/drivechain-project/mainchain -Also, for interest, see an example sidechain here: https://github.com/drivechain-project/sidechains/tree/testchain +==Deployment== +This BIP deploys when/if >51% hashrate runs [https://github.com/LayerTwo-Labs/bip300301_enforcer/ the enforcer client]. -==References== +Ideally, a critical mass of users would also run the enforcer client -- this would strongly dissuade miners from ever de-activating it. -https://github.com/drivechain-project/mainchain -https://github.com/drivechain-project/sidechains/tree/testchain -See http://www.drivechain.info/literature/index.html +==Reference Implementation== -==Credits== +The enforcer is [https://github.com/LayerTwo-Labs/bip300301_enforcer/ here]. -Thanks to everyone who contributed to the discussion, especially: Luke Dashjr, ZmnSCPxj, Adam Back, Peter Todd, Dan Anderson, Sergio Demian Lerner, Chris Stewart, Matt Corallo, Sjors Provoost, Tier Nolan, Erik Aronesty, Jason Dreyzehner, Joe Miyamoto, Ben Goldhaber. +Also, several example L2s are [https://releases.drivechain.info/ here]. ==Copyright== diff --git a/bip-0301.mediawiki b/bip-0301.mediawiki index dc3eb15e60..b6fc9e3036 100644 --- a/bip-0301.mediawiki +++ b/bip-0301.mediawiki @@ -15,9 +15,9 @@ ==Abstract== -Blind Merged Mining (BMM) allows miners to mine a Sidechain/Altcoin, without running its node software (ie, without "looking" at it, hence "blind"). +Blind Merged Mining (BMM) allows SHA-256d miners to collect transaction fee revenue from other blockchains, without running any new software (i.e., without "looking" at those alt-chains, hence "blind"). -Instead, a separate sidechain user runs their node and constructs the block, paying himself the transaction fees. He then uses an equivalent amount of money to "buy" the right to find this block, from the conventional layer1 Sha256d miners. +Instead, this block-assembly work is done by alt-chain users. They choose the alt-chain block, and what txns go in it, the fees etc. Simultaneously, these users "bid" on L1 to win the right to be the sole creator of the alt-chain block. BIP-301 ensures that L1 miners only accept one bid (per 10 minutes, per L2 category), instead of taking all of them (which is what they would ordinarily do). ==Motivation== @@ -32,9 +32,9 @@ However, traditional MM has two drawbacks: ==Notation and Example== -Note: We use notation side:\* and main:\* in front of otherwise-ambiguous words (such as "block", "node", or "chain"), to sort the mainchain version from its sidechain counterpart. We name all sidechain users "Simon", and name all mainchain miners "Mary". +We use notation side:\* and main:\* in front of otherwise ambiguous words (such as "block", "node", or "chain"), to distinguish the mainchain version from its sidechain/alt-chain counterpart. We name all sidechain users "Simon", and name all mainchain miners "Mary". -Example: imagine that a sidechain block contains 20,000 txns, each paying a $0.10 fee; therefore, the block is worth $2000 of fee-revenue. As usual: the sidechain's coinbase txn will pay this $2000 to someone (in this case, "Simon"). Under Bip301, Simon does no hashing, but instead makes one layer1 txn paying $1999 to the layer1 miners ("Mary"). +Furthermore, here is an example of BIP-301 in use. Imagine that a side:block contains 20,000 txns, each paying a $0.10 fee; therefore, the side:block is worth $2000 of fee revenue. In BIP-301, the sidechain's coinbase txn will pay this $2000 to "Simon". Simon does no hashing, but instead makes one L1 txn paying $1999 to the L1 miners ("Mary"). Thus, Mary ends up with all of the fee revenue, even though she didn't do anything on the sidechain. {| class="wikitable" @@ -71,119 +71,88 @@ Example: imagine that a sidechain block contains 20,000 txns, each paying a $0.1 |} -Bip301 makes this specialization-of-labor trustless on layer1. If Mary takes Simon's money, then she must let Simon control the side:block. +BIP-301 makes this specialization-of-labor trustless on L1. If Mary takes Simon's money, then she must let Simon control the side:block. ==Specification== +Each candidate for next side:block is defined by its unique side:blockhash "h*". (Even if the entire rest of the L2 block is identical, different Simons will have different side:coinbases and therefore different h*.) -Bip301 consists of two messages: "BMM Accept" and "BMM Request". These govern something called "h*". +BIP-301 consists of two messages: "BMM Accept" and "BMM Request". -So we will discuss: +# "BMM Accept" -- A coinbase output in L1, which contains h*. Mary can only choose one h* to endorse. +# "BMM Request" -- A transaction where Simon offers to pay Mary, if (and only if) Mary's L1 block contains Simon's h*. -# h* -- The sidechain's hashMerkleRoot, and why it matters. -# "BMM Accept" -- How h* enters a main:coinbase. When Mary "accepts" a BMM Request, Mary is ''endorsing a side:block''. -# "BMM Request" -- Simon offering money to Mary, if (and only if) she will Endorse a specific h*. When Simon broadcasts a BMM Request, Simon is ''attempting a side:block''. - - -=== h* === - -h* ("h star") is the sidechain's Merkle Root hash. - -In Bip301, a sidechain's coinbase txn acts as a header (it contains the hash of the previous side:block, and previous main:block). Thus, the MerkleRoot contains everything important. - -Note: in Bip301 sidechains, "headers" and "block hashes" do not have significant consensus meaning and are in the design mainly to help with IBD. (In the mainchain, in contrast, headers and block hashes determine the difficulty adjustments and cumulative PoW.) - - - - -Above: h* is located in the main:coinbase. h* contains all side:txns, including the side:coinbase. The side:coinbase contains many "header-like" fields, such as the hash of the previous side:block. - -Mary controls the main:coinbase, so she may select any h*. Her selection will determine which side:block is "found". +As a miner, Mary controls the main:coinbase, so she may select any h*. Her selection determines which side:block is "found" -- and which associated BMM Request she can collect. === BMM Accept === -To "Accept" the BMM proposal (and to accept Simon's money), Mary must endorse Simon's block. +To "Accept" a BMM proposal (endorsing Simon's side:block, and allowing Mary to accept Simon's money later in the block), Mary places an OP_RETURN output into the main:coinbase as follows:
-For each side:block Mary wishes to endorse, Mary places the following into a main:coinbase OP_RETURN:
     1-byte - OP_RETURN (0x6a)
     4-bytes - Message header (0xD1617368)
+    1-byte - Sidechain number (0-255)
     32-bytes - h* (obtained from Simon)
 
-[https://github.com/drivechain-project/mainchain/blob/8901d469975752d799b6a7a61d4e00a9a124028f/src/validation.cpp#L3530-L3572 Code details here]. +[https://github.com/LayerTwo-Labs/bip300301_messages/blob/master/src/lib.rs#L252-L264 Code details here]. If these OP_RETURN outputs are not present, then no Requests were accepted. (And, Mary would get no money from Requests.) -It is possible for Mary and Simon to be the same person.They would trust each other completely, so the BMM process would stop here. There would only be Accepts; Requests would be unnecessary. +It is possible for Mary and Simon to be the same person. They would trust each other completely, so the BMM process would stop here. There would only be Accepts; Requests would be unnecessary. When Simon and Mary are different people, Simon will need to use BMM Requests. === BMM Request === -Simon will use BMM Requests to buy the right to find a sidechain block, from Mary. +Simon will use BMM Requests to buy the "right" to find a sidechain block, from Mary. + +For each side:block that Simon wants to attempt, he broadcasts a txn containing the following as an OP_RETURN:
-For each side:block that Simon wants to attempt, he broadcasts a txn containing the following:
-        3-bytes - Message header (0x00bf00)
-        32-bytes  - h* (side:MerkleRoot)
-        1-byte  - nSidechain (sidechain ID number)
-        4-bytes - prevMainHeaderBytes (the last four bytes of the previous main:block)
+    1-byte - OP_RETURN (0x6a)
+    3-bytes - Message header (0x00bf00)
+    1-byte - Sidechain number (0-255)
+    32-bytes  - h* (obtained from L2 node)
+    32-bytes  - prevMainBlock (the blockhash of the previous main:block)
 
-We make use of the [https://github.com/drivechain-project/mainchain/blob/8901d469975752d799b6a7a61d4e00a9a124028f/src/primitives/transaction.h#L224-L331 extended serialization format]. (SegWit used ESF to position scriptWitness data within txns; we use it here to position the five fields above.) - - -The Message header identifies this txn as a BMM transaction. h* is chosen by Simon to correspond to his side:block. nSidechain is the number assigned to the sidechain when it was created. preSideBlockRef allows Simon to build on any preexisting side:block (allowing him to bypass one or more invalid blocks, details below). prevMainHeaderBytes are the last four bytes of the previous main:block (details below). +h* is chosen by Simon to correspond to the side:block he wants to mine on the alt-chain. nSidechain is the number assigned to the sidechain/alt-chain when it was created. This txn is invalid if it fails any of the following checks: # Each "BMM Request", must match one corresponding "BMM Accept" (previous section). -# Only one BMM Request is allowed in each main:block, per sidechain. In other words, if 700 users broadcast BMM Requests for sidechain #4, then the main:miner singles out one BMM Request to include. -# The 4-bytes of prevMainHeaderBytes must match the last four bytes of the previous main:blockheader. Thus, Simon's txns are only valid for the current block, in the block history that he knows about (and therefore, the current sidechain history that he knows about). +# Only one BMM Request is allowed in each main:block, per nSidechain. In other words, if 700 users broadcast BMM Requests for sidechain #4, then the main:miner must single out one BMM_Request_4 to include in this L1 block. +# The 32-bytes of prevMainBlock must match the previous main:blockhash. Thus, Simon's txns are only valid for the current block, in the block history that he knows about. -Most BMM Request txns will never make it into a block. Simon will make many BMM Requests, but only one will be accepted. Since only one BMM Request can become a bona fide transaction, Simon may feel comfortable making multiple offers all day long. This means Mary has many offers to choose from, and can choose the one which pays her the most. +Most BMM Request txns will never make it into a block. Simon will make many BMM Requests, but only one will be accepted. Since only one BMM Request can enter the L1 block, Simon may feel comfortable making multiple offers all day long. This means Mary has many offers to choose from, and can choose the one that pays her the most. This BIP allows BMM Requests to take place over Lightning. One method is [https://www.drivechain.info/media/bmm-note/bmm-lightning/ here]. (BMM Accepts cannot be over LN, since they reside in main:coinbase txns.) -==Backward compatibility== - -As a soft fork, older software will continue to operate without modification. To enforce BMM trustlessly, nodes must watch "pairs" of transactions, and subject them to extra rules. Non-upgraded nodes will notice that this activity is present in the blockchain, but they will not understand any of it. -Much like P2SH or a new OP Code, these old users can never be directly affected by the fork, as they will have no expectations of receiving payments of this kind. (As a matter of fact, the only people receiving BTC here, all happen to be miners. So there is less reason than ever to expect compatibility problems.) +==Backward compatibility== -As with all previous soft forks, non-upgraded users are indirectly affected, in that they are no longer performing full validation. +This soft fork can be deployed without modifying Bitcoin Core at all (ie, via [https://bip300cusf.com/ CUSF]). ==Deployment== -This BIP will be deployed via UASF-style block height activation. Block height TBD. - - -==Reference Implementation== - -See: https://github.com/drivechain-project/mainchain - -Also, for interest, see an example sidechain here: https://github.com/drivechain-project/sidechains/tree/testchain +This BIP deploys when/if >51% hashrate runs [https://github.com/LayerTwo-Labs/bip300301_enforcer/ the enforcer client]. +Ideally, a critical mass of users would also run the enforcer client -- this would strongly dissuade miners from ever de-activating it. -==References== - -* http://www.drivechain.info/literature/index.html -* http://www.truthcoin.info/blog/blind-merged-mining/ -* http://www.truthcoin.info/images/bmm-outline.txt +==Reference Implementation== -==Thanks== +The enforcer is [https://github.com/LayerTwo-Labs/bip300301_enforcer/ here]. -Thanks to everyone who contributed to the discussion, especially: ZmnSCPxj, Adam Back, Peter Todd, Dan Anderson, Sergio Demian Lerner, Matt Corallo, Sjors Provoost, Tier Nolan, Erik Aronesty, Jason Dreyzehner, Joe Miyamoto, Chris Stewart, Ben Goldhaber. +Also, several example L2s using BIP-301 are [https://releases.drivechain.info/ here]. ==Copyright== This BIP is licensed under the BSD 2-clause license. - diff --git a/bip-0301/images.txt b/bip-0301/images.txt deleted file mode 100644 index 2fbbf63716..0000000000 --- a/bip-0301/images.txt +++ /dev/null @@ -1 +0,0 @@ -Images used as reference in the documentation. diff --git a/bip-0301/m1-gui.jpg b/bip-0301/m1-gui.jpg deleted file mode 100644 index 8f3aab1a5143052951672915b341d9b28aa88a01..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 113155 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 ZTiIeuWA%cqyjbkHua(pls}wB4{vV~@%Vhun diff --git a/bip-0301/witness-vs-critical.png b/bip-0301/witness-vs-critical.png deleted file mode 100644 index 79c84b1fc5ddd95f0c574951e91f50ba7efb925b..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 268309 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℘uCy2$hoxOOl^Dty_~{bh|%!c*&Jd}fT2 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

_t%5A+A-%HF zP8K!2r*!vk3;IR@R0ETY68!6mV0|ou1j;KWv!B ziPBu(*~v0I4%%>aDNasPQ#p&&yr$qH;G`3&AzszNts${zysE0$ z;}l*1ULYv1l*!y`jf<<_Hh$n4QWm)Oiw9+GwB{D0YYnj98yRL7mD*a#%Uj8#3!;c{ z5kj*l$ccacU`G`&3h9|0>#s89O%%$3@9HPUmM~v^Yu@Y%t$2pP8xkT$gdSipAAq=B zL-;83{byhj6VsHJ7sxO{)PSl{E<%pGiHK;ap?RvM`RN11N>}~?RaDeQORF=Rhk{(m zUP?+%R#r_8O*(K?SN%EE9)WIniPQB;xR8VjDc2IMFDjt?B#e-IWXU#Pfjd8Ms?|#e z2ghjT01cx0ke4W%NMQu8v|y>Hiji%4!T>*?RtK4C^o^{+f>c139K+Z2V@b0O8#bcQ_K# zhd&wAqUpG9iRRiQFFIHl!%2RoO-M$mpWkh)`51T~2!0(it3xNXGBc>XSrU4>8TOX9 z6@q~_I5!dw^vBF86A218;Wm<%2LS2&m~-ND*k@t^;D9NP=B3iWw~mV{?Uje^kSkX zaA}N>J2 zGuJmOLL4cqUyF)nQ_m}Lp_xbO3J{VtW++L4NOtME154?4ew|tg@+9ut` z!XkV-+c^}zvwJ%+uy>Frcc$9{4+Tq|yB%nvc5DiIM|ijo3Gkyzgnijvi}__TP)x0m zd1Re4;fvbw>%R3VZ)~Tc<%Wk>TE#((VP8EBZn6hO1TANw30*7vnE z)x?Vivv<9wU&Y8dOen`|QXo?KC zfg?yF?APUmC%=(|t+3C+YFBS-y~4IZHjwOKpp@}7+~UfgG1uh{S$SEx2J7FkI?qkl zBqKh2P>~sW-^CIplJ#T5M4w=j%MF_~dwjuZ_u`kg@@M6!VCSvB>bTcxUl;>P_fd z10~coYxWQ*Y5D-?<6PqygoediQ`6Kf;cSwd{uS;ItB#7wYaBGi&v%z8q~09%E*Y*{ z5g!|NWuLIRvDUB$(;T zf2wvllfKXVdcUscE%)}5{_W&Xptnbp5iFqjzgFCFG?vSL_THoizv6F{!)DbBe7A+x zB|?nq%?$*jv7Vnd(26moTHfAvM&&EgSRx|M z-@378lx63sUhU#ZQN%lJVv1&1-#>u$|I_s`)jT_jtgh@=;@g-uh{A&B@#5&aU-CehA3q%4f`a zh^TkPINdc|tCCoe)GKEvLGsCYR1gC#qe@I)-#2;LS!9$hZQHgb?-%e0p4YG)P$n<$ zE!$UC$BW%U7#QPTVFt1b@=)H0qoqu4-<|2Q0k;LLB>33!Z}D+>Wrbh>d!=F-@pNfi zN=$tz^&TItQA{i;^>$NY+?vy42K zqabuq2yQ9Sf`uZxEa@30Dr%@c zdzgrI4wSW;M!Xa~AMP?(JF;Ujgg^PGA%YdH>abOW@k(sZHK@D4&q7v8zoDVOWS;^B zEAZ=+LV$kG$y(sUG296{&~C%uzn3uTdBw|@6XVVXPgvgo8#jA?NL>Dsca59;+hOR< zz1ibqcwgVYal%=#pOyAtUnMDF>HPgyuZ%zv*dDZ=Hnrk63YgXe^F79=h2+CG#Q9Os;ibQ za20XM1WRr^0=b(!Lq!}n9<>MBMM8w?!^1Z)NG+2=#eI^fpdHVt?ar>Npnp^Q|Dx+H zpsMWF_TPnw3KG)Y-QC^YAl=>4-HixHgLF624HDAQA+2GgU)S%tAIHVZaHQ7|H*s+XVc0h^T0wj3QyJ-tK#-5-B^G$AcS1$2{6JJl zMCt-=Je;B;@J51S5L>J>Wr`1YxW0~zfGV@21-GoE)Jj`3C*-90`BNfn5Z@2pH_Can zc5xYqI!!UDuHyDI-F|__{L#VvhQI93&5%H}-pc(nFs8%T#2Adiqt4nE>f1soM;5vX zh+S?^Yi_=L--#5S`0s6()x|N;-u(q$gy5`~qWhGxHXK$FLtR(7kZk?d7A!B%VG0BJ z_IiA}JwA%9=)anP!8hhz2ft%Gj=6iXE659M0|bP5bpO^2K2U-TTPCnwr_FDSp=DKR z!Ly9jl-1TAYSz`A+*k~#m~c(Q;CXeNbs!Pr5t6V|@07Z!mh7up@agd(mR9$>?YDe; z;(Dr?X#DyKe77Rqf{H?)TL%Qw+eg<1x=` zxhe&`4!fn9Z$j&WE=nw312Lt6fhrfdyU|@=m8_L5wl-%vePGpS^tpwoyE!g)WRZjU z5I`kd{OT1+emHzL5TRyPI`Rt&uD8PZ{z`XbWMbla__3)85n{jxo)hpFU?<9H>TRf6 zTs%!<4b9ASCLt{(gL)m6AVL}(=YB@wa_>i?Ii8J#^*+L(1CqGX6&v~81BZ;Ck`ht^ zkCgJR%tDRN4<7QT1sywRD2JU!|S@UCS1VVIB@hNy|MhzLK%*fh$Qg%TSQsQ$SqN-uBv2&9)8xr+qsA6)>qf)w_ zGtO-{4vq3-v+m__`OYqyPM6ESSpce8o6S_f>9MghDG8H>pw-jSftHVrg0k+740a3g z2AvVGwDcq??+>-886DtzPpRBl=mJ?r(cewU)RmXxqM+>Z@C;(B_0G(=EY>e#GMc)_ zav>m)dB5BYL4>?w)FRn-S|b!xc&LmRL3i8f!Ebjdjp+6CUk`arYKI3%Ehiatlj(87pBrgTbl_y3adHm$yn~;ZV0Xmk-j8AHF_CAbYHm zBx*EL{n>~DM`vTRMI-?kKAuQ15JQd*V}ym3%Af{!jaZ2C=jeQWO02EPiHSXuUxPjF zcm*0VZLjr>64@cn?UV>Ic>Icb0>zqz6r5H{BD{D&hZf333lI5)lapUxUuB_gz*3i^ zwmbMvRD$VV7Ks+$h@~$lzPhhEL{HE1oxl%PvBkItuhnx4hy15EJl|1I>E!9wiUzuT zFlB9X$_qDkn4f=NNaDuY-g!OEQ-t+@Px=nZXQ%*&Rue%=Zbdv>D-9L()~z+2N51Xy z^3tvmnNCbsgQTifkGb%~%Ht~4?9Lc2EDw(#8f(l~@YClkK?E>qO!5)Qgpi7J1N1L= z?(~;lIu=XOj?>uI(Np_VOUUki&$n1K%k~_0>05^j>d459?<<6^5`lWBF9{G{Ck3CCW@k2!ohXlfPR4%*yLz>W132&J(laxk zZ`O<%-1`&-e@`;Yz#dCR^Ez$TwB276$`0Uj_ZYIQWpj1gSz=urRR7^#yx$n0B@}$m z$!rx7E9tk+MS&+6<921NQMpe=&FtbfMqGdh1!0E{mM&Jv?UJ-zOmsgpzMITf!vR&Z zw%dvR>~t~3@p0dWDB$Q}=yu?Ad9pUuI8KDXR<^X1zD9&3?N4Qn&RLJ)1%D<5{U>sr zIdRwG{_bu@*OQ77)2WmP%S&h>dm)Gnd&txHpGWt4ua?7wV7^DtzXOMJl%L=A@KB6T zA86Hu?k6uogERyTv9REE+Bi6genp0dUsUO7zkg4kmWDkL1102;q=KHq%-upx+H3jX z0ka?q7aT+;@;k1&>wVlFvtlkLOmWrm3S*bh4Y9b6p8!w(B%y%M<@J#VEBY%^vo!&@ zq+u7=O8*Ori%n^IT3TI;H2Lh~uh!~DN=mzl)Cvdl2R|3iw6*t*O+MN$pZc8!>?+*f ze&BbZnwq~UO_@)9yl`^vMy^NgW>_bSnCl`o8{`yOX@`IMGUTwKhk^f;oNh0tu$!{}4jOd?B#4)?s_2k87rPADV zQ&OoTPoY?3W!-3Qk+Rw*nX3}XF1q1=2aCXXNBD_JT-M=434kE^Yh`;)ANZ5hqfPF zJDI#6gM-)Xm#Nl2fa^e$%}1S7%FOQe{FGwgj}MTdgYIB9ginXh58=~wsr4C z?HM&-WU5_VrpG6Mda`K3Qk7Bn+fDBw2EB}+7u(6YI07o_MH;J)vs1j=VUCsMI|L$J z|K}c?d1H+#m&YSc1l8$9jp`{R!nxWSVK!2#SqND!*au43UnOv#7iX^$3O;$g(&Zxy$-}ISaI-B%-cel&F8o1Q@&dv+LuK|X!PeI|~!hr~*Ei$sWII++| zLPrM{#z(EXmz9-i#R}4e0u!~hICn=)Fd9{S292XuD?GwFOKtq#mizmCai;&;gP;pw z65!Dej95r35>tU_p>loFr1w>5Z79;nw6Ch(|fOa&YaHc}!MvMfn|8`%Gv-;dO3W zom_fGha7olotL!IHEvOJh{2eAH3J1n7)tmuJykoN(Oq4#f6zw26B1q@N8C(kw7$LV zc`*0o>R_YunE+DaayLk?(~qL^^;C-v@@sCM^ieisWVOT6Q`AnIg(U)+AChBaAM?c$ z6jR`E&Sum}p2B}LWwuFHTVV#|1owE>_bTnAMfrf%$f0^#4Y{@pP8F+q@Z}Euu1*rV z3JQu>dNa5jw!^mtOq8>bUcP^3`91h zE{|p8T3K#p2og4#Bea6Oab+wEf9~-!-(a61jq3+f4Gj%(3G39ft8D=~O9x8Cw@tZF zzHAqlWa*aa+uNjmchrtc9Fam0h*xiz=SrL8C3TwHR#Z%;9^gWNT^w9h!h{8kYHj{$ zeSd+9?a?&9E9;)QN{7~iuh=}i7W$G?=M+Nx20uoG0RKXMqeRZ1&MnG#@ zf83occj%(O+aavCDd{n6K3tJSlM6;BeOT@EZF4l?G5S2``T@jrP|vc+n;e{Bb+mSK z#Zcu-Cx8X_?c2%G5@5?x0S1#5GBny7Y-AepRAgg4_VMG#=e^?fxOYAyp#MWr?cPJg z2LF`u;c!xQ=OYG0&DGUHw+&;3wRb-bown85Minp_o|QlXrF^(w`|G3OT54%~g@yE0 zYFz-SWahJx%{)#t4!Qbdd1X!jS9`_HiPp&)bU;i8zclKn0)qF1Y$beb_4T~@QBSA8 zRbRZ2dxMUwrlxMe?}<|P!Dv4a8k`hLYHIz5OBz>~R;qD)Bk2cmb0d2reb5Nqd)jtW|n%540wY&JFw{TU%x9S46aDtXKKo zGBU2WO8iqNO9Qc-0vq5drV^Ue%-{-J>F8kUx4l}q?^fekG1?lAELQl;t(^oD+FX<2 zaS`lZCPhX=#rQ5#T+}X%Wd_U1e`w=ErcAc2S?_Mq3k+*zL+6flIIyLyE`9g$docWK zt#r*n4nyakK)iz(I`D_2-pXO%>*1TtZb4E*YeI8ZUnBUrE=Uewx|x|tT2c2-DEaqA zj1R+{F6@?79+j0MySXq$M_*=UczsEIW)AxP0?Mgm#@$IpdvJ@jdw6V{o!x3_aabNF zdLlh#ptM|ddY%)DUFJ9jxw@r=oe?xtZ1nVnES%S*WX8;Gd4M{hM1F(D_hwf7or_Be zF7_T0;ggl|wg0>JWDJ0cq-SMymnb_eD3YMn*4EutRsxQL$IT6nFI)f>CHE^itLnsR zm6=s(j)aAdFjR5ldvy(srMdUVZ&9#aW@qX#F;(|mdMER}WoLRy%WW8G@+K@7=jK!# zMK*<1c7dr53Wfk9&<{F&1b7VSF`W8*1mGa?NtlsJKQodkkm1sR#i4$7_b0KD1+R7)t7@v)l)mn0 zY2|Eft%?#+yqwiisWkj$f+5YTTjck0@Ldf_dRjx^MK;#^NQA5NIfll6 zT76KDo-yCa*F(V@LZGp}L0&NhJXZ^|O>VX;BmCzpQ1HL}F`+3I|Nia2zVVqGKGpJH zFZlbV=N%@)y#IQ|L$+w_hd@F!HoSj+=D%L$j|%zw4I$m;qM~*Z{|}GMScmJ;F*qp5b9>${a&Q2HS;e(8lB&af*)%58pXFDmK4nzo>Tot2-zWt!1d>-QdMnk{2v2&HNWF8%!>a z-3hQ)k>StfzW~EiSRkcWP*S4l;fY*LMV>nPhEyt~C;8^Y^T!V$y=@-sUxrmJYJ;2? zUH3D20U>WP$eL6P#43k!f*aYPfvBOP^0Vn@Q`ql7SnW{fDYmhZRhJ=WRLbV|0vbY+ zVz$%%{yPMZ_xpa7snG=e;8s2^t1`y|5)8g<`_rw6qk6r`z!+3fkLzfVlx znH4B4BipwI9D1m{3$Z2R~PbihD4ekxZ6apq? ze~Pr3K!7hy$$@z1;dVJ7U~XAgEzE87>9LCc!lf8rAmjX?x{uaDU7hmjY~T$aCO4Ei zIP&RqOYCfHj`yV1ReKN2UkEvCYj3uD_KAFz)0pS}{JF0_A#}d#`{QYF$oOkGm@Py% z%?>Y61oxS>Z9U#ca66yglO6qJ-g@wC&p{AbMiNw$lvw{x=nM4v0|peiEJKJ#oukQd zi!&iC0k4~a8k+r)y0}EAZcF^U-tfC_$D>8+o$(D=rlES`>C!>Z3!2{Ez;CYrQpb9- z$_}^)`!2K`77`M-Eg5}PRKM>&+oPQrcS657*!i;r@FBJj51{MrdkFNw_^7H18dtQ3 z3^F8IiM!vuW-Ml&@67pqt=YXfENiFeiez3=Bw4F$X?Hx%N(6Chd)G#lOxM>2XV5QvW|^b9CVOY z;Yc4_bRVMNf|+j*wMq-Ig}Zx%!wgx7#(T4k^I#X3KpzE;w!_Z5GA=T)89mmRHzVB6 z;5R_X%w!)O_4xD&l;h~HUrYMm7W#|4Sfv024`s(C(pGi!v1*7W_kAF zu5WNRG$acMq-p|2mHeIvfwc~_tLftzrFJIyJ%((31C+r3cqo$JU6CzwJp1tl!oI1Fp1jrZGqG<@zKmxq zsO#Z3x!L`mEe``+XW<-~h!Ie^oc0fjA0Ii(y0EXlV**~#1klg*Rb^QMg-WFWdu%ed zXhN};8p-1XRVzRbmz{S2AaLF67~E}IM8Fm2d2YI#&c3>`*wxXjsje~axuXEUG|-iU zO$W8ncBsokxwo(Hs%dSo2`tm1M6~;@k)sqkW^me1tm*^0aIRDpL{JzQ=nfNz8cfY4 ze9uCo%F33~Sb_d)j3Pa9e`9xhyLlocwv|8${Lq_`6#TCHV^lwdu<#_~&1CvU1K-&V zl(6rWTB3#1Kg>skFz@<$pIHGq9-*nMKvU}LkG!m}G?9_qkH;!8u-dtMcQsDQ%gFQ< zAjwnSpQoQWfV#scB2vI${&WTmpE5glD+(66Tr}(9o_C$vUT9yiQMnfk*173v^2o zVs3s#1v7EC-}fj1yXY%MP*W_2g(-tj#h+WNrJrBR%K#x+9TOF$-~8dJTx0V@)cm(0 z5APRmuXMSr3NthE?XzJ*ey=8r@w(d!OiT!wX*y? zlqQE*owoN&V`Iy`qGdHfp`z5?rW2F|PiUy}Bg59}Hng?Jv^_nW>6UdpJpzqQUsD|) zy#R3s1YK`sQi{3{zN20Rl|`TLO=eaCs$ZCF7zW9@+gu+l73$casEt-ar8SC$_^5Feufr%(mN2>DzqCL9qkIzl#eGWDx-K zs`zxkSQ?){p~xp^-YQ+?@+P~q_6`QHBeF6wGnWEt-E(Z5H(sYiePdMu3{?PJ7@z#S z={rb=hx+^{_z&uiUK?+goD@W{<{4mrkOk& zOkGZ*AYCzvq{8N1k z)mmmB9{UC4PcVcC!14RLmJp%PZ)cBg38ku&?^#>zr|P`QfjO({^cT3EzPoZ-0#!cn z>P!7Eiaj@5F2%@XwWUok#v`D5Z}u|C88|r>n`hSTC&;WjY*)v zeYgKD^8WpMGY>A7Nz?I-RFeS}b#=fNqU6475stGGEm9RbmSl2sF8^CuR#E7KUfKeW zU;FA1yShbddertbo_ws$t+d3q8Tg>=MT3F6IkY)M+GNX&#}4O^;}H_rx9f}J zMGC-WTCP6g7rkHea5;gV2$C=XMnLbs9!cQ^F^5D9uQtd0#>z_YdDcpV#ry0}LiT-MSMn!Wmk8zvw9o&(AfUo;mV+D9K1fiHZPpQ>@{wq#GkH zoD%S|)<2*rx;xP2Y9h(zvNKi_3#?in>n`U;6$lagZ13ix+JTfyXeu}Z14M`kj;`Kz zn_e<0{BJ7d{i5$~X!y|Am&mo#^5%sbY;1j1y08$?#JME&A1ADpVlw<9>9w--xEWyt znscg@DThh_ACrNC<7wsh?>&yRj_q zlTNUVt5)z80p~qv6CqgdlI76V)jN!OwWp>Rl9J$PKFSJHch@4lfCNwGpH*)LjT=k9 zd?Ek#ZHs+bN5gHsg5&-^L}+OaqpN3l*lYbaXa)hyB5N_0Q8Y6%1N|BY1=T{(Hwy6= zKvS4%e)cTskYLP;vbpdaobH{+w$@*$1*`>hgnc~^`1u~IUFj7ii-G=q=$r0vPVrk(rc!Vjg>1Bs)mi!)~nVT&CT_nYe; zk&%Tu*Kowj$e5T^R>}Rn|A{tmS@ygH;!kU%o3ob}DA2*J@dOJimO1WVdc<6QbNX0DoUt2JpmQw zvD_T!z3Q5r1iHLj;=Z}$wW%P6eFWTXR16B-x>7U%5nnm1zFAy4(C@19eOm5W`qFH~ zWqY&;#JCqiz^-U7qKL)iEbtq{VteC-Gs6{XNdhI*(T2d>DN%-yt_@Um;xBqG8(}TQ z#m8~PzyJW*1-;qXO?kG$m;N4crPPp_4!<8&74-&<@V=%uhcL+h$|dkV$SnDY6#s7y zfPi`$2U5HVWi7o5!V8+kZpSpuow=H*pht>GzIw z{mj~+lT5J3R04_kdHwstN6g7J9CLGkN1JkTprOk7g`kr@pKk$*{Rbbv1;1bPF*F1L zED9LP-Cd81jaU$bSu`C+YvG(^%O#QAg zAd|pe#-Ww?Ve{V?%F_1svMOexT-<`nbhoT(jL%iZeHRcWx#NEogI59niB$9;9d3#+ zBhi|{?zIhlv1g&h2N=Fg=YKH#g1mL$PtTNsyCQ|(8}QTc5aYmKHPPCvH>a8^YGQm( zvdcB37k!aaZSIZ;5XeJva_*Wh=h3+t<3jVyUBpq}S2f@%1a{U`dullJN2k95RWEpP0S&1S zj9x1?2*{FB)xfN83Lnn^1bh_uU?zjbI`~RJi0)_*8F(g=CqE~b?6w+jLli*6)N5m( z<*^>3-6U)KAGkfk2Fmd8=}{;*ak(W}fFxN;&_a-k#@ZglbM|i*fHjM+rQ>VdfH5^5D>qh)*;|Hj(x)rN^kfXL1PT!-q#c76 z;O2u3vB!YHYJVS8xqV_Jo9UzH^eoW~Z@CXd2h^g}Oh!kZ%A^ zH1-Q|?|L9PJk0p;;NieI$;8fnjr8n=5~ z+J%CI%4FiaV*+=~A+T2Ibdu{$!qWo-=O6DuGwF14JM?!s{U>oiEnx5}lus^nCw#7L-FOQ|{9!pzXeHJv*r5vNoCI!oNhZqbm177vW5jVTMPEesjtKVAtVtBr^ z2&`}wWerJzP_9I4l=HWe_J)Qa{Q>OehOM30#YVf))s8wE##0+KhZgb{hDun@6^N;3VI_YdENNvmwovysW|$hs z1SG3VbYm|BlMQT6`<$*7g=~8T`AYxCRtk##o~1TLBq!arx&F260pr<$?`98A_xu(X zYpGbkW|w}-*jqO~+R;G9!Qn9*2A3O%5FizqTu9zk2(uRB_Hey)DELg*?gnz}Y2IFL z>gr}7xSd<)465$cFpP^48gbUA-Xq#eOM>- zr@FS@YN!X9Yj!e<^YkyDTfvkm%iEU$0O$lIl$Dj%?ItWFXQ7WN`rov>H5P7NZ5>nq zw>kV-qeNBJV4WC7PgNDL+rmC0D{ILLGsyY`5lHk0){BdX{H<*uIdyp?%hL(-%Y488 zIBush>#?(AcRfE%%+7*j5w4)%0H-{mk|q{aJ#z0^a>+w zCeUw3#^2qOw0=6> zpIX{H8~q5>lmD|hU&wjMrS8~-1_4MYzH%fo>NA|d-u86Q8h*|j|Pc03Y^|=zj|M6Z1=mk`tEOCxlI>&u2=|}{_?yq2WdXw zw_$Wyp+Yo0yki%d7;T5qeCU;DXRkhe@&!dCKthsNJLT2YUA3DO#wX7JjOp=*O;6{` z{7uvV{;v~Ta$-A2RjIXR()Rzu%1^{`vw~<)F~*cohKRlb7KL zsu^QZNtus*y}{sDcX6G?XL;E%+*DA!(IJsPe|l{XdBHJv~?}T01i3~ zHy1AZg}iT9stmH1>PYU1$#b1PR=dDDqm+{PXZ`&GM2t&fq6c8!?m0Ba(p{IjiS3WH zK`~sqoRuy5RfT`_e*t#48!@GCpvDgJC~Vq0PDxVuOPl8<-b4ijn`l(#DNz9$Xc5e~ z;?es#Ihm18L%yOSSip>>#?HQ=NeJJoU!|*sipmOtsD&aqgO*@J4Nne*f$SpTnln37 z^iD864t}msE$#<~L8p2vTf!s?SNeY?09K3hIpY8B@20k}c>Ho~WKv!V3V!FQ=hG^? zBuXVS-5)W)ZaDkBKW_^`TvN)9lIVnwI-%?TK%EC)6aHUFU@;3(e4V8hWo2-w>`n5+ zN~!f^Y5hhpjB)XGbo5O~+iFz+kB%8!RYtSBm;C2e$X&DsSi$(zFqcG`Sx6}Vjcn_L zS$?-0bT8YyKH?O7vRpqFxERAP{VdtT^mylLgT02&S1$=A`|IRj;rUi^y3JkeX<<>ybC{vi#F zTE6I#b=Uja!JyGM{)@Z06MTL;I@xa|cBkKrh*(vVlPKG`afpj=If!^k!)7BvQn2BH zE{M6c2@wMK7YN+@5(rY<8795sfSFX|snU~`Yt6&V4}@*L;bdd&*KSP=2pj0Ve(mPTEiam1ZN;7_0*078LkAF-rKqTj+Xnk=&D>>K2ET#t z72_kIK#>mV>Ff`m!h&B8tvl?7-WA}W07@bzbA}jQ)f)&|v841r@R+5md|Hh*SNGl6+>Jf$%)Fs5)AMR|xo-YV0NZ<{F)4^W+0E)*k`pf{>6E?h{dcUq(f29%!67Lg1tdXXLC%2wt_@sAx zE*jDSaGX!C>5Gdb!b2YQ{>?&@VrM088L*!~JjFI1-iZKgXizg?HogEOge5Akt1}LH7NP5qcRbZNgJ)ZW8c`8Ji zvJDkihN=2M&&C>q!eh&HsbF_J?5EmU4hH5p?hfx7)aUzsY29VqBJA8&~Nx%=MD=U8^!(x0B zE)s-vUGOtOXudGxjv0Q#EhT%Z_N!qG_H=5-C`n1u6t848msu1#*I8I!u2GH+dJ7GSQi)MpNGCT{P?Z%0sy6OnO zf7Vjn>RSOXQ;F2k-CQoZ_3>#$f|rnW1tia0)xUF$Jcdx1Q|>!=c!<}XCOrxN*5+7L zSFs}b%9izj;jVg(ly?nGabSR^<{$WuS0W>*s)E?MwLyDaC23^2061lGlz;|$x_3-P zUwKeCm+NCdTguT<_tKMJ7Zg{;Rb&0*igU=Sr9xNpyHEk038;oxPD>)dV$JnUPyz{4Th1s(Ia*=IrLrq16{w7Cg( zb}&6+<}GH#i1cWlI3RlfLjhu9K(&ne%0!Qg%lB3gk}ChjoZH(?U99gTI<3;s$3)+I zED4ExFZ1A0gf~J%P7}|dY>fdAn;j=Ow>ki<@%hh{$J?pGjTk&5rnD2qj9(mV(Lko> z%N_easN$O3$`vaBsA!#?Glkz{ zA~m(d-gsT4gi=a>7cH6z@?n2}_3`|zOZjKe#}r6|pF-H-%WJ(+>+Z178@?wQ>+~i4 zu=63lsB~y}Z0zYm@gy8+h?1x2>}FiRnZkT1{M)qVSU#YZ2s31A%@5m?mW~Z&&S~G=%IoQR;)uRPbRgDyc9-uOb z15;96RaBx~m&zPA-U|zIj>f}9gHFXl#Oei19DalLKfn%ez(mJxX?2^O>lAbpnOL<4 zBRCQhCU#IO)Q}ROunFD|qr8bK{<0}kj5fyWj`8|+*GjW;-|t->E;Rv9mBqTL^5ljF z(1eO>Y7Te$V$_+#YU==zD<0RSy2r5Ka0$@PX;oD~^EA!kD>X9_&f z(g9^Ksz;s;I12TZm2a!{dT%;PU0Q)UjH;MPV!s#5>!k(~$Qish?QKjEASgHeMuIcv zPomBIY3zTIkt~yR7C*|OB8UiX_kJ!Za``R4&nm8bQG$e{Mu4Neh>uY&=<^4NL8xG6 z5H7p#m6p2w+7}nwU$8sL;qRHQLMv+TRWNk3z%e$lnJi=d*SYE(#( z%TM7cDpo5Bk~2s?+!j|>i}?z+#1!EPh_Ii|xc8U!cCZ zUG6eV#^}D+DQB&1y3uYq@5VI9vAi+w@cIOl?5~-U6!tP{bOt{Ni$7%(=H@AX?p>rr zI*m-DTBkrAXxsA^^@Rgf7Jv3I2OI0b5Ul;Ot~CbY6e*mksZHY=P&hIo)0NA%SIMyNY{SveUUA`}YG`~C zkta^#C@7ZI){e%b0Xc!Ui=|Ov-G)q9@UMbB6XMkC z75rt4|M^q5;gg0TIzsS2f4N-=U2ggJd%&L@@HNGI|MiN4Z!|dnd=YC@=k@!^f4y*( zrxl|oK3b*Jc4)+gp5awtJRa{0<%?f|V)Vx>#gegOdDxBW?>UN!r?KF}9XDnKlj<8e z3W|nbzEDL%IfHxV zePO6CBd%F|S}PlfUG?=e0$CcGC2CZ3ch|1zTxVMuhO@;5GyI-CjPzz;FbNW274v1A z2m|BCm@4n{klbPmUa$HnTv7CT7uZl;eegiXm5l+X&x1b~7L1m;&@P%q2`cI7N~)?_ z{IgTC8SSl&b+ovn@yiJcV()Y&V#YB1I)V`)`(TLycVuiVxxTTMo^DlMk)St)AAG1||9(__R`D`9-?rP^=VHz{p@a&Tbg|eX zhRhX@$#xUqoFd752V&yOHI{})lHk7Q(Cc`)L|=*NRX_#k(#3pmZ^C7z$XQ9STQAPW z&}(M8I@_3E2TvzG_&mv#11^_qEMfWP%v8fW@To6nu@3AURNvF-NRY`aEy|FPf=ytT z4#WMIQ25zK8;&)0uBxePWRLSsZBMVx+qYXNk<)#VPyUZEkcX+MF_C2)US8B*-QvU& zMOoDNAnMOGmuJe3>4m;d$}~ynH8l-GLvW=t_1^9&6G}-DK0JjllVln&FeUG9Jx8-D znS+YquB@z*njAjj;v!U3+DSw!A&G*VbczzO>r&(BN?UNXF7bW0eR&BLn5JZ)Up4Ui z=j)eoqEgC|#fcN#yHswl`|Wb`m~*q=eg7EQIn@@F!WPo)V|{>w99L_H=HY(EZnx8U zZm^kkC{d$v7)w=7NR^tOf7T=;@lR~AP@G%skk``6QG$F6kpJQ%jd-d4Ze~XJ`X+^q zo%ywZhBb%HnTd()#;d0nU1h#4O?!X#i0yfihzKjkbHaTS3K5h8#-`-qt`(03{; zJ834Rn~|wakhl2#-`Lf74}!#IJHRC20xf=qti zpm5?RJiPuaej8A>U(qzFtBHNWonK~l%ep%Ky}_tY7K;iSi;0h?>-{Y7d7az;sRa5p zo0q}N6uAcs3}=zNXgAF}HVS8A>UX(g7*(A>4RdzCK@!Ak@E2t6Q1*GtlRMQ@Z8Jd} z;_9j)5&H@PE?#me^#VevN@;tOt(Kby7XbRBf_O@j;;uuUh3rMCi{(ciX3(%1D`KfYR!b&itlF# z{iGIZ#Tn30vRQr}BKtoGANRJrMk))>QrqJQDx=vKTrY0o~Wd}Zb zV+wf^F$Bm5Utcir*JYNmN#XM>`EZp%7q@R~WO=!-A(5Uz_5^$sqruZau#aSW*PZpC zq97DI_2*VIS>*vsg_qrvlL|)&<<3sX>>T>pYP%WnhGKrMy2+YjOk<4uXy)Sxl;I` zU;)4tX?$#lOF@uVWkS_fkJ zSN+#a=IB29J%UQHB^;4|se#sfy)VtvbH=Q^xl~$Hb^2t4QBOovURU>znHg9|G+mCQ zZg-bM?k6Yjq*JkD`}jJClka~v9T#dfsA3TMGx5P@TP{rr%j2#d5Cm|g;JJ^4s-4eI+tJw5 ztSk|>TK1ut>?2^XpJ zfyHl<1hhN%0g!Xl*M9f(;q@f;mNv2-^)#E=d{&2>Xz8gX#~-_7jgQtOEWlyFV6tL9 z`hgfmX}^puS(c2mNC90<9RV~2J779VDI3^;E!x~x^u7{Bpb6+ws)@Z%859Jgj48mc z(b|?UjUOB|bMJWS&`W%-tic!~c?1%b7 zpO~OAj}Aw6a(dK@v^6lcsZhQCQm+jSW#|{7znG2(!AXZkW@>7K_sxaLKtw296E-W~ z&RAic<_~Ue9P~HyrK;YHdNNYdCX$k(xL-a7zXBi=rWW_aLQm+<*clug_-665mz6%g z;g9DdKlY}x?bisvqaub`$+>T{=|v<5jCkD}H@A}|#L=_(m)iK}vJ|2-GcC~3-rcuI zTwiZ6=tg{SE{}l8apu=Ghx15(103Kui-d(8`g7F8EE)SEfFL|yKYCQ~DTf&= zi_j;h&f_I|lfAT#&PtJ@dp0vPWLK`}#C?rl(661EwT@hn&<=4}EKkzFztX{qn_Gb3 zNC1nMr;Mto*X@|h!RSW6R&02O(*M@%ddjA!lOMttigYtFHl1BeW6?&o zYTh^HPIr`tsut@w44r`eV5s^FJYit?pMrR9G5fN!qvg#ZmasH_n=-@<{ z&}34^eVcK-qP~tS?a}@R=IyB04TT$Di4^RWdg1v`O)VXr6SI-Q^2S9gX2n_8#+Jh^|EYTba=<&;Y{+9_e89@ z1)qie(+B4^;LcX(N4^qOJYlEl0e4wybL;i7>1Z82eQAZd%rAcx^VoTP za^kX1=R;!g4l&{m_2ir9^>Oh zn>Re5Qcjq;eE47^JtPRT?NmC$^Sn7Uk}rY(+bLFCOYaL;O)}b#oA07~F11rfKtF>d z>UPK!?53r=nbQR^)z+!rqL1Kn#Z?u9wx9UKa@W>q=7l{Nd`vx-K*{>^uogrT;9z8w zIe&`~n}C8=eX2Ym-nbZyU)c5dIeM7Ubklov0K?ACXl-hoXY4S*!Xi=!)AcB@#mp?z zvTU}mmS-K-*vLUD2}eVNqoO*r1|A@Nu9#tngL7@rq#*mb4li2va`Dj-0h}T9x2n7e_=I$Lqo%6j>^floF@33`sv4{{fhlqx_Gj#7Z6Ba>J)cRF*(UX;@}11NqDl z$UZ^Tj`Mw;tbDHJs8e(haKz^JPX!zWZAO0We{wgf%wrd|nZ$VH| zKZhh|V>N#AGIULntm_W$9}JqtgQs}8%1aKkCBmaU9AlUnbN6J z-6VmU`Ulwj^z^CunhD2#wL#vIP`1X2j79+m*J(?sY3t?&Mnar65%+;}tGzVRuyW~2 zV&XShffwuJgHUCP5EFa6c{9_W(Hz6Fba6lju`hIalVLdZff&wEXtO-C8+PhjZiyS z7rP1o5%TUML?7V;cHusL_QAd|f@c~If$R~525(?eFChPW^HY`(9krgGVtkyO0$-hEXG9fo-gA=aA10B`Iq09{^`JXCZ2kFN$c&7 z$qM3u!S+u%8r8m1k4?JT3Nh~j;xo+Wp>@1;uXAk7VTf)qdf0Nw4OX7x8Jy z-%NBrNBk-@NaOdY&Zn@{LZ`Cu37>n@c0H2oTbW3f?$PZa*%dW0(Yy^0hXQmg!Ppz!# zi5|Y2$qt2<^cQd5{F|)c%*u|;FFs&m4C^K_!xNTxR&C=VIxykVJljCc(z~1F_>#{> zsj20rO49FvGeQ?F0SnJgsHy#odxofJWTf9bHwkqsDDlg!NR}bIkGLoY3jc7WYF)J|uAuxAYcJvF^=8P%pHIrX0=ILCI|A z?hd5ONJK&E!s2(<=X+p1fw zp~!-#-3ieZR#j3--v=92DIveP5p8P=3id5`GE!0^Oql4oW*a;k7n<2@Y)sgR2FCjb zo&EflM+;nQuj`X@=?D9EmOT!z4K~M-5q#oLXOx`!Uvh9L@L!+qE*^P%L%2q_v?Nwg zgfQ~ryU9XU)Rcs06dNw@bd=|xF!@E`dMHBYlIiaT)*5I3SmO>iYSLy~xXFpYL}3~|Pp@9$O&ldq6|tzY-QyG7&;9@it5PlR$y$p7FEa9xpk%#$4c8H;op`_3`huF zX=&ddKPuC1QO6&y;o6-Rf7OXrcRfZDlr1X?JNTE~G^^r+ijvHqZ$qXs)z_#0`=dMz zjP`;O9|#neWr^KPNoHMLx<5NQ9zyo*0?q>f%2Babca&(?XzcBM33jS_Ws@1{@0(UY z{xva(F*tc^Ec{|QCReipkYOz z!Dml6Mszn|w{L^hbX7=0+1PZo_e44h!;^SM9bPD<;KXerA>ZIXQh8=uv$Qm(3>1MK zQlsYm6b5Qo|5jV$Sv1QJXzb)AmPonM!^BHjnsfC9^AEi~My0CJ z&+M;4!zfra2I2%p>~mRf)6Tk&E@p(v$-I>h_b;*SsdtC$iEi2E0C%;o&kLJ2ED9M- zTX{j7 z7ZgtI{{EB>+Z?53?j9Rs(;;`v$bM?lT3V6{&ky~?!(mm2FP}z59~elJ%t$|JZr)-u z#yTTJJR7%I_!g9xkB*2%MFn4wQ>4GR(nZhfif6BW&~Hw)7%G5xXW;a*Us^gb$+atG zHX>$p=YSp|J~@H#(uI|R(5YEpVKEMn)GaSllboo|7eA2|)3$aOA@Xzaxj13MsihlcbMCpDOjw8zvkdw>L_9 z4Bnj0nheIMgi>`HYz8ahVcWVMZNN27GCWnDiRxkYj`CmVjFHU9K&GIWdCGuR?=svr zbJbokiEUcN(2Z0C?6<|7;~ z%evlf;VDMcD%sy0xbO)z^mvw5iQD&2<%gxc!8oZ=dc`Ok=jjZwS9%51lAo+*-xA^4 z11sm-90)~@eh3-0Cc1F6b6tc) zKK%vL3Snv4qn_PF!CdD*-%97uzfEy#Waps47d5`GXv)XH`qj{4%67i-13t4apBn+3 zRdAdiJ37`QX|Y?V8Yd>c*Em)o-{CGTAS2}Ac5yfm{^;=l2cFZ0USLAJ94BR9JYc2X zGUNcp8DKlD>;Cz|XU9OXZr^QZ(5Fyz7KEW4g~fG#JgCn2?M$wGIQzhhw$rSMUzUQiq4iPC%b z@&9czv8YQ#zO(e746LbFAj{kPIR1r1T;9pT>u4U6vHK5SurHDFYXMV{Q%{DD>!-xf z?{Zg#R3PFQEn)so60I!%WVWo(t0u2t;{HbcZl60)uZuWtIK9s12TY5D-<5-!OFht1 z4E_c&H|CFzKp?nD5l~(X_Vta86K=Al@9$_&Hw}d-q~*Bp2!{SK?dY=T=u%>cHW7hJ z5?N5vin+qmQ^Qpk@hi``cVfw4>6O?i+A<*aI+*wMi^msPv>u<)y*9Dqo|t^iiegD_ zLf^G0oee+LMv}F+uP{R$m%EF(?tJWGYdgR1TLPV@IKZ+=iHIN*6Z2t+ zWj?E}xecs)`ou)hYEPAP0xAN4g^ULe(vgr;E{_siYx;3tGoBx(geNg!-z6FtRP;P~ zVso+stfCX3=E;hSnyCZSN?U{K_Zy0YR!ek6fNZ@Nh|g(gkjflyyOa95!6W$JKX&QK zKyew<#JQ(dv&_}+y^k-dq#nyLL^sA0nT!%61fN91X=bYNsOtsM0yb@jZ{w8D9c!t$ z0nbg1#v!6QLlN`!=dGa`4WF;~BrhXrhwt6P<+SDwA}`o$+8Z0Ylj3RhZ;`Dyhhx=J(n#el2Ko1}TwT}vntz_P+iny)^e_PBf2oa_+?`eN-??}s{ZePCI zOs#&K_27`Hw$_ZC_aWztNAYn-cv%B3N(Onri#ltMI1f+(sA}AB5pnhhvn}=;JsWnE z1a68NL-fMg$xG;{dnGD*c50u(CiW!S$nP^T4|f1D(U)M=IJvRdWUGa>@6F9Pufq>D zjJT0t^pMA^+mjt=g!w-NwI!6Osn}PSDt-NOot6gfB{dTj>i)SL{sF1r@#zw_yX`*k z9YlkJ=$jjD(F63g$i&9)1ZR*riw8Pi;bpL_7*NhJCdS>qxj z1EUUVtgqqn_6k^GQt#j19~e>bdqoj0ZWR`ib-fQi!}};HlGOcVXJ^(!_%*+ib#QwXw!PRz`r1E|~E|(|VIGx}&nn_Nmnj$pzr|vz|Jc&k&E7VGjQVe@?#P-+%q;j7kIt zkD{5qwcPp%9st!q(Qnm7P@Vi1OpZG+8!56|6z|#8Eo2fOpI#T|Y0dI3da75;;?l;} z-V!m7Gcx^@PhwC>5q8AvbT7HNO_w_kl6YHcm)H0 zy-&bM|B_$3(cs}>S%QZnE`16nnqP;H5;KpaSPYOO2NZy-^^9cD=@0*_F&i#{g>xaH zVlg@Xb}9@zOYP?=?q403?oNDgAQ15Q#W|~Wv`={!U0L)fN`k48B*#B*lz$L6k)LUK z*X8Hi{QiNM^e8WxJP!H+$6b{S&S4-Z^e)b&P6 zR_hEq!?t68cBmyO2%o1?{>?jtA_tM$?;h`>tF(F!mrV1$0JGYrnTu*Eg*J&h)1%<$ zM~kB7?rta<+T&SSVVaImgn-mimc2lN<=Pg%Pkc?lN-b}dT&(NPJAlqvBBCS^bfLl1 zy++5e0-j4Vb$#_sOlB3Oa(Bj&(<6uN@b15$D-K`lVmt5jme3oiaWsKRzbWyRm55-` z6WUh=I&z8`Vd7oYTM23%tF2P8eGxI7TNlp3$!GR@YikVO^Os}3#yh)Q>2J!bpqe>E zp=8U>YSvFdv-U=u$d@nRPlFTON&)kY`X0#RF>`e`O8dl|FCXPXsRW7>i0b% zX$eURkE74|2}&)9wEgONL9?F5h2t%x==6vrX+?(Nn7;3k5yeMaWu!0GlKz^c$ICiy zJpN3bQ|V5OXv4E$C+g;6FQuW+-8-`UmY!CTTfF4OSffnxj>FJc$90wTYte4gm>L5{ zZ{HgQT-6PR7}jv{CwPuVt@}2qd^osevQt~MS}1R9*}^7Ba51AlOWcSm0$5c@MR<5p z`ec1@bjLoHe{9W9P=dq=lAIa#cA zSkA=LyzVRGlRyq!YgzH5-1sPZ9Km=p7%P*iEln$E)Ohxd92rt>`NbCc=#Gak?tDx7 z-PwBw;S-`V5V2ykm#d7!7Es;E%<$~s5UA&{YrAyLJv20S{NhwEwPZ-3;CC4n70aV> z<;-=H^2Ov^%;?l~pX^zMGWX9T;}+m0DF?J0VSmOAVAk?-aHT}_adL8&mM!Drh&$Ex zxCzKVQZI1KGVkijtMg1*U;jaNEls(mfD{e`l(pzK>fKH|n`?zZ_R~010m-5qLz!6R z6Ulq5+)p$2&YVbFkw#myui7I4RFn#yAyqvs{;VtpQO0Rl97)2PqQS^q7EGu=FdUft%#o*Z5?Z@sKLHbDA4xH+jjaPRmX zV(w_Grmub>xD9G~gy7E!y7aJifWixE?ajdpP7l+FuRX39HDMN8B72EIL#cWOa>5pw z1S9auzU!krkqKKRMxf{a%EZ9Ne46>~^1^m)B%jQ7#jZSX^_d56=TIrAY2;lu!Y9N+ zLBCa5U!PN>xPb*gypKYh7~=y3PLe=DRHx;TaG6OO7mI8rGl+SjKYS3(#+K>Itwmwb z7B;>~IX}xq2+IQ~0n!LBg*PJ!k1|yY(7u1y5*8Uo&P`L?UF!3_7*L2dd{9a$Mevw1 z%u%r9s9Uc!^>KCm&CP#^5Y1J>OX7jXGCn5&VxU|e7#X?u{5cGzUK(#Ft2rNAK}iXFyhi?fdgKp}tlh6M zo7A(h-B(yI@=HLQ3lkfuH=em9gTg|}`Nk|Jf`Mj#NZyoB$o_EAx?Z<%+_&{kl0v$O zE_cCD;5NUjitL`~>BY$h#CsF+`|vE01)19|SsH3}Pk%gGT9r6Fj+Sq?v>qUS4rb+&%#D5& zs<86$JemK!nj(flJOY)#KEHdDv@~@Li{z=>0?A=&z9yu}v#{_PnAGB`sqD#$`{rh- z7E|K=xJ*KjRkaO2JQDyaJKW+>y@8C2^yq4@6XGG6^;lm-!a50&nTdHP3o~^&W)p_%%@d>F`*-5D}&*3f5rU_05EC< z@8#+0z*E%+78Yg^5pBtth<9zh0@w{SK=n-L$cJp#DmrXVY;xJku}8Pgy8S6HrU*%B zZ(fKEdsroBVq$%rI?eR5(dFd5-h@Lkd%N@AQbcD=MoaK|iCa}#K2t*;yRe>S!Ok6I*Su&Ta(82UG$$6#Y=XqZcRHFdqg zNE*%?AZ%^7kwUVKK|A4>)bu{D(wWV4SptA}O-YG}hO>Yc1FVs8C5>2#b@};$LS0bz zPKHwg`wZFTYkcM*ey4W;dyAkQZ~^*SiOK&Zj=lZ(d^_&bCuo~smJ1}kvO7OIqm|A3 zj6TT5_QUmn4kX1yFvGf_p>02<_Y?YSe3q=M9iPIVJ(d&fS>f{fqM|JYSd%~Y|3?eZ z5YpiE$kO5;j=G?8R>nsyMh}k-0&N{~={g3vaICur<~MZHUNJUdQlzA`!T{iANi;I- zz|r918GZf?r{L4p)SK8X`53H;r+&ac&Lr}?@043Yc2xBlb9AO*8|KBxJ7tH3S&4kc zOXkAPF4*SK|5RD@+XR5d&5aUbj7oYLg!zx|+NStjKt`L{ai z`cFZTlT%(qWH^bZHHkc)eOFoWLKh^)wpB}md}k{w*m`PkuRT)1sR(EVS{y`HYtlj!t6=*wn3 z%ebtBY3cnYrA5ZQ{2C4X=Do?lp~^#pKj4^LAC$fGgGqR&v$IoA@4@EAP^dDJS5b!k zyH~FORJ|97cjLwXmYIYDinBB)3?$+cPU{v}=}t;^MPbI{B_h|?)^J5(eTZ>3f5%TL zzRLAD|EQ3ISus0=f+;<ah`b2@Ng?olBV8X+f(1B1dAVeOUtY4A70|QpPL0e7efJ_A*WoWW3?nduj~B4x%uQ) z0ZOLAcvLj?_k7@?pxhX)$Xv#HBcc(n#mKQeo#1k@9V7DpBkeDj1(AHt&z`2?GB(;P zYb*~_`hvnROVgWeQ`8Kq#%;|DEylgy-0F)m7A1*yfrADiH-U=_Oi=Iod19%WM$e-u zr<`eRWpyJ@x9^8n1LQA#Xe)T}?dfynAaN*cH*4F4TA$L*#l*0UTR`kr`$lJ_E*m8EnF{S7sds0TvzS-4 z{@+4>rd}*46|%A+%2o376Vc++r_3fsQd(NRuz4?c&oRg4M^;u=9-|zCG#@YfS$IEv z@!L)?m{B_F(hPtbN=p3f?a%P=Zr(%`qCiywB#*$Mv@kO#sjHMJE0r#-0xEu^rW7y& zVgWH16TQ2)UuJhtNE#jVK=d)TynJPLbE+{#cQ<`PC_uapw=y+k@Xpe5ZAJ8AgX;XW zFE3s9f0Xyn3~)DfE~dTyquK{aKUd-Z$ouz4yp`GitKg5V2=VMRd9=U%{Q4Uzemg-^ z-+0p5K+}z;f93j-)BjoYAJ54RbVX)=Ka|v8{r$n)7(}keofmsHd>F0#kAHQHR{W67t#sGyf1Zxw4GLGTMmG?#*b9IBRyF>srR6!@ zmoJ@?Sx57K0yHZ?nmpRtYP#?$8gZ!2^d5qwrZd-MM~B&*U@+nTzX<*g0)WF1TPf5! z3>yg}p^?R)R;=8n!Dic6*Yi@+TMl+B;ZK*|m>$~(+QdnXc)jJn$!U&i;+HKauorp6&iM5xPgeLb-)= zttmDgjvXK0x63gUR8;NiA?od@+Vu3;d)V=|HeR9`Y;j;%rUvY1JGwSsVrwbI7VueA zzBB_E+3+iQe>If*eX8Wo$D!}5fGI-9)ql3a@#0@xEW%5Qs``a3O~Ao%x&nLraf}Ye zzrUE5GXc0Dp2d!t@^?YetcFTOI-))7WVeW@2{$0P4 zz5Pujq&*B$g?k&R*w^moNE8%p*K%sK&>s-)fr@|x6oi%*0uCGJ%gf|}%`o*4RBS0% zun@7zw#nTFleA-^ZqlXc%W*)!N=5n6`NckDX)$H#WTEBRe7+cOdrZ=G5QlE zf@d(4Y@iqMYph>BQxxbmIt*qmt-0YE`Bi||^He%FptLTm zB2U@|?tkH>j?UD)o-wj8xfso=+Z9`=*R1y+9jV?LJ*4nI>Bc9xX}F2KMto<`*li9( z%+(nMM;EXJi?WrLA5FqmkN_6#bPq*cOG{~m2=CzTuoMqHLc;zyshIXiKBL~Rfv;YL z{hmU;6U7<_d;yPiVq4!Rr@bR4uYG{2N$kvXg0C`K*;2c)F9I)Q2PV)+DU;G9(62W+ zap*?|CS8BE1T#cSobQUI_P3DmnJp|df@u}I*MN$#8J{`zWhwy!OZ*bXPk z;z~68|Dg51^ID6CI7fnZ`HV$qV22l@;?kmKYI z87+xZ_;^R-I{xx1FD}m7u%LK;J(R1tUFVpkS^#P?(1?Ms|9h>in4~+7jq}X>A8`3l ziks&~$+tFwkFQu-RzE$%Lc9mwGkl1B_z|6 zS3O*cg>wn`OmKXz^nQn$_iWDosri|ktVSg%A&unqEA7@RXHkrULH&Qzo@at-au1zN z*eCw}&hY2e|BQ+xs3(DswqK1FbQ3wcJQ2#c-Jst>VCVgv2W@F)9!pr33WZTt=P-0LhJH2@9RV$P$Y^oHMT0EeCWbvtscm*bc_s#l8l+07a-29SI&&YHx4`L|>uhxvr7!yHf(i^Fxf-s!8eNNx|pnxQFn%D8Be#)|4E*@3dVvkdp%``jXy< ziYFq_u{P+qxd6SFcC8o`vU?L{hoR)I1?p^0lN<&a+9ZU|l#CnwpU|&7uY>o3_}yO8 zP%W7W3WA6?R#Y@o^`}xxGdc{{2K-PC)yHZYk(ysSl_!R|(3AiA^-TjIg+dDn&k6~a zaAF>$cf6A|#~Fv~?X4JXk1apdcHTqOYnBi3yE(1?!8~`rswyh6b(fH6A@>BH^627Z z5x*io2Z1ORRgMn(#lmzL%SWt@)nbctU+es@Jp9zj_GGrTQC5*}Ii=V{2+6&h=L)i< z9rcFfysPh&_<{Q&WQMj?J&{+>dkZYT-$6*SNg~8Moi(QAu-V;6s`D)K+^cvwBlN0P zrf$`_F?Lrj@!AL5Bi`v6J$ZOfZ)=)h=|x|EOaDL@mPGO>$H;`n_y`9qA39TcZTZ^f z>`&_aV(^3DgTsSRe49pz5MnkJKEGu^B@y93Heg`|3S{SilmS`)^V!;FaHNrg}k>nsAirBTz8Q^OU+NG0Gy2F> zsUGI$LSJHAe-Q*k1Q7M9fU8T~+*_5pnx?slC3>4}YfCV|pmlgmdPIaER^>h2s_Ce# zoXerh^1g*QxcHk9q~qDmWAlmzYy1vsd2}@2`Jrm()g|%3z+Wl>HDCk;DAJ+N5c2*i z@!JR{XJ_DIcZZZqf%%WNsj7BSa=3Ka7|Mkn;0z2>RtFn1aY@PX;^mK_y-f+6T+=nk zh`xV_R3*CDPoG+PdZ6VB5G6S}gx81%L!^ZFpyQT>+mVHYjZMtOClj&7>c_!H>A&E4 zppRz#%+j$8*MhO(|-DfW&QLkPX^k zpsN+Gu&p+a=J~E@`X}*lR(|rle2@T=14K67aLv=-Zz5y=08NjG;G5;-*DBYFV|*P1 zbSGfjtjd7?5W2PSlKG`a2iHLe19c4qi9t3_F~`WgQ&nW-8;<9LZOO*0&TKOZ!gqKW zbh36xUeIvc#pM*%qi64V?QT;oOe3jQDxRw(Q)_>pR2{^*g*$rz7--ed54AJ=1K~Ag zD}L(69r%KhO_4dgFenI^KZF;gLn6lBrZ)P3~-o%Jkl zP6}r8$ixbMBd}XH;&XF?^9U@lJu$1VsljaoA3l@9?s-5T+Y1yg&?pI|y-$4R?Up`B z&B$muSq|kySO6*_>*r5w>#4BP(!1v7pw9%I?VBH}$cXu40hl)c&ytF`?v|jG_}v0Q zA6=){7K{y*V<78~CP1yda03k~v^2JS!%jL{YfZIKGnU?( zP*M4W_Qp-p)jMH-Z%J5p>$eX8ZVe|N749LHi;B+2H^?CGpQ=&)L)<6Pb9I@j^u6Fd zct9jUX?JwQvpA_G&xZ1}uP0y3lC8=SUU^sOW2kgR7A5$zB zAtQ)?cv>ML=w$UJGo+Yp%N;!SQCj{}w+VQC51_HKLe0eDu8vh;z+vG>5Yt_>J27`5S0O#v*KIeg1^8-HePE;Z^@b<0fA zH(~t#%|H$)3G}*&Xb@>oi6~9g(&M8^Pfdkc-;7RJ-|l@%mlG5yLip`J^cv_6xu|^g zyt`eFNPv^OTD=@r&FP^0^QWdaF5|7mX4Km{hMey<_t2Fqs@d3{ug{ivzP4PB?81qn zczDl>s(G#CK=c8D3}5eDy$?G2gGI6#)A@Zl2^FEE{fLX?pL`qD<7rXPMMRN*EmuBm z8Z4Nq`mV%){OMwm-m+`%IpQIqW1M)E9S;^FOtpkl>wg^9vw9e@varD5RbS=YUuA3f z{CTQUhhO7&U*D70fsnsI$v{&+3C%bV?Ym(N3Nscx6_${)vbvoeq%+XQ;No%e1Od%k z_&U`?CmZV03Rr``Qp>(k+4d%bOscVOkl23C%e(AFb#FHz8z{_A4GjTkp`Z0kAtkfg zSimB9)bjd1VCa+g+4>%RZJ4k}@MQt013HS5V)ZU&0hUc|dEk)|Jt!*Kc~zH1v&DUG^nS zV%NvK6bvi;0AJ#mJlcy^IMzmZ27EnkT5q+p3bH*{`(fGQ7TXJsONVjJCY6lOC9YD! zT|Nh&1(Czm><;#JC)+<xdDkos@U;+gg&$OZH$5M;2+3$$<0 zQ)abikX_ngVfTk6Cs*pdwiiYUZ`?gNI6D~R2M$RRURL8kCXi*=u2}%7p285Iqg!|l zCXb5CkU%0sGV5#%L~e@=Y1SBsY+;}PAQOmRtj`InZH7orL7khh=Jw2Z|I7%cXmG#`Qbcd{ITQA+- zi`{QPK@dD>IoKWKkE;`2ewWe13!M)aU9*q+v*m8vVN*u-@@wI4;J>QBR}fsWTtJSM zT&u=uUu=J2by~rv?HaZZX}!h7rKRp^;ESHL%TE>><^5gX{#cz5(>=q;2>DMPjYr98+72K~Yv_>P;DpmBKbQ#<@~J0mZ4JL%9MCn~fcnxzhDi zTGl63xzwmmU^72${xD|{*U*sjr3TclIDSmo07(ddQQua!LclQxKW|L<2r`GWf6Hud z*4v+{8~^&1MRm@TSok$EB3CM2bx(^Sx_YAKz0^yheZ}@a=8L#raf@Q5FljND=B1L> z&el36Boy^SYBDs9-@ZocKud7$c9^!{VVk+GxF7Ui1n+|L2J)LRYGWW0MforIx6*Ly z=*a)SsNeq=(ueVXgM+p9eM)Zb|AQ1>t_;K2X=L;sIwe*B-2#{ZXobymmWV7Ba! z@8A1oAE5r3nVD&BZtm*~YYY4ORYhC7``xpaU}7;U2r)3D97!;gj898j+j_R1DO?<8 z{GviP`4afO_MRS8FWo<%KD;Dh@RNjTL3w#@@^Unhoy$jC)0(of+lCAQ&gWz0mXll4 zH3eE#3yX{U499W2&NeXm#KYt2$JA0!5|8al*Xh}MK@5}T5ySEC3(R|HXbjBEJ>A`x zI{3GtCU|?NBcv;lOOe_qEp6Ty)Nc>(%6&2&%t|{bEoEQO1l7Bc|75wPB181ouU`?r zmTfW>=);X$f(Yq)FVByohn%i2kCoB%&CIHG|DeW6iSA-pGbt-8Q;G(SRoky$S3hQP zI-Yi%bw8fwyy$yjK4O9b^Xi#2D7`ny5bWO+N+gBL`1Z-NHi?4@7`7|c&pql5?*FLib2TwiV@G)$mr^H zHAS=B;t`r3kHf~_HTM~YR}}Jkdg-4(xBlnCVQces_1)`GxI9%w#mLxLHATgJBeLTo z!6HA;vwyVwDc9EcsBnEV58^GMI41_6p2L1^Xt^_{wYiy)m^cLni!q)zHa7Moa`{~S z%*&G!7r%>+PCfe@AnB8x`E1z~(U=$(ov#v^*fdg3{uFR&RE&%k(8@UrS-6D-W3cG? zVyFPz<=X`nz}E$&snewX(D%>cqu->ubrNrg6SaMA8n|^ zsKs4ib=+?L7@y^Bltd=t{n^34BK=l)HVt|o?qHDoU0R|F7e_-wYx_qln@sY;3@4_u zthhM-<%fkopD~r|)!x44x1QluRUHKr1IB%oi;GKFS9gAX{?#Xx`*@6MgGPxJ8bu(6e-iF{6e`9XMDh$7qs-gA9@y%zImON&uk*ppeeeRQ+i zuioE$cBZOqZ$0MV;HXSW;&F5+d(qL^3D&x@wbe8K-sN!Z5Uj_)S#M!byT$?K&K>Bm zO1X#z)4K!P-$X^zI}7U1&|r+=&F2%{0|qj}O{QA7q`A4dfPet&hRc!Z>FKU6i=iC( z+}vCSPX8}ob`B3;u(9p$?QuKp%ts*ho^|$L5)5Vj$wkK}aNcM2O z!E4t;+_sfj%{A^xKJD3v!?o>E$87de=e3 zdwO~_G&JJlVbN+bSOgxLUo1jseY)P=b!{jYJO!Bi+1Z(XOOW&aigdP8aA;_&Dwcs| zQ)diIv(=3)CA=45{U0sB)z#Jb__!iW85|uQ9UM%61>zna{6dCuNp7cmnGFpMumu>t zFezyowgfjTMX2|dl$1DbjKPc5efJJ#mzh~xH`uR_R9ADi*93m~5)0H~cz8JcN=C-w zN_Rq$uJA`Z(K4dlPL>AoGF`B=pV~Dpz^0|A>*?vSTF=zh*7DXOese!S2&X-xzWKaf z+YEz`9qs@v_bv_&&eFm`KoxLUSOCR^>Yjiwn34_7^YsocEeKJ7Io>F<6Hf z5(!2&xKuwsKT5F>_Giy3!6pLnS+KCNcO7xCuqYhTf`WolQ&Yi=-%)c~&m{7>a)1gJ z(w5?48*%ZrAVRji{r&5+brvZjI6%kSv)j`($6%`o@$nH65f0m+z&+QM^T%yn~f z+7HjO1Jm(hLq6A|o72bb9}s}105p(p^(`-W_*WXNOo?G(I~S+>r~9kfnVE;%vjR__ zuESe{^V!?h_G@b$9z!4=)4=d>62H3(SXuCcwSSyUpq@|`t zC+2vdLwI-Zbl;eTg(XeyrRf0G>({S!bY{I^?L-`y|EEu%TwGj^{tb#fepm}L*ykJl zc6WEdHEcv3!f8*<$r-D0+=hd#qN;ia6%`c)WxCGQaiPiocA4Qbg1<|D+1|W)bFT(U z_a@1&0N;3CO~HXbTpPCIu7j6>i;D}703stND=S616gZOo)!x?>@={V=JM(|KyStH* zkg{OTsF~SBwk-LEFzfoM&mBxRH#e8#Ek1*`ht$-Wy(t3lIIX6@3=$I)!Hi>) zlHB3qZoIIV7%?$1B_V}9fxM=sxw-j$1e_s7P|Ke@d?PL{&K;~~L8QT42nHz`!>nET zUKe5_1aBJ~8~8bKL^tKq>MGnJcp64p+Rwsix4~1vwBYxhC|%v%uPMSSDvlGmY~hs9 z(9)`EYu8zfv;MuX@fHgu)1{^(>uGL&O^1_?WjF1Od}m~IG$SH0kp!aX)2C0RQ1knF zTn^~CAv1VY@Z)tLo~|*+^PA6a9rxLK_mdy1D=Wonj4+`;FON~FaoGm^-9I~+jE=!D z|NbSS@8(GkP=wRHcu`hWrM@vzTvBrD-O4;E3Bn@$kn@a5L_xeq2pY%Sf4sT}G4by+78cA?ypv@lmbbMzd3jA3 zni?8sN1O0(QK64{AHJgK2dj4GC38?yQ_BHYVrV!_@An7-2V!o0eKHxLaq!Ei1Rj4t zT+X*|R6INhsjPpoBqSsV2?=wS;9t-S_7mp|4GwPZ@lva>N>aO&l99<8{0DwB)H5 zgDcY4CSFOWrlm#x)#Q&oJUr~oo2-PtxiMY>Zpa4}{l;gAQ=L7>xBTUGtHiiBnZr^8 zn&}b0W@h+byugjz-P=R*f@JCfv)}a+4F0biWF_kAgx5xUySxAL0wICpKvX*IQoKd& zCV)M(4@g&*mS7Y^IHlptM1x(wu!zX5cN3+iCyi@sW@vt_R#PwC<{=*6ngefCV$=;| z_l1On6lBMKKMjM|v%U#`7mFzF8p+q}e-fajRbqsGMI|F6b8;rQloeJ%NArl?l9F*ycApjH?6ARwAq{eShw^4`OHTH*%59M~vI3XdQVuIghWfZwui|%gSPE zew7l6Xt)_S){qnnyZ*X;_Q*A=0z(GNQ z^z_l)+tt<8dwYAan)L9Thek&+iP%m0QiTe18ouUY-GdP;n3V46`{3uu$jD4yuYw1M zl!2IxjF|)50FI-zwdeKKC4|0tW9A*0NLKJvCGYONd%OGlkqm;qj@vWxxkF#S;-$$! z{z&lfp_eq!I*stcadD%+-F&F*BoSUJFeNaHn~Mt<4^Kr&$;riKA==K?c0G^i(IXg; zFf~O2zo>oJ@8q3xY*2786BCn~KBF!I&~RX5N0Qfni0h!Er+;FYYR|3&yMh?$ zhrnMo{`sStr}lewe-y^~jN=l&Vhp;MF;4Ca7le5Co7>;tA2GME@KL}SzH4z|f!kg& zVznPq05-Nidih_xtX?S)zG?64>w`hRS=rf?p?8|a=Y3fHf35CcUS8_dxhSitjSUUm zMwptK{^ixfcF=By{8^20q(L6_nl3szdULK4MXJkr75`|prJ`fO0M^3+)Yr9pcHF{jnzf+5I_!MjG>o4KMEkGqf0tX275XhT--0~-#S;b4|Dgn*dH zND(&aq>o?xp5x%+?vA1$mP~IUi2NT(sxvx>FJ(>e$YyJ?Q*1szrnG8v@Iixcx$iNl^p~(Kk%;MBX4b9-tF8L^)2cuHb&@;DD@Li?>^YQ2 zIEArfx5E<}dwhH|ld~nGAV+@bxRnU65CW$|0@$U;@s@V>Py4;4_So21$Rjo;D=;;8 zpSc{E6j8Tp-~YaUt!T*ob2T_P7{cRlU*DH6U;d8d6Q8xWhLX#_yp5XBjpzRg0vg@; z;WY+LBpjV_7$HY4AttM3QHOH#oO+Sd__(XIm>=4jUyU;A)KC5TH3#MfnIq!YyJrym zAk>aolz+e7X3NUX4o%8*E~vvn3-l#HRFriP-)a;$J3(ltmr!(4-y@K(Feb{1EuH0G3_p#G7E3BY< z(IW7f-IviYUtiy)Y~k|2k+HEa3TkiAM@~cGzToKF>+3HM%#CaR(# z2}ZomKYu6%1jq$2sN#CN+S+npqcgZp(}=ihxt4(G8ppu0+~Q)^=j|9^vPza=Rc2c%X658Fn57GP#4Gke}e9FS&=-`kHS&3&} zqLK$77m#;@cL9(E9pcmaNPZ23nXgQm3W|!Y!Nl3w+2Clfac~Y!cJ(dBtl?=u@e2`` z+vOmqzWyqhn3F1dQ#6|zt%$t(=5*!SPx+nMys9p{a4z!95-c-Oi zb_RwSIHd43aH1g3MiSK0nks0x;)XmO0t_Et9lR7s?GlQM+?t53YKcd3b zdtv-G#Zb8#vK>$SlpeFOmZ68}6_B@sW|E zX@Wk$!*W>7ilobbJ)ED($N%`!w;iA~=%=)kG}vaNF#*NLom2~H^3(wFF)%OyfYklv zxxNHvrzbW0jvvkwA0wUt_`nbV50Vb*3JSm_zu|spYy_XM-gZUkUQRZZFZB7gnYp<{ zj;n>GBpeiQj7aaWBb6}voT}aVO zL|1q5$1C*liHVV-F=X=PIsGv4eMU z7kd{W4h*IW+!PxPIQQ`tl94731znqItxzN0J$Rn#5{8Cke8XGu%!cwq&&zNB{+1zO zVP!4vif6;K0!zhT6M73=QyHzkp`krMv1UmQWK2vbQr6O$Be8TE;22CUsLo+0ayp;8 zW)Wlu<*xxTrPJh$s10>lJ`C8-@gU$%fsX0l3{#wG!l@1Dk|BTnPbIToPGQ7z%D=# zb98h(FdwZ3ksk{aGe0jcJ|W@Zj=qLlAjdcGXKHF{M1($Yw&vzD-thxTlG4(2V60zt zH8|(|28JC4yafQ)Ant>07a2A3F9Qu}FR-+-^7@3yBnFT?NGD<1Mn=k;9dMp-b+SVS zTp2JBSXo%WJ_GqF57Lc=wY99ccwT8Kz|$<8oKN~OMv;I%N=+@z$XMOp4tQE8CIO%S z)s0t==pF{hLlt${K#uqCicEzOddK|_+Wyz|C?$>^3Zl@zYdv@EDHlB%SR1eo;Ow9F zekG9qpNqfkN$x-11NTct)PMgH_$?oYk^gx+PwxMGyZ^U-uzl^5r*-rsw{sG;#xuC~ zRE4mVAjL=d-%tGsd&lRDvsdB&Uk0Rx@lkl|jy+@>1j*MbG0L~~u6Snn%TIr>kH_p; z6)Tkf6#ju}8~8ggHseDx9Q{E~(d4wJGrS2aB_=<{KZ+-r!IR5d9t9OUAu(ApmsQ&` znV@K&LQY5|$IutG%a}sHTwkSn;#SiY&hu}x)Kf=shP#7!&eSM_MktX z0$#m*{{4P=xnf#9@z*cir^klF!$_)?iAfWFXZfUrzVUH3TprbWEly_d+oq<~va;DC zx(N9^Ya5#n78uDlWLWSJUutSfoPv&8aZ#S7>7tGzq@bbXc=LOsGbC%b0S_fm){5Ia z!zSc`otKlBaz$82I5{UV$G_4)CDz()D?(DjMdGV|*f{@=`EDX!{AzV*K(KVb%+~8` zaOb+bclosWK@UH~W7;}CugGY#&ty0Dhh@)kXLF#Zd^%TT&@-_G7DK2LNROl<+O zUblY2Aj>YIIuT7-SIaM!G9JYZK@C1J&7lbw$e*QteGY#hY;t!tI}rS=^sWe?=GT(1 z$yQ0<6}+34j`fN0sVqi+EOqH}@%=?wo|;EfI2%6`fXTu31-#}<@E3FC#E29HBL78$ z$wI3<#HVY9)~au^nF;s_ZtolWnb$jIg+%;bvbY6C?~jk~k4FY6=KN}Ej%f}qK10@i z4!w^tKH_U$Q?|vJ4&pt~wrZ?q?(fN(#_|jvCu*3vh_>8J2P#G1XBc0CuJ5s&Os`ru zOFwR~q{5!~&6KxC-Y1Dsp&;;4c6$!WuADeGByu*3DqxOsTXx|;2!KA z$cbylPo{j(frpG$HgH{V*=VcdJQ(v~^SR7h!b>(WHf@vY{sjHuyu6dZ{9O8iSe*h7 zuil)?T&9Uqm_V3JM;MpV%s&i2nLIU;|KR-|tJ{2$p1<_Z`_C_QRO8g^yyuQdPJ}(p z^@R<6T4GajgL4~#@N}2As|{`Vnl2VRM1@r{o1@ULIE_YUxTSww($SqwNdIkD3>vi` zQzO#W($(=slDkXQ;dDBvgE3_CR(Ub$E*;eMBqF0>HB8jlSri|J%B(nNh9@o zFFq)PMRl~zO5Np?qk$NjD$AeG>zhlQ;Fu!WzFuVMb|xM z0s>rH<3@kf@UP!U>^eFhTbzG`4s=Q9>gwMe{`RC~pVap)AeYxYLdO1AFiso3IF>_jB)) z7hLgX^*csdBUz$&e=QIcy@dq4yTrhxzU`k!D<4V1nfuT=Ws4IkE$-Xw4w5A!kL8ZS zba@yqlUtV9QPYa(ny+bRjej9U+B!hBAI= zJt)eo?g%fCj=t^ot0*{)#UfM{>TCyFK-bk)lpJlu+@a+gG6Xgva?xUsiDw~)w~deW zvqg+XRhv8Ao+s`g#=wx^bFS9hhQqr|yS7+CJhe@L3pDNR-escI)Drz9VL zN~X8eol6%rh6jZ&x_>E5iA_mLe&<7CYHSerAhD@LJk4ZGOV@|Y+3M<=LHspv4^@y zkZ#EXhB^WrrBs2cq8s#GW%YNzKe8V0ABF+cKoN+^t9|}?>rkB4%U4Dm+!Bde&cJ36 zLlG69W_9BxD6m>?r;m0s3kU1MM8oVXFZNZg)$FZ2tTa^W1&FtoOJ3dLv)p)dOFzrU zioLO*wAQ!74jtaI`Os3Ik@My32;bl3&0uf;yshQh?|1&-UdzKRrO^9RzLp@VA_4my zq;Dz<*WWtQ)pj!KSRkt{cfDD+`s)*i3_Q6L-9k=A)|Z>#OOL;6uXOmzyfz5;L5~H2 z)PQ&*({)^SE4{Uu<+P)|oVgZHE^m^0xQ+vl-k%#eNPakxWM%2>FJbSJq5+0*OL{qhpVyseXySAE4?Q5u?dy2 zo4GBunVxX0v0N?bgp9-Gw!(agiwl|euIDp(3a#1M%j~((#L20+=m)*xxMyx z&h!SUygfVjE_%MQAI_>*}a=?HB3O7w%4~YJKy6&YBmi|$}Y`TQ&qWqw9kT- zTG2CmSnI8_1=5?YyEsQShs)x5LqiiC6|L&4(Z{P)vY|!3)~`br_xYQ0@%}`?n0Kl} zz5Ua+mgqjRdhBO%PNq%~;_)d--d-yc;}e!#)x`-tbJYf>UYs^90=5sSdtUqv4L9pG zS}#h`<4C>_=w_6pmlWiDxy{Re(7xL--?5{WWaO!aVQNr`ar3@Q3vC`)|?9*$*Ga52aVHSLBOB8(3cMR|NoVJ7*{dK2n(Yu4M7-5!y z{rYh$njoij|=G$lnsA#<<@A6PvMnR%CUmDfT|!z%&4{a@ZB)#yx3v)bNud_hXU*| zNeg6wGD-3*ifFZ%tFPPi7zhSvd=5jT#V9ro&&*5vcWGbeZe%&umf^4Q7Wiiq#7KsQ zJ=xw)COpI;hV*ih4;*i!PVTngAxo_aQ8}sb zL8H?6nt}PexjAGT`{2``Q117$`-j(XRu2=EYP4mTRqR!@j5Cs%BfuA;REH6wMv!Eb zJ&nz|!+6a^Qy{5czTq~^yZd%iG~X&w>dK>V3HL7Q$WL$~Ch1Bd@&gvHi25 z*<+}~eI{?G1Ds2+cu1$2Cr5Q)-j7s>AiY; z^DkdC0W-n-Rhk^doy*~6<6p*+5x7!4PC|CckzVoUkKrvJ!*Ig!CbTsY9FKH!F$m|~ zKJ{*3V>|syWtY8eLl%<|rGaq7liJ;&RGr3VIyIuY&tB#gFZTLKBfAF%jV4-2XQBe+v3SC=qe35MVwwk@_fNtM2 zwW_Us`W_gO4@&uQ60$zTWIy0AXU&0uAgUuu&`jRW=NFhfSnU7qF+F$?Cb{0D#doQ~ zW+SDqg9>*S2WJNlai90oA)`H$H?jm#y-et$wXVf($!;mV}CBaebv{$s#ClAGloxpnl1hm*wN^HnGMTykX}xrf=&N)S*KyfF)82k zX(}lB^vmhvZzraNN9#p{1K+vc=if#a$tdKe1=mC!jxhq*q)8E+Ft2n!P_JVQ5^{dt z7~rQ1p?6?+TyQ<_+_Zur-j#BYaLM^D!k7svkSy>TQrDjwr2KHHBWRvJJ@cpF z&+t6o)m_$eHoW5Icd^lAdlFaHs0SC&v%<~-jd!U!FZpU7%betFR&!8%oHNOUK$@kd zaUH(XKWxp#p0Q+0rb7m2<@3s?XE>D!8-f)g5;i4Xwdq}NE$U#=8%(Y!yQbFc+XGSUAdD(HLD2=XlKX8Wj8n1w6<2C$MF@~;V@S;7825x|5;GY4q<$7qeOct zO(mUHGpSaSl49NJDVm;+nacmUp$-zz1v9=Kl0M)nbsO!g<3%Mro#%^FXUXS7X=e8i zQP}Bghbh-sUAN%Mi50(EpA23L05&9SAqc;t=_A3La8$y=M<>Yr8xO*}VK_}wq{_^5BD;v!1H zj?dl7iBnT!+DPCqnH&?7wc9y7UBEcfgW5poDo?Tq2cPNL556JV-W({qvHsv*Z)=5W z?-idfHY%gd^Cbpq8nCrfxE1eTM}nGPlu$T)6b$6KXGkjKsN*Q@9ugI5=!Pl;eKQfL zny5bZ)wDm zzTw}A{7W({zvUHeh@6x&?#ZsyEVis@!b_2yTS~HKv9J?D--+F-c?Zb0%C2)LGp7gy za)MN>aCb7AuP6xL+rP(PM&H&u8~E0KzaRN2?P|>p6>*or$MDR&AHwBtP5mx#ow5${{85WI?w8BH=gsy#2Brh*~Pg4I+rC$SbO>Hz`?wnxUgbEhcYoce6+dDUi zx{wb2U1@%4z3r2tk#@8=`Il;Y4Gv@Tp7J4sNBHkbzw2+O8M#Sv8cH;!RP1e+ephx6 zwZSR|a&lXvUmaGu0USiXj!_;@CuJC{2OoOnaMRLRVfY%|h27~-`znK)m?tHqj^pv< zZu%D&Jk^W&+tDD!{L9tX*S!%(`sV(UEN3hb@SL!WCgzr}AY7LOg1&flNWjF@$cR>Z zPF_n@rKB|5-$pjJ8w>gwkt(RY^5@zal6Nvg$Im+44tRJ4(XOt+2xJzA_+^q^Qsr-@ z_x0t^&Yl(&?wy^c5!7{cL1{)NV%qwo^7+at6qw*2#=Ae!rWwNEe|Rwn5dA$?x_I7S zj>u@)+{*Z(-G<%71{<>VQo}`Um+f~Lfvz)Gcq?4m5yj5z%d-`{@2>B^F3p4sKcy>} zliecrNLG!rAv(S}lRQ0%kT@|v0R^=DYID?lG{n&PF1~)ici9f>&phWUL@vQ>@?l+ZN%PjxCP&z%u$tFgr}drbTgL0)RiX2*l%=in;0^N4hQMsbHCfKEOv3NnMiz< z2xyMG?4k5x8D+)WVb4%QuD!1MVeIzU=ATSqOwPLfhDxhvwIVXD_V-g0k_e*?GmxZuh7*lTnj3UVfpr>SbBmrPrW(dGAP-fg#Cq|>cYi6IRBB6# z^|i(k{@ZnxvotX??<+{#QYVc*pKB*v2$rxFN&1g8*4@}t5k|WB^ju4v0Cm7U+Qsoi zW-U<%UY(T?_uHaET?8+A;C5zw zK3e7H#wX)pgNhcD><%Yv2J)TOgB$ zGO$xwl@C|cMKc}_9TE;5f`v`JkF!Lv5$h#JiLKck?UGm}Htz#r~x{d$0n3|GW zrR`nD>nny=qV1?D9l-ry#l`G5pL?7t06w-UF;EMK{Nu<^|H6`jA*)qBx2yJI|H6op z2)_dO^&ERzF6XtD2OL#xRc#fmhs%z+`PHTwLsJ7?lH7u~nq-8liY?K~(Ma}0-;uat z-by3@N6bFKrem4RuFTH!j!a2kRumUX)5H9Nkhx~)SC6dn>0NJsUnW1Qa$R~E3N-EN z3dz4E)J=^uWwyfOF0vt*Z|^s{zN@^rxB#kEeV_P{5^E_BkK0gucpvzDbjwwQPmI@}VkQPdMUh4VQVWa`+Qz?YBT~)6`76LgdcVO6~=6r(mil zB;X-pvm0ZBJ)TmUJ@_bi9J}Lpq`b63+C@9~{A}LWoU}Iw102%UdC1oo7ZEqIh``uM zvP8B^yE`T(V=)}0kTRi9WU4?Y<0ED}G z*F)_Fg4eo$(I7y%ovv=|PiKE2uWzT(S0rP9smJB8bxiN@nk7|8nCxnNaEvyH*3-=+ z0`bKaLDOOH)g6V|O1j63kM3c|$Sob8&C4sdhw|ypkXx*ZOsfoTS<2n`H?Mdx766hs z#N?Z{s9UWtfIcy6oYl~Ye|D6J!HBM*U;OS-xof^t{OhDgp>=I9{BdGwFlnm&^~;Bk z#LG51O|L7dP;u$m2ko_n->_&N%GH>ylK3jl363kb#?^_Q|<<9<+{A{5XhkuSRW%2ObX1358_5dtPzT|gfZ?l;w;y+;_xW)%^;GUV}YQ$>)DZ+Ex zuQu#meRFb0EdkDf1z5kuoW_rw0i09~MYZ8`*DD|eWoF&MXY?UI)nCrei)4;$v)%f- z#Q{*pHo{r&u}!JDJUc!ABhLMtmYACa{=o}?W_w#ya+$$Uh?tQ|Z@5^m{7SCnn;bY@ z7&mc6Zgl)yhVoQu{F0T&TzNJ#3i+?_ZghyWFS9Z9X>KREFQE^_*}bh|<3G%xbpo*L zZ-qfxd+!JT?`Y$u#Kg4UKE59aV}8q5R(3r8c<}Ew*x+}=0;92fWm995q)aPMSm+TE zmEnCPbG@dU!Gu@1f|{DBsHg~ODW7vkPC&14#KgJjG?16(h|Ra__ySJ2QSL~u$t$p# z%!L6G8gnM-+Kq7 z%0FL!|En;S!s8j%oShsLX+e_vm;d^5swkTOscPD;?p5lGkqQxL-b-)V`X;N~+Bs+g`L@48)btV{Ik9tDA0Ux;uZI zY21qU15lFXtP)C-&|KS4juq_|)xgoZ7s$#S$R+k0_mdFOPY6YNIWDJ6(aztD{?eDP z-|4)pte>`*&;6n|#@{PxH|fnG&r3+Vfd{Uwu=nRp>wqYOGniv>77+J$($)0nmyOvf zgN;tats%+|%yE?(MS$(ohA>!hlS|qGemKZ&o>nR$w4@?u_iSo-(qyvN4T1;|lNEHy zjy^O7xBeVp*z+=40W0by9YnCn*Eu0OkD0=<%DG=cg_z{Lk#1w=kQX03>D_ulb7ODf zIVpcd67K~Moly-mKAbabKA`7!OgK)Ik_rQiD?jiSe$pGgoGC($Rq!=grw$vfFDXg@ z)Fv{F1If2l$dkiD&-xHRQ1Gymd{c_KWqZxqA1zuc2K{h>i$D!Ly5`Ecs5A4!5{N{nvZWZ z{#~-c)9iXF%!2O!7?fNI&}Z8s9G2xBF9i?#`}>(6zt={x0f8`Q>ln@$M4rSnoz_$^ z&$+z2Hsvklsr3wU=kr<^Y0X&6^dk81d!gQjwe+TMF0D1pDv`^idz5BLC^?`P5|Gi6 zkymGuyz@60zjo)VQBDzO9NA1by#WD(eig$?uR-REN)M=uaS|Zs;v5MzcoX!PA!$pGa)JGN5LI0d$=ho?!iOxsZ`8<>!Kg{_+}G4+t{M zrY5Hh78DFzS2KTp!yJos`e_vm%6iZT0=2*}^Hp|Gi~!t|RH%qZucgDx^BLlihOQLY z2w-~P?1UfjQJiub3F_8u#rM}GwzhP{rgyRp#`pbt41QB>IfQB24c7Ai~F2Oyzk z&@xDb6nY*jr2F{?Uxb*y5TontMdxO4C$WJ(X{iY*RyT^%$TZzo6)Q*9QkSZ$JiyJE z&G08qD4OA~ev2fI$BVz*UCAlR`*Kj8>UC_z_BQlQkCk=S*v{h%o2p|ib!k=iSx%me z)XYk|Bs_v*g47hZ_B7UQ2Y|a?*WpN$van!w%fdoh*fzTCdvX{~z*|Qf_NFr-ks|cd z(7*^tdGN;kj{g-+zI=j%fItBhvu*OXlg!MT#$cM2>6iCxTwJt1BZ_KNlw+MM$4QAr zTSNa+)%2n_khqwv#0NPO(07pP?jG_n{PM$`NqbU2yN;-n{aofAGSL|iNGtK7Xv`Q+ z`ujcM)t-TS>7tLGmycbCXKvqMhd5+!HE%%+0ibc&c~pq$J?~YNU)DzOeC;$VKbPh5 z<%%QJE@vx$-|)!fN^@zqP0vVmbTxeOf{{>~h!^pta$t9kScEt^#~|a^0HN*GF|?mu zoy#2T1%(1280Il50Qc6b}04=WETbSd8F6i{AX zNnT0eW~~XF0rSit{fGNcNs-?plU=Tm1BqDAD);H#KuOgdCUvRzX>Xb`KThB&;s#^4 z9uXpr%~YiO`%^rV$7#!*B-d;ywXuBpmJi8;vNWOM>5sSWrM05JshRR@mOi>u@)CL+ zn*T32j;QC*SFDATh{t9E*Bf|knLb%Tf4TPW87(3*c(;4IGllYjPI9H9JaO8{O(RQ# zjg9s6f(ZlnMH_C9;5KWRD>+8lh46AVv-Dpj1e~MckVf=w-5-K`jg!^*pl$H;dU?qo zl$oh%sJYZ9hK9aL; z1c_v{aSF2G$?Tdrm`1oGIRB5OeG_;v>aT>pNv2=gKeW)cS2w;+7L)6f?UHnlJ$P>i zir&{_My+em-~L6bMMit@~ncg4^eF({61}LehO{m7HM&s?_8Wz~nN{*z?DtYAH zEdyPEe2Rft=nFb}#^(@sav0u+pxe%jne(a(2ogOv3@^SAN{)!gE-RV5iu!a}T$I25 z`kIoPvJ+D*{gyf-_0Oj?ndf+?XD|Zw>_J3~9rD+g>$_)XFxWe#mL`*(E8|-m`I;Ji z`R-afV}DiQBV4wI8jbrMnw#L4nx(Af%t0~c_0B}c;L~zw&~6Z5DRmGDxRX7vZg{!; z-Ue}4t+ErH@)i~4xtnjfSmO2rzM)*C2nP@w&%P<>u2%j^ZRrjaA$96$xfXm~n(}b} zSpUdOg9Y4w;WGdrZSWm+r{w+ljaU*OChO&CW2IQ}0{Quwsy(h2__rLg15myyb z>Y2_*rCdOU$z%^wA^;5bm;0h4+7R|%Lf3V$MUE+k^dchnuf;Epcj=uW!dW98(m~ns z)E;(3tGl!om#UWvdKoNdte{{ZfM>?6sk1ks1y?z1#395Z@u`EB+L*$V3lmVvTeFNL zyv!V2SoL}$MzZtoRdm!m%m!haru%!ZVx`#Y%NjGAQDJ()Z7CGxfj^t3%KBa-@&j>3IvCs2Mx%CxbO?x^A62EvDk zCT9f0>xS`m;LQq=iu9Q^s5l9yqSYD0^R^~o-1X|d(dIU3H{QJnxWUg$Uoli?KAr&& zhnr17Nr{TWnC-j#lf?eSe7WyQK%?10;|!%KC6%cs`{W&#ikgyMl3HYGVg8t4VqMOr z31nuSEG8PL6**TzDAf0-{4ET4J*>c&O*QvOS8|_65p5tHO89cR@MaK<*Wki@OZPyd z`Pzp@SVX@#h1Xk>J~;4qf3%n=%s16in-MBN_Csxff#nYmZe=7d`s(WSS$=JASH$C} z6xyt1%f!S?n41StQqmn9J-RK9<(7iO4IS)o330?t1HD{O6zckacUJ-V4G=rcyVj+X zto~|$Yfa{4wnTD`0S`ucD9S~u{EUf@Ffufu=fajBF7}y}uz17vJfvB{Nc9z$->=vP ztVG4m@AL?Blu0`#pZpNAtzrGjSdSQLJcKl@UB8%AR3}u&1ZI1O!9dRSmmQPL#H6dF zfWkpGbz(PWkNtoSMUF;6pZ*;8#d}er1$JT`Y9y)WnB>N)+8&z<7pDHq6w4h8bqECz z8Z7lC{7T@5=NRqU<6l1#Gq0hTJD9~v(jg{KM@43(RY6dh^)rg!j8=`h$i;pgqqb9= z<32_)D6e4BO43v6q!q<7%2QBVUNADeGqfBW?n76Ze(N5dsa z)Bx_@!Z(m_wr^~)mO+3>2H;CLf>D}B)L0GsonOR(MoThGKsi+Fl?7r^&pGp`>=k#Py zZQvd0YW4@=p^go$Xko@XT}!Mx$AP58Ne|gb)>Z&6r{gsYBicm(A^rw}b4C0%IfUdb zCQ?q}D1rgH2zOmvCQMAQnjbG`rWEy3caG!?%caGSW(L@92t!s!lT3{5`4L#TGBuq#&&0*fB5$dE}f z37$xS2#}5qHkq6&e1D1H7S#F^2;nM2$3Uvfn6KCAAfPV{{T-gL@3?oo_FCk$F>IrKRa;q`Dnrj0|7OXuG>B*sJArKe+J&%A_um%R7%37udo+|nYmo8cxi19 z(B5RXp+9?kgWv>ItW?x3>--ADh$>vv`_lU?;P8`7=M_nG}vkYi~#}d&-llq3dhVRh( zf1G#5cXIFue4-*T(Enb#8Ac!S(HYqCDvFcl=4JVX0$H<{VU_|I0G`$3U-S}~ba z_N1x!^)2^B`GHAhW{HxH+QVkYTxSTmXw9m_Jn3Rrl$YLWrRCnv0U%sU3bI^Tw^dcF zCIFNzTXB7k+e zFHW1VnX;9g;}uza&YJN_&*_TidE>fwm-Qu8r8jF)2on`|xo3`Yoz&f8n3ug?gyiu#!u(-t6zTv-#JY6WIrZhF$Nea+ems{N3`^%Egd4Rj6chsjT^}X6( zV1-X+?(`^I*Sq7sVCLM7O-QZYZA-L+>#11R0I?i!YQ#N1@2swCrCUV`ItQ4?K(W#8 zdUu3UH!7lJ1PE3@H7h{p^Wd+E*R_nd_Dco%nK|6*GnMOLn3M((VuGeIPoG||aJ6C2 z-z#z+Lr1#r?OJjQx^qkI)Zj|~Q5w;4pIE@1e#QDqGLjx*A0pWN0!$~=MLb@6eSIc2 z_!~$u!xORa9yZ&XrGUZ@DACxI*+DP?Byop9hu+fzLICe`9hn8@hmS8>Tq+I*!e04w zPucAOHk_J~DqK%Yq_^GB)RMRQ-yO--ZfTI~TjeiFx?Rd^w_=HwE<}a^n@Qt zU@ZPv7~Xl!1#L}{wDKV#x?`XbqrF;4p4Ymj|E({#Hiq`5>f%L}DnBWUZi%i_>eAd7 z*Sk&V0_=-h| zb<=eN02?6TFz!zOiT;2zw_br0!T0phz7vq4j_i)ulKXQw7?;Y#C?Ush#h8wwah|2Z z_F4eKJ9cLK1G@ zsmH^XBQfv^e;ZKlT7iHV`Zk><2Nn_rIsk<|LuWgUSJ3&1o%)j5mKk?8QHRY|h1c3aAdTWwqO)O&2{pOEYrNxaH#1ou_Vi zfm~P${WTpNB&4CRGmPuCEX7Ce`C-?|UH%BBYa`p#IvG?(E48p?QBOEArV$EFOXfZ7 zjs`+2O~Vqbt*1j7G008H`Q4rj;_px_YtcwUtqJ6n#0jEp5)CHo2qYVXEj zqn26|-EMOKHz#NJT53kjW2?fdk#XOH@C2Gy^N%?MeEY zp;{A4OY@bfDL8@OtS36`zV3XR8K??%E#)wdhyfrvIZTfYRVy*zLE3Kj^sGPM3R{ns z1zuA#09N#K{V*W(-Qh}Z;eo)~RBOvBn3M4mmFUuo;4G&m-C91?`})278}3j~_l^<3 zyLA{Yd5GT!Ajq7{Ob+Y#q`F6FPykg7QqkfTkd*AQVX7m{Vc9G?8@zth+!R}2IDGE} zTt*?x)G`15X((T_n=5@{)$!3sHH9qxq`q6j+n`}R{xuyo1m7>V7cC3em!P=#)+4Hq zd3`e^HS|IWYBQ)9vf{BHIJ)i+P@8s23d%shLJ>ZuDN1NAD9=ApQ5FXv8*=7$JKtUT zdgYST++?KbY?~?wW+DJGxYhQGlve*QE;{^Eg~9C?hhCG4^Qv=Qv6lALX2AC|`g8*= z+Z!UY?Za`W{tOu^n-o4ElvFk_Hz>C{QKiFgOb`2=FVl0S$8}Dx%(xKX}%TxHy0w-P>_f}SHXzwS-4;J4uQ1Q%)`QG**wWFsx(w(g*JN4YDlg6^xz#1)GN1T;|C#Ij z>IZlJUlDQM9D$tU%x&6in4%lOJVQj6yr;u^Z9VBreqVGN8}q7Lri?kbA)G_5qN0NP z(T9HOne@PvlL{KCFm0a6nY&%I*HawhumY~u@SeZlLuUErLG@;!H2L21p|g4G3PwOe z(EKVWd3v2p(91CTN*o0E*{A)H&rAGeZtBxBYYu=$1O(5oMfX!6amPOLO4>B|i+i1J z4BA9b|4DukJlp7ZC!O9!N5^5<1w~`3{G6h>tfbVnm(Z{?w!(}N0!E1@B@i^yZX?kz zV`Fa4%*teCgB~*LH(PXX37>4OZ%M*2v_z8-hAC#WX{s`%y7zgn8e3^8rM+dWUC1o)b#7hUqDgA#Lq-A?mcLW|33QtwBQSYOmY}!Q&mec?BnGLboOLtmnpER!^6G9d0QNShpo+(BgrkxDgq;n61VYd zr{;R2X$ol>scAr2Cmuhcwl5=;tPWPpTc(l$9~B{usLqcuvJw8f1a@jh6L_xAYrePC zq^w`TpNOext14=%c1D{fY~xCay+A838&I=#E+MCs-D&cD2UKO|1;=- zehLQPV34(!{MWtu?>apq`Hx;Jq|txPZ2xuL>=6Iw4`?Jf#mPy?&i_w0*Q3<`>Mz>K zG((*Cn<84oh{h_Q%|Exl*njUmxK(Ng8a>c?4c%$EJ^(OMwU*y(j9jj>`WfG%gTJMp zkv?tAY*TC#s5K1m%VE9&MGNT28I;W)!)2%$iriT^4LXZtiIjRLnUt6WoY9A03)$9F zc&V|+6cKCdy5<58QN9T@Z3lI8cnC4rlg>TY1?JUI~$?w-Mom3Mk)Q^BtQ6>bfG)B1Ft zqNG8I_6l3()+73=mq>oIRUtm$;y*iJ@)Nc|N7jFI1;O#zZC^#998x?sw+jro5|Ama z0H_N@EgR25sg;01u{~gKVqn1IGFf_Bt9$? zE^#eCC7%nlm@E6~x!Lb%$j}18A_Vsbg9$o%J$wYeWOkEE>WZ94hA4y={O^yEQVxFq z?`|ok)Zy^|-B-1Oz694cPk*+7bBbM)dY}$NT51yl1aq>F1pec*%^*aBU!!ij~m`dRhT$g_9Zo z;=v-hd&f6R{m*=#6V-jm^IaNEVR=^kQDhU8dfgZgdP*E04}FC{BL^LH&?@OCOp;Nb zrP4^t!q#W^0TTgz96*$cHoU41dIB7-zCg!c4szQRenjEwGS**9 z-uV4e*|TnOW>{$b!h7tO?3?UwuSXk0d7%W3w0jB#`}_*fKtQ2kjJ=umBLHNZI>hBi zKS9Y6Mcr`6e9QII1)qD0^lEcwt1=Fl$HOC#(+)&CA9>si%=)I0NTqV(a-EXn(Gy6;Gd8CB{zx7C z%^jxxJ!F$QdT#qpJHIi#m+wqkf+^{Lv3k~wFG+%CA%auh5UY|$joh168^^ewf)1pk4K-3sH~GE`y`Y1Z|?r!_Rk>h zKg1!myt=HduIgfA(xG3_Ff?i4uEW{E9m%iC3R!1$8cuHTn4Rw}YE?2kT)`i<_VYxv zceI_UxAbqR(KYeRnMz1@(p##nt?8NF*h}M-gH7R{;dU*ZFHX;~yXbS&dwSttLdey0 zNKD#G^M}h}BOoa9G~Mxq4uLk#1SZ&)F6jG96HWaCOC~6Bgs6%4k>5d+Qht6Of$mdn zbM?a3HshT;k|o$iN1bqV93G8t&?CUh^!k`k@qVC*Nl2>h=6RECcrFqD=<>J6dq0P5 zll=G33wX%=A< z#;gB^&tkb374Ac0qLaSebg9qc2j@H6wemqvD#A~{fAbU|KIL-j_%ngI-mg%N&|I9K z^tpWN>$~bJY*so4qxuqPdQ-A;if(CWkGC(@wB%fP`8ND<4v)rdmMm=Y8xNaLWQJv~ zw)eb~T`qU(!_b_JgYukcfP%5v}cs}xefi;$I!>) zp23E%d;+XXmiI*E-sjzdt&n8)y5Ub`ykuf3H!)OG8BvB`e=WG!P2CVh$h=t73lo1C zO!*YZ+0;iF1!?G2wQUb~g+wmFhZ1h_#Y(2nYRwfVHLB8~F1dN=U2gV=mx7vLUrK9j zx3@YSpTouW@}dve{SrDs5}_Nm`13mc&X+{83Tf1%+fq3U9Fv?w^h5M??}XSwXuI#q zkSTAw@v(}O6jVp1MwTiK;=X@xUr=)@&w9DW+g+So=_)Y%2vp8uu42Hv?mr*mLC*N2 zzm`v>ESaF9)GO>i$A*UbK8l6#J@AHXwR(%szb(A`inoJH^NzL@Agtg7M|o*^PYD=O z=ZlSMaXL*VJ3f{z&}Y1_R~aXpd3VcyPqKrWe&TT_K#f+CSl`|^86lY-=77&^KHUil zaZc%jF&1(9q@!d)XZ<*o;y&`KDo7AzaZxens4{6{P3+Db{YN@1)&g8HS3j#PMUu{e zrxfsVEq2;F1^KIJ{|y*LY%g3e_rwk^cISn>WngY3uJW@H9>>chmd9uS^r8UC18h4SN@zm*OaM&EHGgdi9Eits zGIY#i#NoqdF3u7h~!mC1w7Dm_C(MzDx?fTVzbZXMR%4cY>nSTtTCR><5emIy zv32YM$d>;S3(31aGZ!aEd+Zpgd^)Crk?UyjBjfpi>K7;;{&JAfF#e^Cqs~Q3@Cyj? zC}=^x`B_q6z^eu$3Q4?o{p z5p$YrpU<-$}4|7*?>b zr`v@#i$T2-!XayzTWx7Bsu!JDik9F03Oqo5O^zSV`MI=2BwSru^+NL)+9w3a$GKnw z`?;OgI}L}Itr#0>e&f9;*wu8pl#`GzD5{tKB#E4r=<7@)J1E(Fe(NP^j2PEl&0G@? z?5I1w6h=kf53}LZ?;kG@ZcDecVn1mywTqAXxw}iSf%&6h?x*-NOb%?BuA?x zWq^be=+BLxUP#j5mMt5x^wAd14+~E@Oe%uuZSp%Ervo^MT2l<<6K01Qw?4xOj8Tj( z%FD4ZAK7V5){1-%X$@*NX%L2%LXldLi*xpHS+Fo|=-cnd=38(f;FZ!d8982BOqq9! z1o9L^4*sC-Z8)Doh0sIPy+U)yr@js&O1qK$6X&nY+%dIb_+=iefks#%6+Il=|2(Nr zMgf{*k-dh}94O#xBOKgugaZ@J2@s{fp@vI}nT+fO7go~o2){*ouP%X~l1&3#;`Gms zt#e8XOAB&+sYpV;!is*hIU9T3J^)UA&_z(&>=M3)Q*88r60~ErTzvYa3@#J7*C1l&EZ9y%S!0#A@#+Cj#ig@u1&&#Ut$c;$r=LX5yWmRQ2oD z?3IbbanL9)HqJ!YlbRSTU0U@t3OY0WLFR+a5Mn?ts#<6i&5(=6iZKV+%$~PpPUT?& zD%qoE`;m9kAoAcJWRk(P@(67~uYHlw6d^z*-?g`R3cLhkWWWVJyW0p2U5wlPmc&3o z@?x8Miw(BMHxhnRC13*y$V&1Gl7)oEE#9l^S$Y1_QBn}a2o~P+|0Mtk@dsA#t!Vhl zF&m%Q%3;VY;E~oN>X~XY(G9tq7hi*{Q6ZC za};{;b&}+8zsJ??P3Ul$Tv05N8NG&x<8#Q=!rZ zuCe#L`)S)j1sjSZ3b-YcG<);a4W}cJtQ(O=pYT@z`Yw7N-XVxzTuKX*cnvoKAQUj^ zl{G)=F6MIdl$0T;(3mCb9UZM(^t?E>5jIcwcP4bhe+O{nUPrHvgFu=?`dHZ=dd)*g z#mO<$F{w2*-yEkU%f4`Ztu;j3rv=!b=y_J?69Ff>IzjBAmb|7;XkT=DgR2D$Xdb-a z(aPCtqI1ap`&jF4K*J~3Uv!=VJ$%!}rjNq*5J8*0C2DN3#eOVCF*d~O2O0%9AAWi# z6g!fja6)X3m|vX3r>Bi!u89~#QzyEW2{7oS$}!6Pw+)ykby+-H-saKQ2)n%>q_mJA z(3fBT%n8GQ+MLM5SKW{P0`=G$Efq{z0OwZERavj~$rZP45 zs7q`6lt;|vL+2lZq~n&BTF+AzC|%yHPqL3=fWTMICm|)?k}A*l+qK#BOqkd_8}SEu z*U?n$Mo~0^=TK-KQ(~>vYIPnLDAXN=S7+x%Xsa+x{I^8&4p{b-pN2mDj@AI5(cj1) ziE2nkz>^ki>-idUr&` zI!31f7g3a+E+n7++09||sK_1X4-VS*#gAKq0lAB>arM+U;e|IA-CcEQR{ZJQS zdz&FHE-zQkS=}y}U+Z~1Ql@wOVcCF)%0qU5X#fVYOoKp6xDG~fv8&YNv4@pyNd=!(2_(WxMV~?5e>B{{HehCgzOH?EI+&C=M z4P}vy4SC~tK(DK#faP|&cZ!9arSf~1uqLke*VT`z-@&8{Tr(j!DG00!^2FzY9Fh(_ z`$zibC8dR_KN1wwRQw!hgN4s7#_ij}(-d6LuMwd?u3=qihFs+^D?8!q4=J~U_`FGy z8BN#sd#k*yCDgUc{2oXp%e&^gl3iMM`y4`1rST#2)pPSp+!q!zf#nc`&(J!W?8)1x z*Fggg5SSr-F4!PBRr#ky`!UMaelpt(%s^>V54Sc&jNmHU-)SSb+;%e$@eWAM#=X>|Bh~casS)<3?1}2R6o_ZG1pzeeDeXO7= z9EnqxTF29M5c6buSSN6oD}?>F>D0b9c>xEDkR4OCTJIr%>;V~a0~?>mIw+|qbIXfg zm6SR~`vpfEq?bH(XZwHWd3^my7oxdo?If*W13$kY%+;tg2E&{i$aIt_oqJsk`eC8HqF4v6AJC`F`ClMlA| ze7d)rQQdwWMo)uxr8;E!xsEcb7kV8PgyL|q%ii!k_j}=w5G*!$@Y^I>WA*FR2PdrV z;q1tx%-^Io?fn3pkfFjvjiNRPWa5o;!`~qQbjFg4mxb>%>2{M$mh(sQC>SAf9QrXV za0{n5r~8ERsZ$>T(w*u*B{3jvIX_2p?Z-U%>|PhG%0klOZfY>f!6t}gzy6xM*~zS2 z1I{Ps-{?$``QC)U4E`TDAZ+SI-0{qmXOw_P(hXdK7LVGRnmV=SQ+?L4HP{^3U?6-j z*j{@m`ip9dA7&aP|vMn(s*nSxY|@9h6Bggg}Gh9_s{W;0qtX>FNM@{o7MFz z^z?#U?(#UzP^32)pk|u7mo0?1e=Sa`y#hDr&Wr5$=ov2=PjqE~|0L;pWBo#O6+`g< zkiA59&tj%0tiQ2pA@(cO4g?I0RVwH_Z{F3PqHJW=eE;58HwT<-c!kvQ9p*-wm&A5A zO~qds3_J}AW^C~M$o0G=T7p{;mWYg~-_n^h3h5Qza$lveTYk;VR4~+^sHWyxlRgJg zKmU~rFxHYf<3UtLTv(95%E)87&%`PLRqW1BKfQO-yQ=n7JsH*9Xa{#<)VPlPf@_S2 z&6cNc*ER?y%|ktI8GuG2HgS$&mb@xn2$w#BeA??y{O{9ebc2OqF%Y0=RW>L+y{hXE z#cb`XpBO*2;th;Vr{poH)P}%NTD}ZAEVO+thts1R(0M$3T#~-BT+OB_$)u&Hoo2Rh z^;mlMw*qtvbdq$C&p<0(NFM|meQs73JAk${O@GJoxM!OFwLd+4R}`MugzANvfX8jM z5siX0mBn_%^bu5L+wDm$G*u8G{@bl+xa0c7E~ISSMm zd#on-^tS3?aP?nq(#Gt^f0Z8~3j26eLgT?xBl2U7*CToH@^(9AaPg#W-g%GXTtj>w zhvGV7su%uZ*(pz~0o)Z^F|A>=o&Ld zLt7Vj8;dIs=6>#D2FgSdE@~l~YS*w=9PFx=XEs4ZU~ zTq!c376qthWff!rLHO;EI#h0|abl$kZimR1i54hO(7$8?8Vn6QT{QEwe@9LDA9!_z z!$XEkOxX;E9`NQM6Kp{I+EqD*eF_6zf~dS`@V~ob`SM-28Tazm_q1Pjf9x#hmRu~^ z1YEdm0|Z4qc)ZSq-!`VcoH`N<8A4-O(EHEo-nlOt&*FAl6{QG1M6Y3GON~HiM`3Y^ zo#U679FLnDY$%MFyje5=XCcaj@WlpCfcpB-0>7%Jjyq^e@9!~Qoyr&HgXykC>{w+| zh2x|yfae7W3^;zEAc&a?m~O=ax4s>|(82a)wPC&Y<2)P?&Dicpm4qDAE6UK0KWW8J zr(f!HS}6gz0zj^ltzj~zZ#Jz>m`MbIs-q`l=nyDt2!60UCAKJ~;1H!3M^dk}BDy_L z&5)v}<1vlWvV6orCf*h>?oUhFw0k!;cn)v{m$zPin6)y`g*}qloTflI%weJ(je%Br zX$936HO#$>lyV4`VN+0vsaMmOULF>e*z}V16q+uU9FA9xk5#tnN!2(q7{6D~$S8$D zq@2!@a`w140zUTPPyI6c#*>3n?SDGko-9Pp!gG;%YW&; zkjm|C?$pBK90>$|+-h1-rf!y$9a)t4HEfGG14f82)^o&At+#itg}X6No_~M|m;6YU zKBjS0D1`O{aS{b8>?<@)#t0VqZA;b{BB^%&$0>Cc`rxDE^KP*s48BnFjqmCFcD)7E^yo_>s?8lQC{Pf%>AuG?|HUWT2eH6lx zt3iJ7$Dwx(>T@K^E=ux%$P%kweNxKXe`V|iZ^(+T`1n=-8%*sll8-X-GLkBVDau^; zZa7~{av0ee4fOI0OJE@eqYvgPA@x!C+P**}uzpr&&RF|}T=zFGxEz3~<}>kUmhKp* z_lCJ2X^gSfdnNHGAs_ChqN4nL(><&>++W<5*seIZ1TndJC4p0?EP1tSXZq@WHNV$- z5>Rs7oG~ejN?TCpImx=dG>+G{)U-sW%5@YYgrH1~kJ;~YK>q7-NK6qgp{CfQU;(eV zv}b&vVrDM9(NM`%0YC%j4N7v-J6}_>c;xU%whL;>$h)FLJx(-cvR^YE_|kWgUaU^W zO=AQbs*6&RPNMbK>^}>op2Yj%cSFS3qqY zUXKlWhctrwTuKXLIAiu3Hs=LP2gm))LDTJLp&cIzxKCX!R#~bXmKx6YmP&AI#ZZW7 zH(h-6HXvE3?(u+1W2B>P^L&P}M4glZ&eenDcF>TmW38ilqS`W1VazcI^ynR%=jBHM zZL4;2rk~XFM4#K(*c_zO)Q^Y{({S)Ia&pw<7e~ruc?Tmj-0y@m6gB|B-;V9y3UxOH zOY`KSZ&HMWM$7&!Z;i2JPw)agPZ9{?TOQA-DCu(wYb42i589KFT5t^%45Tl@xtJDw zV)0Cs=n{lcL(w9nLdWIC#Rp}0?H<(NYW1eih}B-Tn-QA4=z12T6bmV5A%BhKYh_&@ON!KOfgzl)D4mjm--}2#Jf?; zi8G}AvYEC_U;KuDg)BD6hOf~q+kz&E=OHlu<~iUNwLkAoTgaBZ><;M6{iCd;I`K=r zK)v911sS;WaDOW*$oKsIh>?It3$t?S8oZ2&rp2ovuf;NE^^DW#afIgdEj|@_b3{}c zAS@i%9cPH9?#g|!~cmv6=hD2dr0DzB##*+pw#^I8VpUm=ni>f4F4e(oAeu2mz=lb0zO^+A@_vnCjBL$L z0e}3dPn=|f@5}53&ifPDC4mQ)HN`KM;%?dv;tX^pG$`Lu5FQ9PvxjwOo#4-md8k5f zb~+4r!buYF3bJw(Rdt*XcQ4DYzkpWSj3Np1bXIfTJM10{hg3yfQzAzWM2(PRP@rnx zx(k)T(6DELv_=3Jg3rz|$wBC{kVl$!^Rg8?#4q;+RhBJ}^*nMC9^T9D7bdt{Z%lGW zOsgvUDydo3^KG_%>(RJMXF3`enOT+!$Oih!`m74=vtN^O1e{hpn8Yi2s)UB>RCd9H=`! zwg#;7=7N9|#C*MM6D1AxTS_V#9_~cR471SP z3cu@XL#XRsjAepgRPKmuV3=VqYq1${ukadv2a`6eqf?9JS+q@LL77B62H^ z<&$47W{Gdm#hDb+{l`SXU0@3XUl4fv&vHJU90(?NuWPyN*!Lc@W&(ERC%?B2n+Zot zGAceL&xT`TBeFWDRqv$!}0$j zll<_Z>s!W0FiJTE`OC*MI}pviD=REcRQ(YsA~K~kzHqipHT(JwaEQ#ammPO#9qlRN zdN*N4plX~3<~2T=A=hjl?HyGcTCn}T$Wg9V20+|5{jX4)`0&nkE`_#cgt4m_m;3k9Jh%SA+CGU7~ng!Pymb7&tliCyjz#*_JO}=%% zBWkr>+uT-t3ronD<=OCe%Dit@*Vxp_up`407mcXN10GU}R&si~T%nb#V8!-HK0SHK z?F>L#0DuB$L(rf08U21z!knq-%PNPwh*YnmCBdG?q4t@z5uKOJ;mIo(i=6C}>_nDs z!c?MUY$P8*vz>%v-N{hb6Dsuvry1?;wPT|q7d6BD?RUy~Py_%gSU$WB@qEl017m|^ zJvLKn<&HsTcPpw51U;{82Z3@Y8m#XTYD1m+foTy0Wg!M#2i=GPylXj7R)ftw<^abG zV`+xawN+gK+&BOU>ZlyfWIT0fo%p~7x~@3o=%2lYAXjuMz=bL)K`~w`N3J2!8HmV1 zX9=DV!=d~kLrzDG6iJunIa5TER&Yvq+l z_QLvrVD?|gsLRZ)%r6#KR?i7lkDL1X4J!s0F!v60gMAZwxR!)(^`fIyqQNX!v&zwB z$Of`Op*OiNaw{cD{XXb{8>ifx1LN6}!>SCcteO^Z7t(oyQO#liE2QPA@i zywq;_UDR%))t8&5%8)U0W0VA8Yj+hZT(AqVktQ!ytE?o$sMv+wr&rt^PKe|+jdN%sEu@5g|rwIX=DN|d43_|J#`UZB$(HHGef zKR(0d3GE97q%Wv#(bzG`mPv4(t5MNW$?>Ub!^XR&=6~(?OlG4cKjZKTpc#ocR@t^y zp2Vs|GtD>Z1NOgOy>=rrGncjKwUqCtqy3q%(P043m9m|&q`a#wf1|dd^!Vg&5l;VPtZUfEiOX?!=i|d>J1(cn z^s3h!^d(J&$^Gj<^ML|psL3%(nrFz~2cLzr#@-&*pJZ`8y7#C^(qI^GnRpIAe8+GD zsWgCZp&>-xa<_JKvvvbf&g9`oru#GV+B{sOFMQ>`9EaP?Of!o*`U{h5b6U|N9z9_W zQZ+IM$`6hxOn2&c8h~*H={r)X-V|_=qa5y&CHdEC1^AP%PTQQicHK-?D}z<<4@7qw zeH-#H5LFUB1|e8NFDx&&qd#So{);fS1qCh&w92}|Vz}P7Z`SM_Q&I-Izf&p}94=G9 zRfsF?9P6Ot<_TrtySm^t^!Cnmny}iZ@#z_x(C_VOe2P!EUL?=Zo0+Sw2chKO!<9KL z1#PQ?hGluY_?|8;oaCc~8JzgPq|dke3n~?O4>N!8^zvFd-(CnoOVn(x+H^xdqnwTmcp|?mDgdV+znfYZp_sfiI`pYcpCvQX zTtSh0b5jW$`@!oWED+@F~_d)PlUcnyf4aHmHr3u|!5X2HxMz z^N!A3s=Kamut!%|qyiDqkLY`1PEJ>yZJ#Kke!U}B2h;|(5_{kLP*xHiA7RGl{50Gp zlBnDsQ}{`o1_60PS(P3i4-b_nf4-4B{k|-k89mX7@^ey@eA-V6$2jns+GzrI`%8&J z1buxQ+GDm(DxA!b?h>8rH%`0yd=5M1yv`@vlo%3PqN1MKB;s$3v&8zFYY&~4e68Ze z^DMAFc-&7v+*!1Gu1`>xm~B;H_zz&;njaoQc-?g{v)W++IKR(rl+jfIYvmB4F# z1#(_Dr#9xs32A7@v293SCjBu)`Vf_$nfpWH-Onar@>y3WRRvMjm=7o|mkIAW0F+Jm z-TH^7v9raU#a&tYG6hZqj+BPsb>*);Cx>7n*jabpoypBob2B4H7JDNK5Hz_C%h7Qv)THv8i16$9 zWOM}d#>Z1*u5#=iL>i9NsMOJ5X|a+|N$v)XDW!1e4Q`HeH|H}M)@cF;0v?em((^CU zdM`-%6VcIqQz{#xnT7>oeYSYERRx#7!i>r?$OA62bES|*%zJK7rG zI(~NyRMM&AiRd6< z7XmHZIQh5Q`FLDT4V5D!ao=*ziDw7Wj=e7Fv@emhYl?Rkc~#!S@DTmI`Bf44@-epT zC2Hr9dDQ*uFwuSQ`?`)q4&r`h$Z(+nyU8*kz8ek$;SEM)6!ULM1VVxq2DQlZ9rRSo z52pF6ZN9`k%;?5JBd?;q++OYn*WrBC%yW?*tseR38c$yORlVyQdk($ z+BY!t$ZRC(s88+`Ae_N~4qx6831g z5nuGJf5?azwDABiZ5}#ky1Q*@uI7*Zjr&pM{gkJ-4rp3=R8lPYgV$&Cwt*|u@W(}; zWg{}-&d#ysA)})zV5-4@NaD#~&Su^G0{P(3*g!8UuRwFK*mdP;#nYwjYMi(9sM!yG zhy6C5thN4EN3=-{dom1i%Pd>W%_3n zg7&FmJz-%7o%%|!#n*%CyuaNapUZlOhu7ezui9()cvgQ!l`XFaw`p$s!k<3`?m^i+ z+idW>-QlS<=eL4W|9f1Nm?VpgMA6HRKpwOAD!^iV{2LBqriEF!%dOII7v~c{>u@kcW(O-C%qTL)F9$t?uI@bGB{qNCp z@FE2g-<0GODz)lHJO=PkG&LK(%V@c|P1IN=)Y=r`5&q?OfG<+YXcY|pRFle*MMarI z#i4wKLPto*Yqemywp(CqR*;^r26m2C=zYANt0t(a0VUA!bq5G+e;)o zPv#G#Ha6kbi-|hn@Z*%jo z*`Fuh|G2*sJJL0Vo+4}SJW;>f5w13yqqR6xs5N!E*8{;gTrC+LH-U`^Jp+AWi|v+6 zgsrwz_N1t~(uC5`0-yWMMb7q73P4V=!{IwB)%KeCIOq?%>hnrUm_xeO)HSz&-{>~w zL3aKf^Et)n)1rp9&^=#aik*}7lPjpF*gb!NJ3|B*%7>Ut*8HeM3SndKKIj8~dp z032!UgaiL5bo*(2Mn}e{(6W&PfC)LJ%(E3QkNhi&hKf_NU?%u?p(>Q!e_C6A5W;oyYa z-r6G~MP-opPjh{_vYda8#Am%E?7Ye6b#FUY#RS&$wtADMASCm0?JqUY`ui8=mgJ_t zj|}Qk%~$Gp|BdR|^ImPMS_R^+FDI2o%Wrj@T5aJp4Mbl2`W?qK`&R2VG~pCH@oK)- zte`++kx;r7zt+ZEy*zzCnY-g?$x8aiZ>c!1Ry(7U&HgK?*d9volf4!jr*rba9`TX# ziYTcLCZ-k>^Fpu!5a6V|y(Ps;6O+$A(EDV)~A?4ZK5#Kt-hr*KP)3XsR>3yTRJPY-|TiL~|g-H}HB{Up;a_@07( zHQ#C;BZ4U56^8yh(^tO<(BI1o`8@SREvl9hIcN`2bA65MZ!XRDtDOnH_CSvdRa)W= z2te7~tW>E=Gu;-X)+0|r{kX8yY`e6y4hv_bJm!}rmQ`!*xKz<`+2%VXeA?vw6f!eI zS;Fx8bNfSVO=gBa9?0-IKvvKnS(Bm&7f*cgfKyY&4%-IQB9%zL&`KBonR};P06OWh z-*u=j8k|x3I~x6`(XTz&w%{b{@XIi2_s8!_Ris90h+rucFav-pRJ95tO7#;Mh=FcE zoyf_89k6}?yHojy^cCb}BcXW!WDFRy(ny+B2TYgS0+fVs@^0WV{p8n3&p3IwbE`6| ze7iYDMoHIL4Ug)$=_JScwf}FrQ+FT0J|TZc=^Yp@E-q2Xrk_)HOyV~-K0a#BK?E!( z(D<|>Tn#e~fd2zo8PLZkGdu7B!FIl6uU%<&{>0=06%}QG{9v0>6~HHe6GjTCS;Q-m zTwY4H{kImteu~(-icA`x8=vy#&xrM})i2!L*2(b)H;pACs_Iwm>m8uAT?*Tq^}hb; zlc%TC5fvipr^lagWneNHo+(tIHwE^9R^2a7s9&5I{-=&wUJ;XWEFhRG7&ud2+K}cN z=GYOu3up-Vmb{o7ks83dJPEdY8yW7@H|Q7ny}{^po2%N}*Z{ZC6FLG4I=a;zc~N1% z$d1vfU;7ot;e*NCGn1Ll$8X4^HaB`_nsO`+4d1zZkvvjMsPBCEVLLn!W#4%tC{g5B-=pjAuK{Ovk>WxOr7|*CHg?Lp z73MKr*Qd|uC*_fGn_S@xD<`9A@ucJM*~W&_hP@vM3QSvn;8zJ1e;v0TwPCU57r`<8 zvo>Abko%te=VYTpft0MxH_@(6zsyW>5ub}+q+i|K2kwbFlo5ccB}j8dVQhT-aIukr zy=rToi_zV^ezQk~Zhwg%ByC+$m8LxqbqL4ba1)SY#3HH4%eOCkV63?C!Nc&EGZyb`XI#2t_ z93`WQ^(xX~?HM#-WDF}bF;(JVWd)_1nYsvg1ReD?I7eg_FIe1N)$EJB8k2f4bTtG; zMvop`$Noq_gqjbNwl9~inzK#+X@oWL;PC%Pc1$H1;q)PGSy`o;nbRhmijVAT z|2hxn>~k2O{}94X0vU{^)coi-(M_Dq>a7=nV!BGNp_Tp{qK8c|E$Ihmml-Sr>xqi8 zO7qSARN*%ZKgO6NH&lzs-_>A|$H2-mSaNXOe7fk=ha`Ifd_X|1KNvRf2l=L??3;yx z=oxqhT$YB*892qqNOxB^M8Fk|H)b-j^FAwIY40?NIuxH$P>VK09LV00q5mbKMFU`% zBhWZUFUDr317VNv;|^o`sj7CVl%b z)qles;E#d=G|r|`%p}q|U`Oh=wt%4E!`9&ObgA-cQz%cQ9yz## zq%AN?!y;rG9d_>~i^6tHXB!KD{!HWH&AYiab=o)P^%jtpq92;Sd&ri+z{kXet*vA| zzOiR~`SLy$*~{~xi0tDCqSti2y~Wtr(s%sv7eytj)N?n(5@6(4lv5I3N1H?cFg_v_ zctItrNEWD=@N1?!XIFuvDqKIL9AG8rucW> zpl^d-zd}?w($S)c2)E&0#vI241x(*f-_rcEj@UGQR#MDg0sdP)o|_Q>@bjJzKb!;2 zxmO4x5yzJ|PCt6}^`*Q3;oTo>m2s-~zT)>0Q+R5jyUGE<2Hz`1Tsm_)6RXs9pfNgT zz5ZX?;Cek6Av@!c!XJGRDs(iQb)W(Us1ssgM(b#l>$W#dEfGL(fL4{Z@6c!(Q)kfe zdu7k3 zt2abG@v}iIb}JAC&u#zx4ajIJ)KF9MdPuZ8O77|mu3Q>)9Zs9x-sE7$a|K;$Zru|nV|W%T$Q9LV*!nkOg&*?C3Euo&eTVFjSUYO|KZ0vqQqIzZhQ`;T~m*l;KA;>B}Y@BG^Wz{-%8^iUj&GW??TU>yGV1EUNTaT4+vor7`86t z$IF%Z_=XmFBWkWk%`Qs3t^YU>BLmjZ=UaL==^zX z?iWh(Ht_fW#mT%|&r^4#QS(tk9--0Pgz^xZy?D9Y-Nr-lm%=F>0mP8}j`ZPml=wN- z01A-Khuwx%9Ioztrv_>l$4bXA@vve877isser?j1e3Vh*gt*1s7i^|xV-(s2CZuU% zlw4jvf$Z91^%%*>?A6}v<=tE2Y(+Dd=W*}mtU3Qj;#`6+S>FT_@yBg-wFgi7(7<$*h#E~>?1Avu5Vy>6okIusquo){&$6b+ia=@LVve>L2 zSM>3Gn<|R)Q?>-(-NlDDIE;yB)VUy{IyIK5<~6o74tAAVGqjh8DZU9rv9(XYhxFl(dK!xWz;; zNz%Cry;zb1zHq@}-%aP{Wo4y4vcozdEkoUx`z$){fgBcVS4V@c7x0RsbI+qB9pO8^ z=6--)gE381Ny*XfEFB4#rmybErpiGf;{#BMXh z(kFtQG%fS*@u*GSV3Pas0xkWY9_geJPUVowv)81g{SsrTa3H7!eSbP@8Gr^IqT6DyY z=@R?d+F`djc5O$;syNlhP~4~_PLvjx3OIbKc4XVc8p>jG<0j)xl4i*0Q*&~&*>8*mVu_SfzIOUEMP zk^^HiO?gGzyUj&GC#I!Vx8qlFe{vprvh%I-ngDbNCV18nj-G+xrqlZ=*fPN(*OWhe zkur+{Z25nMYPAp5+HPOpX|!ZGu9XLW{2ainJ^(ZdK+%$NTzztI#db|&0fO0VJ}wz!8v|Z4ShyYY<5 z8y6_V14ObQAD~1BR=gQYRv?D};wNw^1LgZQtN;X15?CnDH(ZIGDJ@Pp67YfyT#3^W zDt-TV={1kk|0%s*wASUWH*K7~z7_0Y8UXI$5X<~G&o-2SSRbZsY=)eX7p1~?sON}` zvYk0AqyngY31XaF7MESDG(l#8Ks_TJt$E0{A=fqxpTM!>ND}x}Z-u9YT0Nth37EIS zpj9t`nA1&)=ox(Im~a%MW0V;g-gR~DX*Kw$Aw$_zHc4kEU!Yf~E}+Cny}`gL_fb}Z zhpKmXU0}Yd73&*|%B!fbvS*u_ifhDvB>x$Oi9qmd^vo9vz}YGrH3nRL17z{ z6C>3d!Ui|>|E|02+?OyuxhcdHbckKb=JG>j`e4(=aw}RqpL!S2>i$7dwm&cQ^8@%f zpQ97W-Dy^I=tX3a>hsIXgSE8OyU~c&k_QQ-y&G(%{>lfVZllTrg1nWu?75ISGc|?T0(nKYxrDS{6NT z>>wH>w3kp}qQ*Kr1OWpec}79eG)Fk(0veDBuP1A6GmM&V*ih#Oy~Dr9;Los<^`b8z zmjZST?1z(#zmA;55q|@%u;QggkZQ^%z(VG+u}6}UHUVg|0`@NyM^BRIkQWyis6M$& zWQo<3*&J&%W_wWPC|8A|c>?WV;3JQZtHNLBJwea)0U%1baCA`4rU#b*FiC$EK8u*f z_ayd&zU+>6&rP^3Mxo>#C-Ya_;6cC{S86g{miAY*aZ+C1`t-pMXL?4O@V+TJ;%z|JwJL)?1LtiRj;MtqWG|g=!r6%E_C{ze^F#Q^-FE5JmGujr+B=q61XU zVVB`n43=R^6Ht0#O<_$7&iu@8Ll&4eXgi z;3+$3fdPaMyc{uXaS_&L=x@GrCQ5_7Vb#>r)Tk-C%ONCS{~B;Ew5@VNZD6Cq)bJCM zh|<;`3LvN;|P#hVy3QDL?Mu(sk$CIR<&K@(0JWI8a>&vYpR>RpP zY-jDo%P)?{OI;*E)q3R8UwaGTApQ~@P0SM^`v9LVa>asiMMV)00cDZrgi+`ywUro9 zyRC0DGkjuAr(#kc3lY01$+rxltf&H|_n!PMM1_e2alc>L)h|9?cbK0U7B=ueuL%kY zr20(YiO=@;;0sNK=_bjLDI~FQ+rYxoS~incMX)$h@8!`4A3)`+ki)BVC=e#czuU!} zL$hGDjIa6j?I~X#)U*h%2ZFcc!s$jfHha4T`B|9WC%R|7KNb3!5^HLp^urZh7VCwg zjF00?+EuA6aP=@`a#+|=CK1-hOMs6RwEF_DRX^sj@Xq5IBDvhelqlI6IIa#_pYO%O z;58ea?zeGJE5TKm81Sd=tVNiYeDBOS3W8Mpf?T3^+kuc8ynPtATSjt%b@mC0|Nue(WEest8a|(uzlcL^iuXfM-o? zjj4d>&i;;M-srl*dgNG2LRv5GiHUV8o8fP{3)~b8IEenLjHFVRCaYm~F|f-T{bf!n z=u5C^GQ@$yF-hl#;K4Au8aMDJzs5pVXLbN`I4~rxZ*EUR%r%4Iu;F%OKLh^~zJPSb z*EF+6M<;g2o4Fc&Q&Q7>D;TTcs#1j_CxPOgppZafSHkoqY1}Zc(|TP);cdtI-(lC3 z*=GH`=^s`K7AEl5(&8fqeRy>O_MIx6kb~qv zoq(VDP=d1ye^33hhs)-or8z7<5GDA9SM(=VYB$#wpbw!cqknz?ALw-TjE#Vlu z;d*~YVSYOHOG7h73pz1kv5x=+z>#*6B6wCnGruD@MZLbPRQM53V?(G(C$?TGnaU2_I5vXRE7gVZ8{A7)>!iG&g5C9IzM(3r4pN z5RFxe=~RI9qoI2`1trpg@p@4 z$pwQwkPqj5w-LR6`)~Ta+Uu_(ysFoqjJsJEnAilx!0|Qx_GSu2KI^j1Q`6~LJQe2A zcU8@#^XrNqzP_&gB~Xv!d-IQ!WwZi}w)dZTpSb^{TZ7Em92gm!nq!5@N2{y5JX-Q; zH>#5frKMqfsDIiC&4mO^$z|__TY8$38&>SY2rcwYfXHRB{NlPLY<-;d2%aN%$`Re>ZCg_u=_zfJEK?DSy9$prw=zc_~SFIcl zSkjF^Z1#akl^iSNIjkK$x5gt18#@Y0wnV5%<~{D)d~@^b1?j`sto?(}__*Cn3=>DA zO>D$g@8l-TCjV}!O4exsfZEvD2*yW2af)h#r?+o7E@}1?A|PUe2?#7zN`BCN_LWg( z;n>8&r63*r^U_F)P;fX`cRP6P_Sv2)h)4(E(xm~`)9FGz^$XAa_QgXyoY|Nga4i6m9%B7&?B zG6sRB!W#3Se%%2@l8@>}__aB#z>?-deDUIom+JGJ=WDSjlzBAU7IUhg##_u@ivrKW z`l%}rmg5ZqXMw_SpGCnNm^P50h0^o_?1tGWkC-VcENX`b;pAmcaFKyPaPXz|N!ERv z7^iEJ|M6ENL*qrw#dmS#_s>L>7+zzDP!dS6Q{}UWhI5orUSVkJON3Q)en)9c|B8Z* zWkyG?@NBpFNFnxc^KZAmty=8js^>$CP3kgRT6cF~N;9wh)<6QU$r1nGetM?0P8=ccTbS|n8d0`Ov-M{pLJ}92L0`k$>FI3SD zR;pZG$yKc{n;y`doF~f93WtNz{bBLmE@eYQ0+Vyh?|4ox-$uba^G`n=!rm z>Mvf@VB=0Z47vr?FRbmDCdS5ks^QJ8@!3;BhL2~VA8Kh<&nu$fk|JL zIdU|4%qGWlon3Yj@kVO6GaanlK)QkEoBEdKb@}v$y)u%d=TpT-?UikDts= zAx%;@dXQ-F;PqJq=}V}1&|4Z04i^_Od@4D{e^^%`CGz#=`DJqQ$WNh(xx#WEbjS{k z81}Q$E4r;9o7YD>H1F(REa&Ew%l*cisjugdO@ob@%lm+yeDC4U_}pYjyzcWyG&IYR z&7bhd5MmjhdZTk~T*Kkqg3Fd>q<5UKaOoKmc)3MmHF=< zLJQw}dMF!he8scX5fQ2PrA7)L4SV;c0;=}8n(E7ndKX3tgU0ON9?By&zk9FqQBB)0 zC7;(}{}tC3(yXS>I=3|_&~v_~@~!q|V6sbxp5PxC9~fsCeVJ2qVy7%>s$Coy!B!`{Q8|x5 z+aQJwfS>*H#mv+gMz4;;v zWz%GoRYrps7!ei{<`;3kYX1mlV`oerclhShl)egDlzWD zRS2UaeVx!AGnA$`R9R6Sa)ICWl|dp;ylB3@ZYz6%VpsY=Y=UKcaE`^Rrnr<`Wo=u1b z-HYRw=o0NGLx%>qP33Imcyk*s^D1?}kui=MwSP{==!vC|KF~VpxHcgZDY)Idtq-#C zY4RES#*NEs4I(4yB?XsC7v`~XEcF#Xxx}A8%iL>0L>_Ex?3hi;vapnFn}5sU$(8wV>}}8o z!qBVS3|C3ecVkc8^}*G^y+K%q#PeXzOZ0VCY3bd!XD*`Qi-hchcU#F02m5j5<>ijx zc#494ZFQ3!T3+7zAWSI_4+nFLXHrs`>{e_US*Cb+dUuqKE@ugNZh_Ofioz)!e%pyRmT#dHqeQRj`k(>88|pOk7SagPjBF&>8Gl$|C})$ZObV- zqCX^88lkz0qb`=f_&IbTz`w4k`GWXthnrIj{#)Jp`Y*F7Z-KwRO1!9iU`XDQ3iQp- zJ1_Gg`^jVAs(9X275VxeRatz2BPBP$#WCDG(zdB7KETwX-WFX|i;_VGwX>_z0=?JEerinOqMxdj^b~=it z$Y+WvbLWgh6MiBejD>@+@GQ=A72ps4X90=hf4Wuq8_P^dt$d7+*YA(Iw!YE0Scjc6 z{#TP)zE59&68(Vae`^7l+03nPS6_g&vo7o5GGSZx6zp)p;mBsoByW+pTHJqczFJ2bmAZr%NwrGJp?~}D}6uokrJ_UfOB5S!fwrH z_A|d6Uz5b}Kg;w}A$Bjw&d*M-);YcJE~>zVbj)<`_GId-i5Gl`cDdBJ;&Cm%IF-!7 znm_Tk$uDJXM7g^!lrmO7+HC64@FVyM+!*v+(gsu~1#!BOZPGv}j>HWvEB;Bs^HQN- zFj6rB=pOyPP45@(JJB!s(2^4z;9s|e9LX$k1)t8CGFL`>G@eU6;y=S3;8S_Jp47h^ z+;4t3e|f40qZ1eq9+C9+ZzR(=^XuUy<^u~?+s!T;5-av%CA&vIS`J|tdHLA$zrg{> zMvUDKvf7~Q^St@F!?~BXn@-Rj2i{xdyN*z^vZePzdcyN=RP&XtI6 z;c~|6PZf{hJlU6vt^{s-Hb$u>x^MwS509@Cxg3M8bFjt>u4 zYK>~+qrW_sThdL&0886#Y_9lQ>Pn@>2A7^}Fj3w9gtT|ma(Nfeen);N;=TowTwb}L z`{qohB6*owucJ}dkheq7#zlXB0aIt^zB0Vj|Y&u9hyIx4- zmYBm^N>erD^~mqoSi57ADom+&@0PSZ<&HDVe*F@!dsP4jMSpL#cywP+oALKoUaSvD zem3dkNOU=86{a~fBJ+U(Vh9O24I|hw7fhX&PT<(xmb>479}$@*OYxSGQS5BfgTsqx zqb7|p)|cI~efIu;!gkET;evoLI6WOaxczh)KH|{gRXNc&Ee8Nl+n%TKoYm|T9e$c@ z|NX-N94v&0C$0QBz+ZQ`+3T~Uq~6!BqYW-Vb)mz+MzuR)-_haKp;C0bw^thOCnx7^ zH{$J`=p}$pHf@kA($#Ca>Wdg;x7l!5w^vC+Ba+Nz@MfBGK3(5TB6H-_I$tU_D@)Mn zh{#()IUw~*I_AUMC^3orUJeTaT7e~_T=A-pg8}y z*-kDAg%|F~L7(`AbSf(xDkj(`s%_^gUQ3GNi)M10th2C|;d5UTiro6YoO~%hq(&Nn z^&9(h#w!&>6~7Oee<~cL9HbHqgM{=9_56`psYoJw@^gY(7D zD;yFJ65OQGY+N*0DtFD7fcLL}+=9>|Q^^3b#kY%3Qk5Q0`px&gz^uTa+9n4pFENug zTKMuQ3&c*;qyM>vV zu}cqAE_85EKS*dmRaHK9xVtUAItMTIOaEXGhAoHM=H{)m^cRh1L~jGy276LXO!3@Y zbQL}$TT@fbii`gtBNKr`IA`;q#72&1V&1Uj?CZ*|e#r3yvzN+ehLiJKrwEUzsQb&s zryvH3_}ZL8slM^??y+*ChKTP&qN+-iig`Z4!J}KDKigK66`#k&?{IO6Bqbpu@nR6N zvJy^AtX8pQ<>p2Nh+6qbBW98!YfwWcm0c zrN0|_&w+dz*dY}g%T)SjV@=QoV6UnBL!62N90W%3QdgHJvNw>M zt5;uNeX%)vbf@60pt*nm)~m+j-Q8UUg}EO;KtVk=K2F9l4f26XBO9;Y-_Z>X#Xo*L zPdE`BkAoMe^tZabF=2>RNa8)ZX-fhdu9n5j=+9^}W7A)K8@l1d_;qz@#X=Sq6G%vf z!opy>fcbXU6X}Md`i`PRlE%{WPI-8|oq?@WobgiZwX9K_kYrkBNlBwnDFr$BWczOP z{q#S57N2Fd);CXg_rUx!Z1YzQ#Sa+T8`Dz8;kL~Y93-jo}iR)O>L2nx5Qrqg;S?z}wk%PoZw7J(LU_j6dnqS=L7JgdWR zMKxeuv43kcCpqnZaT5ztd|wvNf|O4jE=r1?LOQV77LYFR6KW~USzh0uT*xkJY>cSq zzE@ZANsJtmQ_8fi)uvHbc0JpyP$@p9e8eUhMeBS2E3Umg`rchjGch_gR_gQfUzomu z9RulOJ|^emHAE}t!i$rE{7p3*am)TFxJ=;X#AO|>_9j8(S`JD zd1e0qtw=}rv*T=&JZ=vm zW0QIYrksx3uiZC9LgrT+z{db5VX$xC^CJitr8@(kOQyjJ`>{2-IvkY`VX?`-3Ayxsdo=T}2pKxsIbs$`$syIBqek(EhjB?1G{+1LfqC|K0q2c(MuSk~RxcwnvT+6vr> zZ?RU#C?*`Ag5l;vPhAQTyFh>Bm@yo}TLZAK!G(pDyP{$Yt^zd7h!7&gW5K zqyE1C?kxtvpq`nU1sTzKpc5_rOtK`#G5n+l59z#|jMuCO_x$tp=8FVgBqx|W)i-B% z@2wBcw%+hQ&Hs+2#C{I7*q(3q1O<6uBRrpGz=)*a@VGrFZl+=>iDl4TeFzs;8^Xiu z&6IbCi!MI;KK+F-e{j5sDd@Y3ChfkKs|>AeZ36hy*nEGi*p(FfxieU7iv*ILwX9}- zRT_oIHa9P1h+*MLE#;zBHUyIFY%eRRNN{llvJ|-=ljwG$fH>PrApxfptLOUmTg;VR z?!$QJ=H`Bpk$1dvL@wI;yH;s9P@?VS*QEVS%j4mog%2Yj-MZG#oUOP{jVvPPx^ULB z=JfF)J0jxSVI}SY4$W(q_2u2=CyUVBVkG8gc{wy zT=$?A-YFXILsedG=9%jQw#V0tc_oD|=}zLn&+&IXXpV`~@1g@oy7X0^7VCG}hddWp z8jkjT@WUE>#j% z_Eee;;nKNZ-)w1P<2p(3OJ|1FPZx4j2gRr)f7jpIBpXOB&MoG>>_pvLUJlF4GkSr8 zmBgvfWIWu0O)ZOWL7fjuk{Ac;k|bZa(4GPrF|mi8?B51`C>k2(syol2Z z3jUZXn$aJ(Bblh6`7K9B85F1+VZKVsow|u@J-w`YiCp%YQDACNnhO1QNBdXv>0_PV z-}EnDj2Qn^eDBI(fmd8L>GkAUebf{g)M4d#8@U6ZPepPzV`Q@QvG343M(q!vQD^Mntv$nuv+|sioeNal~miz z>nD=$dd*;Qu?v2XZB9X!^4}(&k!|ok3Jy@w)+SDf!FJvEJUdJ z%jq|wHy4C?(AFy1&{$bm0FR0~gZL6lv*FtK_WXEUaiaG=S;2niS5e}^I4=FMlJR3e zE7X!98h(Cvu~#T%=jaHMeMuaN;qmWFmfX6nHASObuV?NqSsOhMrqj<+`Q@W&_hRE3 z&~o+z)PsMpprSNP6;-}O)_aZ5-s}-yXS;E?)>TPMQ}QFa{Xn6zh4$Gqu_cc#1|~eO zv#i`=D}YJ`MMQ*W$vl;n$eJ7=XM&`N*y|?q`w&{4ZHLV)OYE0~N+X%g%L60~3}#!~ z@h2itkQjfMDw_H3|5B@2YiJ}wMN<=aUF|6zc)@v71=Hnab*Ypii!6n#ii_{~jweb%8(x4-Oke|j}o zV{}6Ik`4p2i4PU%%j^C|m{aoI9_qPV=n+8vwJo$p9V(sCLzLA$N!Px4Av)^ODKoj~drx#PigNbb#6+>fV z03_j3pPqfW)ZAQ|l0r&Xv_8uk?)PG3vw+9VTi}h`A;D~0Nuygn(I=XEm-5UMh*w`2 z9(xwfJ4u1|4L%#+mAKL4-Q^0t^V7YZx>(O0CV8)(zMO7Z@7)yuQ5Cmve-JQ7U3V(+in$jYTfk77$p~%&^@!&Q=7l*7H_;2Co15itzfyXriw!GRm8_y$xHXYumB4M ziL7$aD^O)Mf6EiLuo!B(8ys#+FV+_h{83Xgiq9@`f1z@kCj8Vn#IMP_&tVbQl_va0 zG}Fv1-$K`>Z;1ZssF@Krw8kS3hvTjVCiXLn{SZ;GHw0NHah4x;1cS|#H-Y!4NeAZd zSgz;&m-)p*7JZTCz~@kksqwYt+~rE^GiggpGr5RSS5a}3?rw@E_Zd8_9PT%NzK||f?@pz{aUZl#wpPWr44|TE zeXL+BzooQ&7AihAGC5ObtZ;q0gL|m)2ZM<)RD!3+S#3d<*=F2GH=P{D8%)k0Gkt9L zwL7Z|5_2);!gp^+$!-@7f)r2JRDy>azJ6}G-fwkcCt7GocIS1UR~+A*KX?I^xQvJ> za#`&Z5Hl|tyl<4GD$XsbE_+A85TtfHPhPgv7%7pN<>`5iL^%iasuKer!ZhgUKYBe{ z$_{ffm)m7!mA(^MC*mYM_~B+e*b582m^V+1&ZPv^Q+nC2$mC-8aOn2o4$eEL5_|5O zm(Dv`&grnCorcM@w8>Th1#RtpN{Lk21jByF8ysV{uOb{n&zr<~mREnLD%kcyS^0`w zrfA1wGnj-ax8itT)xWg#0ZU1E8?`Q3QDy-09{7#~$zI5o?z8)cRaW|kz0_icNU(#n ztd=}$y`IWNM5^K7_OvLpKhSO3GCLhMaDMGpeU~0wRdvSJvz%hmUVl_+5Bl3!N`6g3dM*t1CVlnZ}`G z{LL>?uJghs^D%aR;PPz!PJtO2?C7{-HboWE4w?pacY}{{OZGrudULnHE$O!5bhsR! zd-%coIFvF*oZ0Kp-+Ou;7ck_%N%NZl`b{n zdoFv+S5nB@pQL^7QrI2HX+nlbHfydU(ZBHZ!*|4oJPh6{kqfWb- z8393MVL{t!&cB+VRtOg2Vq4h7+xwyp2Wjb4vW4t^y|Y}%bNnt}=&$qw1p?Fht1%O4 zw)@!JTeVqrrZQ%5syf3{0eSAs4pXgp$dWN$rGid0M&H~-e#Drfta4ygMuQlPH^~z? zphX1rO|ICKq(?kiWY6umzd&lp8!iMh%za{bh@MGdxU07=ueVOziJYA#FciFq&xQlZ zm&pgdkW7o#0*xk>aT0i_v7etOCeVn6cZ%wXU%Nvst@;=!`ufoJ8*+7L9`q?)I~QC#i-`s}STlI)uO@JIjEr<@Y0>HG zCd|)YBVn?*!5<^X#UF*dY3u1>Jh?o48eq50tze_vnYq7N8lQk+j3mj?h0v=i<^iDI zJvR1%sqE8-4{k?Vj*e_NBLbNte`s(0+Z}Y%Z1PVv~)W zZ=!Ou$B3uDLBq>%RLn}RtNX;NG&YRBAoaR(C<$9cm{U65kkR(5i@Et}tDgXy+i{)4 zwz{0#U1CcM2=KX~Pt4X1g`Vfzi|s)?PDQitf95#B!fpJAv9s4)_{MD1TbH$b;>uSl z1o35#F&>Oq7nRRy!9HL5W94|T%Ff0$@aJvJ=O4uyLBzbCtLdW3z}089HjE)^4N zC6n>ELYMVUPF)7QXgU#Pw}Hu@iV8M8oYgX&F zK3)zMpD_hf|5zZzA$g`4~0x`%V?8z_bj@|frG@tVzdmghZ@5J^lQv1Fo}&6c#PWQd?M z2gIOSV1r8s@hJ%ifCBpESk{f@!fd=H<7pVtv-t!L8+>I{4Bfyv27lzp&#F}@cXQ)I z^xM5rNfH@$kGB$JSXD7GxSDnEF@riaYxt%PswfH$K)t>-bd}7554l%c)E{nKxX!Un zxtvuD48SZe_`ntV`At_w{}6KO43VP>LXL#I$CEvO9Xn$Z^OPaIM1YPQ_KKXGhG9sS zua;l{Q-q~i_jUa+?00SsszW0@dJ|)9RMc2`8H%O`)bbEOtOo?3s!jL71vKY{fOj*l zqjg;W%&(s=uM3g5oaoWo*%d40|Mtx1Ticr&uv(m!N(!+L7QIk{y!~V7?OqZhf3y*} zh!e&0#YjpDV>xqNYC50DU)rC4bKKSS+OG1U1lC0~4DvR+f?j=WoXIxz89DH`ys7&2 zD-RJZq4`k_Z2yAl`1P0@wl|T*%{V19sZNI}z)wmCUao*u4n z`=WWCqd6t8Nl~G%6Z6u=eC`wx)$PfmlkoRoqz0@L^h}hyRc-FUWXqv+D#F z`V|JHBK`I<)?p{Xm9mKU-xPuP+=?u7q=yFoprfay7q$(5O)19u-sAdIRaEOK(BgcK zf$1OE^4?S~VLM}Qx6b3~;X0nZjhTsTzUklBF3#Hg`^~CP@+uRr^ZYY;-j7V6sdrZ7!Vmd|QBzIHAop`X}Xa_iJmK z=d-r`K#%MF;%|}1W5UB>Vrwas!u9s8!$$9vdi5j-N*>SqKjlW)mdqcAnx3?V$Jd*k z=-axVTkyM$4UfL6tm=G*$eYMh529&2cm-`86!_Qd5`@&$XBh9)Uc7jw8C*VYD&qri z*P8R-gc6#yOlDVy(N{-^g=!n+Ht#N@CjKx&vhEwmY*qB@*0O)fYw8VW z`+DV7iu%7)7j3T!6PoR%^u?Ss34rApVlbYdqEQdHs&hbYllzvHwMwmGe{kTzX4Prc zMXDJ12c94G9fH-g_hX7Ih4D^oYhM1R2)k`r5RHS{UZ5c81z@NQl>s617$(D&Q4)l!w`HJ`>Gz#&r|&LeR+%U%p~AeT>yTW$5WC&g1YAPNk@wg;{4u9#vEGen23DxO41!S7~!F5uvC^%WRUuVmRI-5Bv3n z1Pd)K^Ic(k}`X{*!SCBQz~#zqS|L#e|Cf91LieRzIeCmgYG$!)m)(dWCgkwKgywEKEF%C@3%B%jS zi90U@h|G5;n+;ZX%Lmdq)1JFb0w(iQIY`Hp$-p-DGfivt%4v;+6YY}Y*SocIa!C<( z-G7KHPKO*zaKyWllkUq%a+D+h$Sgr-5wa)P<>LYjrS31pJ1}3Un z&&0&ULJNZrt+d(1L4Acf80b2@2ED8@LqL&~3>-S^Vc&<0jEwd;xh~nXks!;n&5ipL zQC-E~LL?3ndZefm_<}JU;%Mum! zs^5z>D`0%Du~7IjVZAlT#)c;+E2~A}PDvv9uXdPYh2*gaH4}dh%V~zbVywWyf%UE_ zL^TML&F6UrBmw_OAqP_*a+x1~QQ;>x1cSk%J z4MhiaxO9c>%+4am$78eTuO1LaB-5{)04>GR{wy{=Iv^gA8$km}ZgNEExRG|OT?k+; z>Z(B&ChiyFbWv)E&qi2Sqk6@<-v^q!hFC&Fj^7DZJ@uu5v{Y0~h+pwDn+j2AuUHhKkI1-tg2Vp2NdFBs=f~@Jm({V!$shn2A0MTPwXl=81880N-6IldF@pdj z17c15{&LQLd^|!lY#G0#E;~_p)w1e3w1z`5LV{Z1|jl|?U|uf zaShn5)O;v4dB6ftSIe4_o&KmAwgQY>D3t#y8IyZbhl z{cv^If%fq~k>w)*14*m*0ZTyVOF}?gXGNn(b&hKG70);0eI#&+#)6hlxdsnE>KmFP zLu20x<2j^^^aeXWHI{Gp5r3kRrDJAi)Hi05M3DkrjlNQRPBBYFjS`3u-+*+iOc0?# z#|J2-*rEgu#@jc_L(7K9)VIpMD%D;~DvNCFo54u8Nd;qdbk91(x5tGJfZp*m_cY8Q z0Lv~uJi0BE8(q`#r8dmeo^9M-Kstc$$HTp1_(*{NdpD>kG<5BJ$IobRoX0Dy4&iM) zs%>pip@kJM3?v2TThiXX#d|Mnd!W`6MXe|$1)w0*h528&^ppFZG+CuK*^yZ2EvFZu z#JrCkWd@PSpOmI`7fbbH=c?!Y{3t(G{9JmsX`5^BDr8xt_&#lKTc?`X6g+c;@Ql^) zE5J%)o!yuT2!Ik%g&ar|A~>?MFB#TtZ|=sj!JD3nn-8T-Af5F?OH6`(7DktHyRCXS zM1S*{Z%wFm_LLXd$$(}VUXPLb95}Q&P%Rp!Sc8lwNrpV5dviVQ@2`c=@GldpFJY*t zB6#+TT1eak59k<$K@9-s9o9>oIr%=&_+&rqg>==}}(>?%5ur`virKokkG zq?pgn-Wj*qYid#^hj-LLP}}gZ`S$SccX$wDn>DhA*mz{5C2WE(pd75-oVUbFiviBp z#=|U&F^+XMvy!yXvHd0A;~Tx{lvFT(o9GWhcE@y0;UJloE8B}Yr*k?@-=fsiznI4m z^a5{ea&)tz5{Si1Mj|_}LnlW@VIZR9fQN+7`1^cNiOGt8)DoTOj-3l^6Pc!hZs>8DnMHizOIu$0?uxYz`N|a1w zF)FK0P0g@Zhq3uyB32Qz^n8$w#=r<~N?*$eKm*0gy+4A5ghXADWp8g3l!6Wu+C|3k zr$=w%19{*3SND9vCsEWrypP5huV1@gyNY zUlV)TD=IOfpaSSv)x5xTz*zmumr%lg^0~2i_U+hEgkx}v&S)atE6ZMfMZZVqqns7v z;W1F(Vf{*#fQOBh%^|hVVh8m9)u+3VqI~Y1k@TbqvT@{lq_>uB9!y9TIfX`t&M3%H zv-G5Chco4~?LvV0KgK-AFnL{$=nnVH4T2@(e^>RN6*zF|4{~)Xy3?uU6o`>EI@ zp&~QaFuStIQZNSxkJJf-0N74|p3yJml&S&?NBrgCmNulO^+Fb zQm^>KHI;E|a7N}ZS_He!|0|So+k*+Uu!9`%QXzXXJ7fH#i{9pz=&(OP#^FOl`wxXh zhg~R9GXJy64ybNIDcR`(3HXwR9-1DG)avhXfL?S!svoB1b920kMUK&Pi12>!GlB%O z1e9Y{gb2|ZZnc{U+VMasB+O6=OXX@s2NA5a|dv8Omw_0O=1<*i0~z*#uV@x{C@Uryz=3ri|B6G z>&MQoaXQ*zUn+5TKj!axoz>LDmkH+BGW%q9CXBbqR2}EJ&GHZIX?;Grn0!rWI{p$O zX};o!N=o^ep5!A6*14*%-1AMTZDdc<8e$KlE&qy&%U`c(U>d&-?mqFttcNwwcLBy{O%oH<@5l|2L&z&nGGf zTH8VqQCh5W1H+Gi2r`~Utgl}({f>c_o4xuiYt+WxoO%x{whI4LXD6s%kC)O|1-T|C z9WlxEYL7}EboS6UY+c+`-)L$l&v*!v6Zv_*hB5?Je2r*QD$w&07ftp8%oaxOaHb1^0D$)G;t%ImR zW@$Eg6-MFmUoPVP>PC}4fi1I=7Wj61dAFuMp942MqIxrEEodbX6e5d&&;RlPCZ(xX z9o@rD0u$2dx#dZihaoBEAnubyfGBKuZ;>A&R1#uT60D47YUgXB=9J}BO#U*lvoVlP z`{(vpm)X$dQdt;VwnQgxx_3W=3hDsHkMAeYLw)EN^H#TnO$eS$E_n5~wdmD7BNzj_ zJ4dJ`K)c%}>Nn)AqH<+=W{4LVL`$>9&L&$`NgoPN;fAr6O$*a<_;#c3rRX9>&=kweXQrlEgGe985yEu+4yy}QtromCZa=M zOKITX=6(d5)oqFZR>#JkMM|RY6HP&RXelF?>b?qK@KQ5fUJF$OEVHvkcXgVotIdA* zr*il6x5HxFB;tZ!ct?fBq5#ksfJ~2g!%U-lNa&^th;|MR6uR7E#L8F({?@e>%&%B_g6}kQSdl;@+w;UkGfd1v0H%0pgr6SkspW51101<0YB7Ge zwYA@}|3pT`#CQ#f+=jq=UmKlFM`ynYVyf+*s~kH6syT2Fd=GsOeeUhGa^%lTc&K54 zYYv5wLs4Dg&O}6yy4vn1eKE(Api2Z`M59!O;$yW8o&xj@~au^=+*Ad-Q)3 z$r%_fh0yQL(|_qFwZlTa?*9yX{)?826R51kcHB#2&ajIBMnS3De4Y$+?~yseHdwTV z*Vce9?~_Zn2MhK8sJSyuRKMs1??Wj7r(WAiJ|L4CttvC6rtIN$4AIs;YWCvAVUj1p zk1y5r9mCZI>g-_$`{{pL?u4H~LZ9N<*S260tmXlPr)*S~wll_R|L;{!uX_yJJsdW~ z-{=^r29}l|tx5a@asz{@n?2O0{=!JOp+coFFhDdt35a`X=~q4}bey#S>qwC;(SYPr zk3GNq`8_mMRVBUG+Y!!y_PnJ`?e706t@l4CY;6NFRZw4hR9lQyRTPMcyO!$*6#2qc z7Zk|M3SuSkP-6z)d7ViOwFg;bW>(+d?~_ThTwF|)RvygDnC4}ru8_=|rUSJ;TcfAN zC-<7HRNb|{m?N2_3}fSv+dC_BnztSUahnA+0ms%JMn-tPe|vgdylyLg4-uERb1Gv` zQSZ`2l@++)8iFx{jN`OYy)Nkczq-38}cTA*%clc z!O+ylHkJAo=#Rldb~dp&fJFsXT=kfQghsFCqD0MP95}MU*fC`d^VNgIUH>3y19_LM=gcZr#q1 z)OsgS(c>oY%>9hpn-vQ~8d};{;Ro-LA3$PrO5Ks%5Pt(!#_b)ZC?@nZ+_$z>Rcmtm0 zcG;5ePiHE`bTLBy8}Eivac{0@9_Fq40yQ$F6 zHJ;X+*n#9{ten}BCya5FJ&q~M4p~W5!fkN8`&~?U(fviX6`<<=9$nwf{!^51=ZB}} zd^+@fXuKa=%(CEVuxJhZnby0yHYJU>`^J;U#4vgG|IhPMFwh$KEV$~aW~Z3;#XFqW zyKl5Y>f24$`cad8H;s^xL6RhlI{?T@P<^)?u^*0oxbS~;&~I-f6~@5)Kx;8@fQ7P3Pk`b@>;8J}E|R=dNKY9^L`8Ri1RcQ9 z_R4(OvgYK{1P5Xwwl<@M4I*`?rPss2q@n8Tq_>vuV?r%K-cG8)NUe( zc)gOjaJjZg=yl}!^K_fP_Z?JHUICs_1~#!zl_OIlPaX$8|12vtp2!v_#4P50t5VmA zD7J5|`$jFA6Bn!R){7y&^pU1p8rZ&b5g~^CB)Dh}Bc;>!Zs` z5MqT!e%>bKaO&SfMyP3}gbpSOApIREv#3*i253wr&eH8gp+%Ulr{o zWeu7baa0WrS3_@jC{__H*IN^ly+Wjf>guZovp|9wBr972ly_?5iAld%j+uI-G+omBv009EwJe=~BZfXht?D2gL zFvoGPD5<>QB&aJY0>W=`!B#(lm(^(k!}F3;BaEl#il5bjvkNPJt1D;iEe|u_&_dnq zt3Yc9%mSw;a)h$Qt?wbe>Cx7~!O7tfT~wlb;^<|?1&N$SMhu`eO$2Ub6UNK)_hn>j zPk0k5J|tj;res#2iz#<^$1)sBrGGf~LUoi5ODUBb8o>yLKM<4Phbhhy8EfGi8j;J* zo>P`@rKQgvHU?mRZ}N+F^BTabSLOtYXU99cTwGG+sI^hSC%NUS^E850J1g3dhmgmp z-t&v<`;V`JGIGiS`}P>v85MFyZcf^{XT_-`cJS~99S2dQHg0Zq<91E)OwS!qZ)dnJ zCcR#nC}^mTjsmT+;f%U>^A}P&nkN#RV8TMe;jjJ)|NmX Date: Wed, 25 Sep 2024 08:00:54 -0700 Subject: [PATCH 356/454] BIP85: Update/clarify spec, add change log, Portuguese language code, dice application (#1600) * BIP-85: * Add new maintainer (author unreachable) * Swap chain code and private key bytes in application 32' for consistentcy with BIP-32 (major change) * Correct derived entropy for application 128169' test vector (major change) * Clarify big endian serialization * Add the Portuguese language (9') to application 39' * Add dice application 89101' * Clarify Testnet support for XPRV application 32' * Minor grammar, format, clarity improvements --- README.mediawiki | 2 +- bip-0085.mediawiki | 100 ++++++++++++++++++++++++++++++++++++++------- 2 files changed, 87 insertions(+), 15 deletions(-) diff --git a/README.mediawiki b/README.mediawiki index 170b05314c..d92cb78669 100644 --- a/README.mediawiki +++ b/README.mediawiki @@ -452,7 +452,7 @@ Those proposing changes should consider that ultimately consent may rest with th | [[bip-0085.mediawiki|85]] | Applications | Deterministic Entropy From BIP32 Keychains -| Ethan Kosakovsky +| Ethan Kosakovsky, Aneesh Karve | Informational | Draft |- style="background-color: #cfffcf" diff --git a/bip-0085.mediawiki b/bip-0085.mediawiki index 633210c6c6..9534cc921b 100644 --- a/bip-0085.mediawiki +++ b/bip-0085.mediawiki @@ -3,6 +3,7 @@ Layer: Applications Title: Deterministic Entropy From BIP32 Keychains Author: Ethan Kosakovsky + Aneesh Karve Comments-Summary: No comments yet. Comments-URI: https://github.com/bitcoin/bips/wiki/Comments:BIP-0085 Status: Draft @@ -14,10 +15,10 @@ ==Abstract== -''"One Seed to rule them all,'' -''One Key to find them,'' -''One Path to bring them all,'' -''And in cryptography bind them."'' +''One Seed to rule them all,''
+''One Key to find them,''
+''One Path to bring them all,''
+''And in cryptography bind them.'' It is not possible to maintain one single (mnemonic) seed backup for all keychains used across various wallets because there are a variety of incompatible standards. Sharing of seeds across multiple wallets is not desirable for security reasons. Physical storage of multiple seeds is difficult depending on the security and redundancy required. @@ -33,6 +34,9 @@ The terminology related to keychains used in the wild varies widely, for example # '''BIP39 mnemonic''' is the mnemonic phrase that is calculated from the entropy used before hashing of the mnemonic in BIP39. # '''BIP39 seed''' is the result of hashing the BIP39 mnemonic seed. +When in doubt, assume '''big endian''' byte serialization, such that the leftmost +byte is the most significant. + ==Motivation== Most wallets implement BIP32 which defines how a BIP32 root key can be used to derive keychains. As a consequence, a backup of just the BIP32 root key is sufficient to include all keys derived from it. BIP32 does not have a human friendly serialization of the BIP32 root key (or BIP32 extended keys in general) which makes paper backups or manually restoring the key more error-prone. BIP39 was designed to solve this problem but rather than serialize the BIP32 root key, it takes some entropy, encoded to a "seed mnemonic", which is then hashed to derive the BIP39 seed which can be turned into the BIP32 root key. Saving the BIP39 mnemonic is enough to reconstruct the entire BIP32 keychain, but a BIP32 root key cannot be reversed back to the BIP39 mnemonic. @@ -51,6 +55,9 @@ For each application that requires its own wallet, a unique private key is deriv The HMAC-SHA512 function is specified in [http://tools.ietf.org/html/rfc4231 RFC 4231]. +Application codes may be arbitrary but should be semantic, such as a BIP number, +ASCII character code sequence, or similar. + ===Test vectors=== ====Test case 1==== @@ -78,7 +85,7 @@ BIP85-DRNG-SHAKE256 is a deterministic random number generator for cryptographic RSA key generation is an example of a function that requires orders of magnitude more than 64 bytes of random input. Further, it is not possible to precalculate the amount of random input required until the function has completed. drng_reader = BIP85DRNG.new(bip85_entropy) - rsa_key = RSA.generate_key(4096, drng_reader.read()) + rsa_key = RSA.generate_key(4096, drng_reader.read) ===Test Vectors=== INPUT: @@ -93,14 +100,15 @@ OUTPUT ==Reference Implementation== -* Python library implementation: [https://github.com/ethankosakovsky/bip85] -* JavaScript library implementation: [https://github.com/hoganri/bip85-js] +* 2.0 Python library implementation: [https://github.com/akarve/bipsea] +* 1.0 Python library implementation: [https://github.com/ethankosakovsky/bip85] +* 1.0 JavaScript library implementation: [https://github.com/hoganri/bip85-js] ==Applications== The Application number defines how entropy will be used post processing. Some basic examples follow: -Derivation path uses the format m/83696968'/{app_no}'/{index}' where ''{app_no}'' is the path for the application, and ''{index}'' is the index. +Derivation path uses the format m/83696968'/{app}'/{index}' where ''{app}'' is the '''path''' for the application, and ''{index}'' is the index. ===BIP39=== Application number: 39' @@ -143,6 +151,10 @@ Language Table |- | Czech | 8' +|- +| Portuguese +| 9' +|- |} Words Table @@ -207,7 +219,12 @@ OUTPUT: ===HD-Seed WIF=== Application number: 2' -Uses 256 bits[1] of entropy as the secret exponent to derive a private key and encode as a compressed WIF which will be used as the hdseed for Bitcoin Core wallets. +Uses the most significant 32 bytes +There is a very small chance that you'll make an invalid +key that is zero or bigger than the order of the curve. If this occurs, software +should hard fail (forcing users to iterate to the next index). +of entropy as the secret exponent to derive a private key and encode as a compressed +WIF which will be used as the hdseed for Bitcoin Core wallets. Path format is m/83696968'/2'/{index}' @@ -222,17 +239,26 @@ OUTPUT ===XPRV=== Application number: 32' -Taking 64 bytes of the HMAC digest, the first 32 bytes are the chain code, and second 32 bytes[1] are the private key for BIP32 XPRV value. Child number, depth, and parent fingerprint are forced to zero. +Consistent with BIP32, use the first (leftmost) 32 bytes of the derived entropy as the +private key. Prepend an empty byte (0x00) +per BIP32 on master key serialization. Use the last (rightmost) 32 bytes as the chain code. + +Child number, depth, and parent fingerprint are forced to zero, as with any root +private key. + Path format is m/83696968'/32'/{index}' + +Applications may support Testnet by emitting TPRV keys if and only if the input root key is a Testnet key. + INPUT: * MASTER BIP32 ROOT KEY: xprv9s21ZrQH143K2LBWUUQRFXhucrQqBpKdRRxNVq2zBqsx8HVqFk2uYo8kmbaLLHRdqtQpUm98uKfu3vca1LqdGhUtyoFnCNkfmXRyPXLjbKb * PATH: m/83696968'/32'/0' OUTPUT * DERIVED ENTROPY=ead0b33988a616cf6a497f1c169d9e92562604e38305ccd3fc96f2252c177682 -* DERIVED XPRV=xprv9s21ZrQH143K2srSbCSg4m4kLvPMzcWydgmKEnMmoZUurYuBuYG46c6P71UGXMzmriLzCCBvKQWBUv3vPB3m1SATMhp3uEjXHJ42jFg7myX +* DERIVED XPRV=xprv9s21ZrQH143K4Px85utdpu6DFvY2NpHkJajPoupAznfiacH2MC9LasyW4uvqKXNxLWcjqGTbHKAhoZoMAbmRe5g9tAPA7cUUX4UVA1vFKFm ===HEX=== Application number: 128169' @@ -285,7 +311,7 @@ INPUT: * PATH: m/83696968'/707764'/21'/0' OUTPUT -* DERIVED ENTROPY=d7ad61d4a76575c5bad773feeb40299490b224e8e5df6c8ad8fe3d0a6eed7b85ead9fef7bcca8160f0ee48dc6e92b311fc71f2146623cc6952c03ce82c7b63fe +* DERIVED ENTROPY=74a2e87a9ba0cdd549bdd2f9ea880d554c6c355b08ed25088cfa88f3f1c4f74632b652fd4a8f5fda43074c6f6964a3753b08bb5210c8f5e75c07a4c2a20bf6e9 * DERIVED PWD=dKLoepugzdVJvdL56ogNV ===PWD BASE85=== @@ -295,7 +321,7 @@ The derivation path format is: m/83696968'/707785'/{pwd_len}'/{index}'m/83696968'/89101'/{sides}'/{rolls}'/{index}' + + 2 <= sides <= 2^32 - 1 + 1 <= rolls <= 2^32 - 1 + +Use this application to generate PIN numbers or any other numeric secret. +Roll values are zero-indexed, such that an N-sided die produces values in the range +[0, N-1], inclusive. Applications should separate printed rolls by a comma or similar. + +Create a BIP85 DRNG whose seed is the derived entropy. + +Calculate the following integers: + + bits_per_roll = ceil(log_2(sides)) + bytes_per_roll = ceil(bits_per_roll / 8) + +Read bytes_per_roll bytes from the DRNG. +Trim any bits in excess of bits_per_roll (retain the most +significant bits). The resulting integer represents a single roll or trial. +If the trial is greater than or equal to the number of sides, skip it and +move on to the next one. Repeat as needed until all rolls are complete. + +INPUT: +* MASTER BIP32 ROOT KEY: xprv9s21ZrQH143K2LBWUUQRFXhucrQqBpKdRRxNVq2zBqsx8HVqFk2uYo8kmbaLLHRdqtQpUm98uKfu3vca1LqdGhUtyoFnCNkfmXRyPXLjbKb +* PATH: m/83696968'/89101'/6'/10'/0' + +OUTPUT +* DERIVED ENTROPY=5e41f8f5d5d9ac09a20b8a5797a3172b28c806aead00d27e36609e2dd116a59176a738804236586f668da8a51b90c708a4226d7f92259c69f64c51124b6f6cd2 +* DERIVED ROLLS=1,0,0,2,0,1,5,5,2,4 + ===RSA=== Application number: 828365' @@ -374,9 +434,21 @@ Many thanks to Peter Gray and Christopher Allen for their input, and to Peter fo BIP32, BIP39 +==Change Log== + +* 1.0 (2020-07) +* 2.0.0 (2024-09-22) + * Swap chain code and private key bytes in application 32' for consistentcy with BIP-32 (major change) + * Correct derived entropy for application 128169' test vector (major change) + * Clarify big endian serialization + * Add the Portuguese language (9') to application 39' + * Add dice application 89101' + * Clarify Testnet support for XPRV application 32' + * Minor grammar, format, clarity improvements + ==Footnotes== -[1] There is a very small chance that you'll make an invalid key that is zero or bigger than the order of the curve. If this occurs, software should hard fail (forcing users to iterate to the next index). + From BIP32: In case parse256(IL) is 0 or ≥ n, the resulting key is invalid, and one should proceed with the next value for i. (Note: this has probability lower than 1 in 2127.) From e1aab46c6359fcabd77b8d3c2bddfc8045bd5cca Mon Sep 17 00:00:00 2001 From: Matt Corallo Date: Wed, 2 Oct 2024 16:46:57 +0000 Subject: [PATCH 357/454] Explicitly mention care around payment instruction expiry in 353 If someone puts a lightning BOLT 12 offer in a BIP 353 entry with the offer expiring before the DNS entry's TTL (plus now), they may get stuck being unpayable, so its worth explicitly mentioning that people should take care here. --- bip-0353.mediawiki | 2 ++ 1 file changed, 2 insertions(+) diff --git a/bip-0353.mediawiki b/bip-0353.mediawiki index 9c48f91140..ef4b6c0abc 100644 --- a/bip-0353.mediawiki +++ b/bip-0353.mediawiki @@ -46,6 +46,8 @@ User and domain names which are not expressible using standard printable ASCII M Note that because resolvers are not required to support resolving non-ASCII identifiers, wallets SHOULD avoid using non-ASCII identifiers. +For payment instructions that have a built-in expiry time (e.g. Lightning BOLT 12 offers), care must be taken to ensure that the DNS records expire prior to the expiry of the payment instructions. Otherwise, senders may have payment instructions cached locally which have expired, preventing payment. + === Resolution === Clients resolving Bitcoin payment instructions MUST ignore any TXT records at the same label which do not begin with (ignoring case) "bitcoin:". Resolvers encountering multiple "bitcoin:"-matching TXT records at the same label MUST treat the records as invalid and refuse to use any payment instructions therein. From 3f4a0a17bcadaf1cd5e00d6065417979a4d2ff1d Mon Sep 17 00:00:00 2001 From: Jon Atack Date: Fri, 4 Oct 2024 16:18:52 -0700 Subject: [PATCH 358/454] =?UTF-8?q?Revert=20"BIP85:=20Update/clarify=20spe?= =?UTF-8?q?c,=20add=20change=20log,=20Portuguese=20language=20code,?= =?UTF-8?q?=E2=80=A6"?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit This reverts commit a1be309f91f70b855626c823af317d9b1163309e. --- README.mediawiki | 2 +- bip-0085.mediawiki | 100 +++++++-------------------------------------- 2 files changed, 15 insertions(+), 87 deletions(-) diff --git a/README.mediawiki b/README.mediawiki index d92cb78669..170b05314c 100644 --- a/README.mediawiki +++ b/README.mediawiki @@ -452,7 +452,7 @@ Those proposing changes should consider that ultimately consent may rest with th | [[bip-0085.mediawiki|85]] | Applications | Deterministic Entropy From BIP32 Keychains -| Ethan Kosakovsky, Aneesh Karve +| Ethan Kosakovsky | Informational | Draft |- style="background-color: #cfffcf" diff --git a/bip-0085.mediawiki b/bip-0085.mediawiki index 9534cc921b..633210c6c6 100644 --- a/bip-0085.mediawiki +++ b/bip-0085.mediawiki @@ -3,7 +3,6 @@ Layer: Applications Title: Deterministic Entropy From BIP32 Keychains Author: Ethan Kosakovsky - Aneesh Karve Comments-Summary: No comments yet. Comments-URI: https://github.com/bitcoin/bips/wiki/Comments:BIP-0085 Status: Draft @@ -15,10 +14,10 @@ ==Abstract== -''One Seed to rule them all,''
-''One Key to find them,''
-''One Path to bring them all,''
-''And in cryptography bind them.'' +''"One Seed to rule them all,'' +''One Key to find them,'' +''One Path to bring them all,'' +''And in cryptography bind them."'' It is not possible to maintain one single (mnemonic) seed backup for all keychains used across various wallets because there are a variety of incompatible standards. Sharing of seeds across multiple wallets is not desirable for security reasons. Physical storage of multiple seeds is difficult depending on the security and redundancy required. @@ -34,9 +33,6 @@ The terminology related to keychains used in the wild varies widely, for example # '''BIP39 mnemonic''' is the mnemonic phrase that is calculated from the entropy used before hashing of the mnemonic in BIP39. # '''BIP39 seed''' is the result of hashing the BIP39 mnemonic seed. -When in doubt, assume '''big endian''' byte serialization, such that the leftmost -byte is the most significant. - ==Motivation== Most wallets implement BIP32 which defines how a BIP32 root key can be used to derive keychains. As a consequence, a backup of just the BIP32 root key is sufficient to include all keys derived from it. BIP32 does not have a human friendly serialization of the BIP32 root key (or BIP32 extended keys in general) which makes paper backups or manually restoring the key more error-prone. BIP39 was designed to solve this problem but rather than serialize the BIP32 root key, it takes some entropy, encoded to a "seed mnemonic", which is then hashed to derive the BIP39 seed which can be turned into the BIP32 root key. Saving the BIP39 mnemonic is enough to reconstruct the entire BIP32 keychain, but a BIP32 root key cannot be reversed back to the BIP39 mnemonic. @@ -55,9 +51,6 @@ For each application that requires its own wallet, a unique private key is deriv The HMAC-SHA512 function is specified in [http://tools.ietf.org/html/rfc4231 RFC 4231]. -Application codes may be arbitrary but should be semantic, such as a BIP number, -ASCII character code sequence, or similar. - ===Test vectors=== ====Test case 1==== @@ -85,7 +78,7 @@ BIP85-DRNG-SHAKE256 is a deterministic random number generator for cryptographic RSA key generation is an example of a function that requires orders of magnitude more than 64 bytes of random input. Further, it is not possible to precalculate the amount of random input required until the function has completed. drng_reader = BIP85DRNG.new(bip85_entropy) - rsa_key = RSA.generate_key(4096, drng_reader.read) + rsa_key = RSA.generate_key(4096, drng_reader.read()) ===Test Vectors=== INPUT: @@ -100,15 +93,14 @@ OUTPUT ==Reference Implementation== -* 2.0 Python library implementation: [https://github.com/akarve/bipsea] -* 1.0 Python library implementation: [https://github.com/ethankosakovsky/bip85] -* 1.0 JavaScript library implementation: [https://github.com/hoganri/bip85-js] +* Python library implementation: [https://github.com/ethankosakovsky/bip85] +* JavaScript library implementation: [https://github.com/hoganri/bip85-js] ==Applications== The Application number defines how entropy will be used post processing. Some basic examples follow: -Derivation path uses the format m/83696968'/{app}'/{index}' where ''{app}'' is the '''path''' for the application, and ''{index}'' is the index. +Derivation path uses the format m/83696968'/{app_no}'/{index}' where ''{app_no}'' is the path for the application, and ''{index}'' is the index. ===BIP39=== Application number: 39' @@ -151,10 +143,6 @@ Language Table |- | Czech | 8' -|- -| Portuguese -| 9' -|- |} Words Table @@ -219,12 +207,7 @@ OUTPUT: ===HD-Seed WIF=== Application number: 2' -Uses the most significant 32 bytes -There is a very small chance that you'll make an invalid -key that is zero or bigger than the order of the curve. If this occurs, software -should hard fail (forcing users to iterate to the next index). -of entropy as the secret exponent to derive a private key and encode as a compressed -WIF which will be used as the hdseed for Bitcoin Core wallets. +Uses 256 bits[1] of entropy as the secret exponent to derive a private key and encode as a compressed WIF which will be used as the hdseed for Bitcoin Core wallets. Path format is m/83696968'/2'/{index}' @@ -239,26 +222,17 @@ OUTPUT ===XPRV=== Application number: 32' -Consistent with BIP32, use the first (leftmost) 32 bytes of the derived entropy as the -private key. Prepend an empty byte (0x00) -per BIP32 on master key serialization. Use the last (rightmost) 32 bytes as the chain code. - -Child number, depth, and parent fingerprint are forced to zero, as with any root -private key. - +Taking 64 bytes of the HMAC digest, the first 32 bytes are the chain code, and second 32 bytes[1] are the private key for BIP32 XPRV value. Child number, depth, and parent fingerprint are forced to zero. Path format is m/83696968'/32'/{index}' - -Applications may support Testnet by emitting TPRV keys if and only if the input root key is a Testnet key. - INPUT: * MASTER BIP32 ROOT KEY: xprv9s21ZrQH143K2LBWUUQRFXhucrQqBpKdRRxNVq2zBqsx8HVqFk2uYo8kmbaLLHRdqtQpUm98uKfu3vca1LqdGhUtyoFnCNkfmXRyPXLjbKb * PATH: m/83696968'/32'/0' OUTPUT * DERIVED ENTROPY=ead0b33988a616cf6a497f1c169d9e92562604e38305ccd3fc96f2252c177682 -* DERIVED XPRV=xprv9s21ZrQH143K4Px85utdpu6DFvY2NpHkJajPoupAznfiacH2MC9LasyW4uvqKXNxLWcjqGTbHKAhoZoMAbmRe5g9tAPA7cUUX4UVA1vFKFm +* DERIVED XPRV=xprv9s21ZrQH143K2srSbCSg4m4kLvPMzcWydgmKEnMmoZUurYuBuYG46c6P71UGXMzmriLzCCBvKQWBUv3vPB3m1SATMhp3uEjXHJ42jFg7myX ===HEX=== Application number: 128169' @@ -311,7 +285,7 @@ INPUT: * PATH: m/83696968'/707764'/21'/0' OUTPUT -* DERIVED ENTROPY=74a2e87a9ba0cdd549bdd2f9ea880d554c6c355b08ed25088cfa88f3f1c4f74632b652fd4a8f5fda43074c6f6964a3753b08bb5210c8f5e75c07a4c2a20bf6e9 +* DERIVED ENTROPY=d7ad61d4a76575c5bad773feeb40299490b224e8e5df6c8ad8fe3d0a6eed7b85ead9fef7bcca8160f0ee48dc6e92b311fc71f2146623cc6952c03ce82c7b63fe * DERIVED PWD=dKLoepugzdVJvdL56ogNV ===PWD BASE85=== @@ -321,7 +295,7 @@ The derivation path format is: m/83696968'/707785'/{pwd_len}'/{index}'m/83696968'/89101'/{sides}'/{rolls}'/{index}' - - 2 <= sides <= 2^32 - 1 - 1 <= rolls <= 2^32 - 1 - -Use this application to generate PIN numbers or any other numeric secret. -Roll values are zero-indexed, such that an N-sided die produces values in the range -[0, N-1], inclusive. Applications should separate printed rolls by a comma or similar. - -Create a BIP85 DRNG whose seed is the derived entropy. - -Calculate the following integers: - - bits_per_roll = ceil(log_2(sides)) - bytes_per_roll = ceil(bits_per_roll / 8) - -Read bytes_per_roll bytes from the DRNG. -Trim any bits in excess of bits_per_roll (retain the most -significant bits). The resulting integer represents a single roll or trial. -If the trial is greater than or equal to the number of sides, skip it and -move on to the next one. Repeat as needed until all rolls are complete. - -INPUT: -* MASTER BIP32 ROOT KEY: xprv9s21ZrQH143K2LBWUUQRFXhucrQqBpKdRRxNVq2zBqsx8HVqFk2uYo8kmbaLLHRdqtQpUm98uKfu3vca1LqdGhUtyoFnCNkfmXRyPXLjbKb -* PATH: m/83696968'/89101'/6'/10'/0' - -OUTPUT -* DERIVED ENTROPY=5e41f8f5d5d9ac09a20b8a5797a3172b28c806aead00d27e36609e2dd116a59176a738804236586f668da8a51b90c708a4226d7f92259c69f64c51124b6f6cd2 -* DERIVED ROLLS=1,0,0,2,0,1,5,5,2,4 - ===RSA=== Application number: 828365' @@ -434,21 +374,9 @@ Many thanks to Peter Gray and Christopher Allen for their input, and to Peter fo BIP32, BIP39 -==Change Log== - -* 1.0 (2020-07) -* 2.0.0 (2024-09-22) - * Swap chain code and private key bytes in application 32' for consistentcy with BIP-32 (major change) - * Correct derived entropy for application 128169' test vector (major change) - * Clarify big endian serialization - * Add the Portuguese language (9') to application 39' - * Add dice application 89101' - * Clarify Testnet support for XPRV application 32' - * Minor grammar, format, clarity improvements - ==Footnotes== - +[1] There is a very small chance that you'll make an invalid key that is zero or bigger than the order of the curve. If this occurs, software should hard fail (forcing users to iterate to the next index). From BIP32: In case parse256(IL) is 0 or ≥ n, the resulting key is invalid, and one should proceed with the next value for i. (Note: this has probability lower than 1 in 2127.) From a34cb4f769a1bcf93b025d1441590d055e63b563 Mon Sep 17 00:00:00 2001 From: Jeremy Rubin Date: Sat, 5 Oct 2024 10:01:53 -0400 Subject: [PATCH 359/454] Remove j amesob from bip-0119.mediawiki coauthor. --- bip-0119.mediawiki | 1 - 1 file changed, 1 deletion(-) diff --git a/bip-0119.mediawiki b/bip-0119.mediawiki index 6ca0adb5dd..8e73a33c26 100644 --- a/bip-0119.mediawiki +++ b/bip-0119.mediawiki @@ -3,7 +3,6 @@ Layer: Consensus (soft fork) Title: CHECKTEMPLATEVERIFY Author: Jeremy Rubin - James O'Beirne Comments-URI: https://github.com/bitcoin/bips/wiki/Comments:BIP-0119 Status: Draft Type: Standards Track From b0125501f824804dc5f39f143c3c674f3eac6c7f Mon Sep 17 00:00:00 2001 From: scgbckbone Date: Sat, 5 Oct 2024 14:44:06 +0200 Subject: [PATCH 360/454] change BIP85 status to Final --- README.mediawiki | 4 ++-- bip-0085.mediawiki | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/README.mediawiki b/README.mediawiki index 170b05314c..6cbc02a276 100644 --- a/README.mediawiki +++ b/README.mediawiki @@ -448,13 +448,13 @@ Those proposing changes should consider that ultimately consent may rest with th | Pavol Rusnak | Standard | Final -|- +|- style="background-color: #cfffcf" | [[bip-0085.mediawiki|85]] | Applications | Deterministic Entropy From BIP32 Keychains | Ethan Kosakovsky | Informational -| Draft +| Final |- style="background-color: #cfffcf" | [[bip-0086.mediawiki|86]] | Applications diff --git a/bip-0085.mediawiki b/bip-0085.mediawiki index 633210c6c6..2df26d6088 100644 --- a/bip-0085.mediawiki +++ b/bip-0085.mediawiki @@ -5,7 +5,7 @@ Author: Ethan Kosakovsky Comments-Summary: No comments yet. Comments-URI: https://github.com/bitcoin/bips/wiki/Comments:BIP-0085 - Status: Draft + Status: Final Type: Informational Created: 2020-03-20 License: BSD-2-Clause From 80f8011e9cb8aec32d013363bcce1924601ab79c Mon Sep 17 00:00:00 2001 From: Jeremy Rubin Date: Sun, 6 Oct 2024 14:55:31 -0400 Subject: [PATCH 361/454] Remove j amesob from README.mediawiki from bip-0119 --- README.mediawiki | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.mediawiki b/README.mediawiki index 170b05314c..261a1380ca 100644 --- a/README.mediawiki +++ b/README.mediawiki @@ -641,7 +641,7 @@ Those proposing changes should consider that ultimately consent may rest with th | [[bip-0119.mediawiki|119]] | Consensus (soft fork) | CHECKTEMPLATEVERIFY -| Jeremy Rubin, James O'Beirne +| Jeremy Rubin | Standard | Draft |- style="background-color: #ffcfcf" From ca280b9762f7ce8db2c8db1149fcae0270c27cdd Mon Sep 17 00:00:00 2001 From: Jon Atack Date: Tue, 8 Oct 2024 10:48:57 -0600 Subject: [PATCH 362/454] BIP2: replace legacy http links with https --- bip-0002.mediawiki | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) diff --git a/bip-0002.mediawiki b/bip-0002.mediawiki index 4bdc23bdb9..291a0b1d9a 100644 --- a/bip-0002.mediawiki +++ b/bip-0002.mediawiki @@ -362,28 +362,28 @@ In this case, only the acceptable license(s) should be listed in the License and * BSD-2-Clause: [https://opensource.org/licenses/BSD-2-Clause OSI-approved BSD 2-clause license] * BSD-3-Clause: [https://opensource.org/licenses/BSD-3-Clause OSI-approved BSD 3-clause license] * CC0-1.0: [https://creativecommons.org/publicdomain/zero/1.0/ Creative Commons CC0 1.0 Universal] -* GNU-All-Permissive: [http://www.gnu.org/prep/maintain/html_node/License-Notices-for-Other-Files.html GNU All-Permissive License] +* GNU-All-Permissive: [https://www.gnu.org/prep/maintain/html_node/License-Notices-for-Other-Files.html GNU All-Permissive License] In addition, it is recommended that literal code included in the BIP be dual-licensed under the same license terms as the project it modifies. For example, literal code intended for Bitcoin Core would ideally be dual-licensed under the MIT license terms as well as one of the above with the rest of the BIP text. ====Not recommended, but acceptable licenses==== -* Apache-2.0: [http://www.apache.org/licenses/LICENSE-2.0 Apache License, version 2.0] -* BSL-1.0: [http://www.boost.org/LICENSE_1_0.txt Boost Software License, version 1.0] +* Apache-2.0: [https://www.apache.org/licenses/LICENSE-2.0 Apache License, version 2.0] +* BSL-1.0: [https://www.boost.org/LICENSE_1_0.txt Boost Software License, version 1.0] * CC-BY-4.0: [https://creativecommons.org/licenses/by/4.0/ Creative Commons Attribution 4.0 International] * CC-BY-SA-4.0: [https://creativecommons.org/licenses/by-sa/4.0/ Creative Commons Attribution-ShareAlike 4.0 International] * MIT: [https://opensource.org/licenses/MIT Expat/MIT/X11 license] -* AGPL-3.0+: [http://www.gnu.org/licenses/agpl-3.0.en.html GNU Affero General Public License (AGPL), version 3 or newer] -* FDL-1.3: [http://www.gnu.org/licenses/fdl-1.3.en.html GNU Free Documentation License, version 1.3] -* GPL-2.0+: [http://www.gnu.org/licenses/old-licenses/gpl-2.0.en.html GNU General Public License (GPL), version 2 or newer] -* LGPL-2.1+: [http://www.gnu.org/licenses/old-licenses/lgpl-2.1.en.html GNU Lesser General Public License (LGPL), version 2.1 or newer] +* AGPL-3.0+: [https://www.gnu.org/licenses/agpl-3.0.en.html GNU Affero General Public License (AGPL), version 3 or newer] +* FDL-1.3: [https://www.gnu.org/licenses/fdl-1.3.en.html GNU Free Documentation License, version 1.3] +* GPL-2.0+: [https://www.gnu.org/licenses/old-licenses/gpl-2.0.en.html GNU General Public License (GPL), version 2 or newer] +* LGPL-2.1+: [https://www.gnu.org/licenses/old-licenses/lgpl-2.1.en.html GNU Lesser General Public License (LGPL), version 2.1 or newer] ====Not acceptable licenses==== All licenses not explicitly included in the above lists are not acceptable terms for a Bitcoin Improvement Proposal unless a later BIP extends this one to add them. However, BIPs predating the acceptance of this BIP were allowed under other terms, and should use these abbreviation when no other license is granted: -* OPL: [http://opencontent.org/openpub/ Open Publication License, version 1.0] +* OPL: [https://opencontent.org/openpub/ Open Publication License, version 1.0] * PD: Released into the public domain ===Rationale=== From 2eb22b8ec67374573efc158ea64dde1d1da7c6dc Mon Sep 17 00:00:00 2001 From: Jon Atack Date: Fri, 11 Oct 2024 11:09:08 -0600 Subject: [PATCH 363/454] BIP327: update status --- README.mediawiki | 4 ++-- bip-0327.mediawiki | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/README.mediawiki b/README.mediawiki index 261a1380ca..6c48d0e237 100644 --- a/README.mediawiki +++ b/README.mediawiki @@ -1022,13 +1022,13 @@ Those proposing changes should consider that ultimately consent may rest with th | Chris Belcher | Informational | Draft -|- +|- style="background-color: #cfffcf" | [[bip-0327.mediawiki|327]] | | MuSig2 for BIP340-compatible Multi-Signatures | Jonas Nick, Tim Ruffing, Elliott Jin | Informational -| Draft +| Active |- | [[bip-0328.mediawiki|328]] | Applications diff --git a/bip-0327.mediawiki b/bip-0327.mediawiki index c9e88abddc..7eb8d1a6ab 100644 --- a/bip-0327.mediawiki +++ b/bip-0327.mediawiki @@ -4,7 +4,7 @@ Author: Jonas Nick Tim Ruffing Elliott Jin - Status: Draft + Status: Active License: BSD-3-Clause Type: Informational Created: 2022-03-22 From 2e98c7115cb524037300180560f5c399edb6883c Mon Sep 17 00:00:00 2001 From: Aneesh Karve Date: Sun, 13 Oct 2024 17:02:11 -0700 Subject: [PATCH 364/454] BIP-85: Correct bad test vector for Base64 --- bip-0085.mediawiki | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/bip-0085.mediawiki b/bip-0085.mediawiki index 633210c6c6..ff5b16fbb8 100644 --- a/bip-0085.mediawiki +++ b/bip-0085.mediawiki @@ -285,7 +285,7 @@ INPUT: * PATH: m/83696968'/707764'/21'/0' OUTPUT -* DERIVED ENTROPY=d7ad61d4a76575c5bad773feeb40299490b224e8e5df6c8ad8fe3d0a6eed7b85ead9fef7bcca8160f0ee48dc6e92b311fc71f2146623cc6952c03ce82c7b63fe +* DERIVED ENTROPY=74a2e87a9ba0cdd549bdd2f9ea880d554c6c355b08ed25088cfa88f3f1c4f74632b652fd4a8f5fda43074c6f6964a3753b08bb5210c8f5e75c07a4c2a20bf6e9 * DERIVED PWD=dKLoepugzdVJvdL56ogNV ===PWD BASE85=== From c4264ae98025e382ae19eb8a4a933b157cafc7f3 Mon Sep 17 00:00:00 2001 From: Bhaskar Kashyap <31563474+bskrksyp9@users.noreply.github.com> Date: Mon, 14 Oct 2024 22:35:43 +0530 Subject: [PATCH 365/454] fix typo Corrected wording in comments --- bip-0158/gentestvectors.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/bip-0158/gentestvectors.go b/bip-0158/gentestvectors.go index 2d11b14496..2df15d203d 100644 --- a/bip-0158/gentestvectors.go +++ b/bip-0158/gentestvectors.go @@ -223,7 +223,7 @@ func main() { } // We'll now ensure that we've constructed the same filter as - // the chain server we're fetching blocks form. + // the chain server we're fetching blocks from. filter, err := client.GetCFilter( blockHash, wire.GCSFilterRegular, ) From b7bd93fed7a5827b5652dc27b0dfd51d5ad3a429 Mon Sep 17 00:00:00 2001 From: Paul Sztorc Date: Tue, 15 Oct 2024 01:09:16 -0400 Subject: [PATCH 366/454] heading typo this section is (rightly) commented out, but it still (wrongly) shows up at the table of contents in the beginning, this should fix it --- bip-0300.mediawiki | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/bip-0300.mediawiki b/bip-0300.mediawiki index 9260cc6c29..74231fa292 100644 --- a/bip-0300.mediawiki +++ b/bip-0300.mediawiki @@ -408,7 +408,7 @@ If an OP_DRIVECHAIN input is spent, the additional rules for M5 or M6 (see above

-def complete_handshake(peer, initiating):
+def complete_handshake(peer, initiating, decoy_content_lengths=[]):
     received_prefix = b'' if initiating else peer.received_prefix
     ellswift_theirs = receive(peer, 64 - len(received_prefix))
     if not initiating and ellswift_theirs[4:16] == V1_PREFIX[4:16]:
@@ -370,18 +369,22 @@ def complete_handshake(peer, initiating):
     ecdh_secret = v2_ecdh(peer.privkey_ours, ellswift_theirs, peer.ellswift_ours,
                           initiating=initiating)
     initialize_v2_transport(peer, ecdh_secret, initiating=True)
-    # Send garbage terminator + garbage authentication packet + version packet.
-    send(peer, peer.send_garbage_terminator +
-               v2_enc_packet(peer, b'', aad=peer.sent_garbage) +
-               v2_enc_packet(peer, TRANSPORT_VERSION))
+    # Send garbage terminator
+    send(peer, peer.send_garbage_terminator)
+    # Optionally send decoy packets after garbage terminator.
+    aad = peer.sent_garbage
+    for decoy_content_len in decoy_content_lengths:
+        send(v2_enc_packet(peer, decoy_content_len * b'\x00', aad=aad))
+        aad = b''
+    # Send version packet.
+    send(v2_enc_packet(peer, TRANSPORT_VERSION, aad=aad))
     # Skip garbage, until encountering garbage terminator.
     received_garbage = recv(peer, 16)
     for i in range(4096):
         if received_garbage[-16:] == peer.recv_garbage_terminator:
-            # Receive, decode, and ignore garbage authentication packet (decoy or not)
-            v2_receive_packet(peer, aad=received_garbage, skip_decoy=False)
-            # Receive, decode, and ignore version packet, skipping decoys
-            v2_receive_packet(peer)
+            # Receive, decode, and ignore version packet.
+            # This includes skipping decoys and authenticating the received garbage.
+            v2_receive_packet(peer, aad=received_garbage)
             return
         else:
             received_garbage += recv(peer, 1)
@@ -494,17 +497,19 @@ def v2_enc_packet(peer, contents, aad=b'', ignore=False):
 
 CHACHA20POLY1305_EXPANSION = 16
 
-def v2_receive_packet(peer, aad=b'', skip_decoy=True):
+def v2_receive_packet(peer, aad=b''):
     while True:
         enc_contents_len = receive(peer, LENGTH_FIELD_LEN)
         contents_len = int.from_bytes(peer.recv_L.crypt(enc_contents_len), 'little')
         aead_ciphertext = receive(peer, HEADER_LEN + contents_len + CHACHA20POLY1305_EXPANSION)
-        plaintext = peer.recv_P.decrypt(aead_ciphertext)
+        plaintext = peer.recv_P.decrypt(aad, aead_ciphertext)
         if plaintext is None:
             disconnect(peer)
             break
+        # Only the first packet is expected to have non-empty AAD.
+        aad = b''
         header = plaintext[:HEADER_LEN]
-        if not (skip_decoy and header[0] & (1 << IGNORE_BIT_POS)):
+        if not (header[0] & (1 << IGNORE_BIT_POS)):
             return plaintext[HEADER_LEN:]
 
From 014b832e07d3be3c6aff1230d560fcf7032f0495 Mon Sep 17 00:00:00 2001 From: James O'Beirne Date: Fri, 29 Sep 2023 09:17:32 -0400 Subject: [PATCH 120/454] BIP-345: add sigops cost of 60 --- bip-0345.mediawiki | 1 + 1 file changed, 1 insertion(+) diff --git a/bip-0345.mediawiki b/bip-0345.mediawiki index 87e084cc68..e63e0a2871 100644 --- a/bip-0345.mediawiki +++ b/bip-0345.mediawiki @@ -266,6 +266,7 @@ where After the stack is parsed, the following validation checks are performed: +* Decrement the per-script sigops budget (see [https://github.com/bitcoin/bips/blob/master/bip-0342.mediawiki#user-content-Resource_limits BIP-0342]) by 60'''Why is the sigops cost for OP_VAULT set to 60?''' To determine the validity of a trigger output, OP_VAULT must perform an EC multiplication and hashing proportional to the length of the control block in order to generate the output's expected TapTweak. This has been measured to have a cost in the worst case (max length control block) of roughly twice a Schnorr verification. Because the hashing cost could be mitigated by caching midstate, the cost is 60 and not 100.; if the budget is brought below zero, script execution MUST fail and terminate immediately. * Let the output designated by be called ''triggerOut''. * If the scriptPubKey of ''triggerOut'' is not a witness program of the same version and same tapleaf version as the currently executing script, script execution MUST fail and terminate immediately. * Let the script constructed by taking the and prefixing it with minimally-encoded data pushes of the leaf-update script data items be called the ''leaf-update-script''. From eb3fb727c31dd348a63992d22a35558e031174f9 Mon Sep 17 00:00:00 2001 From: James O'Beirne Date: Mon, 9 Oct 2023 14:07:19 -0400 Subject: [PATCH 121/454] BIP-0345: restrict trigger output to v1 witness Co-authored-by: Antoine Poinsot --- bip-0345.mediawiki | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/bip-0345.mediawiki b/bip-0345.mediawiki index e63e0a2871..73b265e5db 100644 --- a/bip-0345.mediawiki +++ b/bip-0345.mediawiki @@ -46,7 +46,7 @@ usable for custodians of any size with minimal complication. A common configuration for an individual custodying Bitcoin is "single signature and passphrase" using a hardware wallet. A user with such a -configuration might concerned about the risk associated with relying on a +configuration might be concerned about the risk associated with relying on a single manufacturer for key management, as well as physical access to the hardware. @@ -268,7 +268,7 @@ After the stack is parsed, the following validation checks are performed: * Decrement the per-script sigops budget (see [https://github.com/bitcoin/bips/blob/master/bip-0342.mediawiki#user-content-Resource_limits BIP-0342]) by 60'''Why is the sigops cost for OP_VAULT set to 60?''' To determine the validity of a trigger output, OP_VAULT must perform an EC multiplication and hashing proportional to the length of the control block in order to generate the output's expected TapTweak. This has been measured to have a cost in the worst case (max length control block) of roughly twice a Schnorr verification. Because the hashing cost could be mitigated by caching midstate, the cost is 60 and not 100.; if the budget is brought below zero, script execution MUST fail and terminate immediately. * Let the output designated by be called ''triggerOut''. -* If the scriptPubKey of ''triggerOut'' is not a witness program of the same version and same tapleaf version as the currently executing script, script execution MUST fail and terminate immediately. +* If the scriptPubKey of ''triggerOut'' is not a version 1 witness program, script execution MUST fail and terminate immediately. * Let the script constructed by taking the and prefixing it with minimally-encoded data pushes of the leaf-update script data items be called the ''leaf-update-script''. ** Note: the leaf-update data items will be in the same order in the ''leaf-update-script'' as they appeared on the stack. * If the scriptPubKey of ''triggerOut'' does not match that of a taptree that is identical to that of the currently evaluated input, but with the leaf script substituted for ''leaf-update-script'', script execution when spending this output MUST fail and terminate immediately. From 1a629a496149bf1728238a55464907769ed635ae Mon Sep 17 00:00:00 2001 From: Andrew Chow Date: Tue, 10 Oct 2023 21:59:08 -0400 Subject: [PATCH 122/454] bip 2: allow markdown --- bip-0002.mediawiki | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/bip-0002.mediawiki b/bip-0002.mediawiki index c6eb950fec..af8bb3090a 100644 --- a/bip-0002.mediawiki +++ b/bip-0002.mediawiki @@ -102,7 +102,7 @@ The BIP editors are intended to fulfill administrative and editorial responsibil ===Specification=== -BIPs should be written in mediawiki format. +BIPs should be written in mediawiki or markdown format. Each BIP should have the following parts: From 6fd7de46b79898cff9dd1ada44fb65bd22b41f6c Mon Sep 17 00:00:00 2001 From: GoodDaisy <90915921+GoodDaisy@users.noreply.github.com> Date: Fri, 13 Oct 2023 09:05:19 +0800 Subject: [PATCH 123/454] Fix typos --- bip-0088.mediawiki | 6 +++--- bip-0152.mediawiki | 2 +- bip-0176.mediawiki | 2 +- bip-0300.mediawiki | 4 ++-- bip-0330.mediawiki | 2 +- 5 files changed, 8 insertions(+), 8 deletions(-) diff --git a/bip-0088.mediawiki b/bip-0088.mediawiki index 936f2ca931..49be7dba42 100644 --- a/bip-0088.mediawiki +++ b/bip-0088.mediawiki @@ -89,7 +89,7 @@ installation of malicious or incorrect profiles, though. ==Specification== -The format for the template was choosen to make it easy to read, convenient and visually unambigous. +The format for the template was chosen to make it easy to read, convenient and visually unambigous. Template starts with optional prefix m/, and then one or more sections delimited by the slash character (/). @@ -127,13 +127,13 @@ Constraints: # To avoid ambiguity, an index range that matches a single value MUST be specified as Unit range. # To avoid ambiguity, an index range 0-2147483647 is not allowed, and MUST be specified as Wildcard index template instead # For Non-unit range, range_end MUST be larger than range_start. -# If there is more than one index range within the Ranged index template, range_start of the second and any subsequent range MUST be larger than the range_end of the preceeding range. +# If there is more than one index range within the Ranged index template, range_start of the second and any subsequent range MUST be larger than the range_end of the preceding range. # To avoid ambiguity, all representations of integer values larger than 0 MUST NOT start with character 0 (no leading zeroes allowed). # If hardened marker appears within any section in the path template, all preceding sections MUST also specify hardened matching. # To avoid ambiguity, if a hardened marker appears within any section in the path template, all preceding sections MUST also use the same hardened marker (either h or '). # To avoid ambiguity, trailing slashes (for example, 1/2/) and duplicate slashes (for example, 0//1) MUST NOT appear in the template. -It may be desireable to have fully unambiguous encoding, where for each valid path template string, there is no other valid template string that matches the exact same set of paths. This would enable someone to compare templates for equality through a simple string equality check, without any parsing. +It may be desirable to have fully unambiguous encoding, where for each valid path template string, there is no other valid template string that matches the exact same set of paths. This would enable someone to compare templates for equality through a simple string equality check, without any parsing. To achieve this, two extra rules are needed: diff --git a/bip-0152.mediawiki b/bip-0152.mediawiki index 8200714b95..fad17460fa 100644 --- a/bip-0152.mediawiki +++ b/bip-0152.mediawiki @@ -211,7 +211,7 @@ There are several design goals for the Short ID calculation: SipHash is a secure, fast, and simple 64-bit MAC designed for network traffic authentication and collision-resistant hash tables. We truncate the output from SipHash-2-4 to 48 bits (see next section) in order to minimize space. The resulting 48-bit hash is certainly not large enough to avoid intentionally created individual collisons, but by using the block hash as a key to SipHash, an attacker cannot predict what keys will be used once their transactions are actually included in a relayed block. We mix in a per-connection 64-bit nonce to obtain independent short IDs on every connection, so that even block creators cannot control where collisions occur, and random collisions only ever affect a small number of connections at any given time. The mixing is done using SHA256(block_header || nonce), which is slow compared to SipHash, but only done once per block. It also adds the ability for nodes to choose the nonce in a better than random way to minimize collisions, though that is not necessary for correct behaviour. Conversely, nodes can also abuse this ability to increase their ability to introduce collisions in the blocks they relay themselves. However, they can already cause more problems by simply refusing to relay blocks. That is inevitable, and this design only seeks to prevent network-wide misbehavior. -====Random collision probabilty==== +====Random collision probability==== Thanks to the block-header-based SipHash keys, we can assume that the only collisions on links between honest nodes are random ones. diff --git a/bip-0176.mediawiki b/bip-0176.mediawiki index 60311c4c77..2f5ee9f9d6 100644 --- a/bip-0176.mediawiki +++ b/bip-0176.mediawiki @@ -16,7 +16,7 @@ Bits is presented here as the standard term for 100 (one hundred) satoshis or 1/ == Motivation == The bitcoin price has grown over the years and once the price is past $10,000 USD or so, bitcoin amounts under $10 USD start having enough decimal places that it's difficult to tell whether the user is off by a factor of 10 or not. Switching the denomination to "bits" makes comprehension easier. For example, when BTC is $15,000 USD, $10.05 is a somewhat confusing 0.00067 BTC, versus 670 bits, which is a lot clearer. -Additonally, reverse comparisons are easier as 59 bits being $1 is easier to comprehend for most people than 0.000059 BTC being $1. Similar comparisons can be made to other currencies: 1 yen being 0.8 bits, 1 won being 0.07 bits and so on. +Additionally, reverse comparisons are easier as 59 bits being $1 is easier to comprehend for most people than 0.000059 BTC being $1. Similar comparisons can be made to other currencies: 1 yen being 0.8 bits, 1 won being 0.07 bits and so on. Potential benefits of utilizing "bits" include: diff --git a/bip-0300.mediawiki b/bip-0300.mediawiki index ab81c3223c..e5048e75b2 100644 --- a/bip-0300.mediawiki +++ b/bip-0300.mediawiki @@ -290,7 +290,7 @@ For example: if there are two sidechains, and we wish to upvote the 7th bundle o The version number allows us to shrink the upvote vector in many cases. Version 0x00 omits the upvote vector entirely (ie, 6 bytes for the whole M4) and sets this block's M4 equal to the previous block's M4. Version 0x01 uses one byte per sidechain, and can be used while all ACKed withdrawals have an index under 256 (ie, 99.99%+ of the time). -Version 0x02 uses a full two bytes per sidechain (each encoded in little endian), but it always works no matter how many withdrawl proposals exist. +Version 0x02 uses a full two bytes per sidechain (each encoded in little endian), but it always works no matter how many withdrawal proposals exist. Version 0x03 omits the upvote vector, and instead upvotes only those withdrawals that are leading their rivals by at least 50 votes. If a sidechain has no pending bundles, then it is skipped over when M4 is created and parsed. @@ -465,7 +465,7 @@ M2: 1 get, 1 delete, 1 create M3: 3 get, 1 delete, 2 create, 2 hash for each coinbase output: search for prior M3 for this sidechain lookup if M3 was ever rejected or paid in the past - for each prior proposed withdrawl: (included in 1 get+delete+create) + for each prior proposed withdrawal: (included in 1 get+delete+create) M4: 1 get + for every proposed withdraw, 1 get, 1 delete, 1 create, 1 add v0 needs to read and parse previous block diff --git a/bip-0330.mediawiki b/bip-0330.mediawiki index c24ea427b8..996f74e15f 100644 --- a/bip-0330.mediawiki +++ b/bip-0330.mediawiki @@ -210,7 +210,7 @@ The reconcildiff message is used by reconciliation initiator to announce transac | uint32[] || ask_shortids || The short IDs that the sender did not have. |} -Upon receipt a "reconcildiff" message with ''success=1'' (reconciliation success), a node sends an "inv" message for the transactions requested by 32-bit IDs (first vector) containing their wtxids (with parent transactions occuring before their dependencies). +Upon receipt a "reconcildiff" message with ''success=1'' (reconciliation success), a node sends an "inv" message for the transactions requested by 32-bit IDs (first vector) containing their wtxids (with parent transactions occurring before their dependencies). If ''success=0'' (reconciliation failure), receiver should announce all transactions from the reconciliation set via an "inv" message. In both cases, transactions the sender of the message thinks the receiver is missing are announced via an "inv" message. The regular "inv" deduplication should apply. From 44794188ec9c0f202f8d7263392860b89a24948d Mon Sep 17 00:00:00 2001 From: Coco_Ardo <105318683+RealCocoArdo@users.noreply.github.com> Date: Fri, 20 Oct 2023 20:51:06 +0200 Subject: [PATCH 124/454] Update bip-0042.mediawiki spelling Bitcoin the network is written with a capital B. The unit is writting with small b. --- bip-0042.mediawiki | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/bip-0042.mediawiki b/bip-0042.mediawiki index 223076f59e..2c5de6dfa3 100644 --- a/bip-0042.mediawiki +++ b/bip-0042.mediawiki @@ -15,7 +15,7 @@ Although it is widely believed that Satoshi was an inflation-hating goldbug he never said this, and in fact programmed Bitcoin's money supply to grow indefinitely, forever. He modeled the monetary supply as 4 gold mines being discovered per mibillenium (1024 years), with equal intervals between them, each one being depleted over the course of 140 years. -This poses obvious problems, however. Prominent among them is the discussion on what to call 1 billion Bitcoin, which symbol color to use for it, and when wallet clients should switch to it by default. +This poses obvious problems, however. Prominent among them is the discussion on what to call 1 billion bitcoin, which symbol color to use for it, and when wallet clients should switch to it by default. To combat this, this document proposes a controversial change: making Bitcoin's monetary supply finite. From 3732ac478b0ea2decb678cfc5552c92538bd23ca Mon Sep 17 00:00:00 2001 From: Vehorny <153144728+vehorny@users.noreply.github.com> Date: Thu, 7 Dec 2023 02:12:27 +0100 Subject: [PATCH 125/454] Update bip-0010.mediawiki --- bip-0010.mediawiki | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/bip-0010.mediawiki b/bip-0010.mediawiki index 42071f3a6f..289e3b041a 100644 --- a/bip-0010.mediawiki +++ b/bip-0010.mediawiki @@ -93,10 +93,10 @@ The following is an example TxDP from Armory, produced while running on the test In this transaction, there are two inputs, one of 150 BTC and the other of 12 BTC. This transaction combines 162 BTC to create two outputs, one of 160 BTC, one 1.9995 BTC, and a tx fee of 0.0005. In this TxDP, both inputs have been signed, and thus could broadcast immediately. -The style of communication is taken directly from PGP/GPG, which uses blocks of ASCII like this to communicate encrypted messages and signatures. This serialization is compact, and will be interpretted the same in all character encodings. It can be copied inline into an email, or saved in a text file. The advantage over the analogous PGP encoding is that there are some human readable elements to it, for users that wish to examine the TxDP packet manually, instead of requiring a program to parse the core elements of the TxDP. +The style of communication is taken directly from PGP/GPG, which uses blocks of ASCII like this to communicate encrypted messages and signatures. This serialization is compact, and will be interpreted the same in all character encodings. It can be copied inline into an email, or saved in a text file. The advantage over the analogous PGP encoding is that there are some human readable elements to it, for users that wish to examine the TxDP packet manually, instead of requiring a program to parse the core elements of the TxDP. A party receiving this TxDP can simply add their signature to the appropriate _TXINPUT_ line. If that is the last signature required, they can broadcast it themselves. Any software that implements this standard should be able to combine multiple TxDPs into a single TxDP. However, even without the programmatic support, a user could manually combine them by copying the appropriate _TXSIGS_ lines between serializations, though it is not the recommended method for combining TxDPs. == Reference Implementation == -This proposal was implemented and tested in the older versions of ''Armory'' Bitcoin software for use in offline-wallet transaction signing (as a 1-of-1 transaction). Implementation can be found in https://github.com/etotheipi/BitcoinArmory/blob/v0.91-beta/armoryengine/Transaction.py under the class PyTxDistProposal. However, as of verion 0.92 released in July 2014, Armory no longer uses this proposal for offline wallet transaction signing and has moved on to a new format. +This proposal was implemented and tested in the older versions of ''Armory'' Bitcoin software for use in offline-wallet transaction signing (as a 1-of-1 transaction). Implementation can be found in https://github.com/etotheipi/BitcoinArmory/blob/v0.91-beta/armoryengine/Transaction.py under the class PyTxDistProposal. However, as of version 0.92 released in July 2014, Armory no longer uses this proposal for offline wallet transaction signing and has moved on to a new format. From 682fd8bc588df7d71476420f7bc9ed1cbacabd05 Mon Sep 17 00:00:00 2001 From: Vehorny <153144728+vehorny@users.noreply.github.com> Date: Thu, 7 Dec 2023 02:13:58 +0100 Subject: [PATCH 126/454] Update bip-0060.mediawiki --- bip-0060.mediawiki | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/bip-0060.mediawiki b/bip-0060.mediawiki index 8e9f289f05..626a039725 100644 --- a/bip-0060.mediawiki +++ b/bip-0060.mediawiki @@ -23,14 +23,14 @@ The implementation is problematic because the RelayTransactions flag is an optio One property of Bitcoin messages is their fixed number of fields. This keeps the format simple and easily understood. Adding optional fields to messages will cause deserialisation issues when other fields come after the optional one. -As an example, the length of version messages might be checked to ensure the byte stream is consistent. With optional fields, this checking is no longer possible. This is desirable to check for consistency inside internal deserialization code, and proper formatting of version messages originating from other nodes. In the future with diversification of the Bitcoin network, it will become desirable to enforce this kind of strict adherance to standard messages with field length compliance with every protocol version. +As an example, the length of version messages might be checked to ensure the byte stream is consistent. With optional fields, this checking is no longer possible. This is desirable to check for consistency inside internal deserialization code, and proper formatting of version messages originating from other nodes. In the future with diversification of the Bitcoin network, it will become desirable to enforce this kind of strict adherence to standard messages with field length compliance with every protocol version. Another property of fixed-length field messages is the ability to pass stream operators around for deserialization. This property is also lost, as now the deserialisation code must know the remaining length of bytes to parse. The parser now requires an additional piece of information (remaining size of the stream) for parsing instead of being a dumb reader. ==Specification== === version === -When a node creates an outgoing connection, it will immediately advertise its version. The remote node will respond with its version. No futher communication is possible until both peers have exchanged their version. +When a node creates an outgoing connection, it will immediately advertise its version. The remote node will respond with its version. No further communication is possible until both peers have exchanged their version. Payload: From 6f288f0f685000a9fd8669b4dfae4788619ea97e Mon Sep 17 00:00:00 2001 From: Vehorny <153144728+vehorny@users.noreply.github.com> Date: Thu, 7 Dec 2023 02:17:00 +0100 Subject: [PATCH 127/454] Update bip-0012.mediawiki --- bip-0012.mediawiki | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/bip-0012.mediawiki b/bip-0012.mediawiki index 70069d62c8..bd3d88c9b4 100644 --- a/bip-0012.mediawiki +++ b/bip-0012.mediawiki @@ -43,11 +43,11 @@ OP_EVAL allows the receiver of bitcoins to specify how they can be spent when th If ''serialized script'' is a large or complicated multi-signature script, then the burden of paying for it (in increased transaction fees due to more signature operations or transaction size) is shifted from the sender to the receiver. -The main objection to OP_EVAL is that it adds complexity, and complexity is the enemy of security. Also, evaluating data as code has a long record of being a source of security vulnerabilties. +The main objection to OP_EVAL is that it adds complexity, and complexity is the enemy of security. Also, evaluating data as code has a long record of being a source of security vulnerabilities. That same argument can be applied to the existing Bitcoin 'scripting' system; scriptPubKeys are transmit as data across the network and are then interpreted by every bitcoin implementation. OP_EVAL just moves the data that will be interpreted. It is debatable whether or not the entire idea of putting a little interpreted expression evaluation language at the core of Bitcoin was brilliant or stupid, but the existence of OP_EVAL does not make the expression language less secure. -There is a 1-confirmation attack on old clients that interepret OP_EVAL as a no-op, but it is expensive and difficult in practice. The attack is: +There is a 1-confirmation attack on old clients that interpret OP_EVAL as a no-op, but it is expensive and difficult in practice. The attack is: # Attacker creates an OP_EVAL transaction that is valid as seen by old clients, but invalid for new clients. # Attacker also creates a standard transaction that spends the OP_EVAL transaction, and pays the victim. From c595d7c517c29138ac2ece3a5e147d5036f9276a Mon Sep 17 00:00:00 2001 From: Yannick Seurin Date: Fri, 8 Dec 2023 15:34:36 +0100 Subject: [PATCH 128/454] correct fingerprint for invalid hardened indicators --- bip-0380.mediawiki | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/bip-0380.mediawiki b/bip-0380.mediawiki index 48dd93f9e8..94f0d666a3 100644 --- a/bip-0380.mediawiki +++ b/bip-0380.mediawiki @@ -244,9 +244,9 @@ Invalid expressiosn: * Trailing slash in key origin: [deadbeef/0h/0h/0h/]0260b2003c386519fc9eadf2b5cf124dd8eea4c4e68d5e154050a9346ea98ce600 * Too short fingerprint: [deadbef/0h/0h/0h]0260b2003c386519fc9eadf2b5cf124dd8eea4c4e68d5e154050a9346ea98ce600 * Too long fingerprint: [deadbeeef/0h/0h/0h]0260b2003c386519fc9eadf2b5cf124dd8eea4c4e68d5e154050a9346ea98ce600 -* Invalid hardened indicators: [deadbeeef/0f/0f/0f]0260b2003c386519fc9eadf2b5cf124dd8eea4c4e68d5e154050a9346ea98ce600 -* Invalid hardened indicators: [deadbeeef/0H/0H/0H]0260b2003c386519fc9eadf2b5cf124dd8eea4c4e68d5e154050a9346ea98ce600 -* Invalid hardened indicators: [deadbeeef/-0/-0/-0]0260b2003c386519fc9eadf2b5cf124dd8eea4c4e68d5e154050a9346ea98ce600 +* Invalid hardened indicators: [deadbeef/0f/0f/0f]0260b2003c386519fc9eadf2b5cf124dd8eea4c4e68d5e154050a9346ea98ce600 +* Invalid hardened indicators: [deadbeef/0H/0H/0H]0260b2003c386519fc9eadf2b5cf124dd8eea4c4e68d5e154050a9346ea98ce600 +* Invalid hardened indicators: [deadbeef/-0/-0/-0]0260b2003c386519fc9eadf2b5cf124dd8eea4c4e68d5e154050a9346ea98ce600 * Private key with derivation: L4rK1yDtCWekvXuE6oXD9jCYfFNV2cWRpVuPLBcCU2z8TrisoyY1/0 * Private key with derivation children: L4rK1yDtCWekvXuE6oXD9jCYfFNV2cWRpVuPLBcCU2z8TrisoyY1/* * Derivation index out of range: xprv9s21ZrQH143K31xYSDQpPDxsXRTUcvj2iNHm5NUtrGiGG5e2DtALGdso3pGz6ssrdK4PFmM8NSpSBHNqPqm55Qn3LqFtT2emdEXVYsCzC2U/2147483648)", "pkh(xpub661MyMwAqRbcFW31YEwpkMuc5THy2PSt5bDMsktWQcFF8syAmRUapSCGu8ED9W6oDMSgv6Zz8idoc4a6mr8BDzTJY47LJhkJ8UB7WEGuduB/2147483648 From 83ca57f22268edb1ff2815085a4383ba8d1b55fe Mon Sep 17 00:00:00 2001 From: Ethan Heilman Date: Mon, 11 Dec 2023 18:11:22 -0500 Subject: [PATCH 129/454] Create bip-???-cat.mediawiki --- bip-???-cat.mediawiki | 89 +++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 89 insertions(+) create mode 100644 bip-???-cat.mediawiki diff --git a/bip-???-cat.mediawiki b/bip-???-cat.mediawiki new file mode 100644 index 0000000000..8cd7baae1b --- /dev/null +++ b/bip-???-cat.mediawiki @@ -0,0 +1,89 @@ +
+  BIP: ???
+  Layer: Consensus (soft fork)
+  Title: OP_CAT
+  Author: Ethan Heilman 
+          Armin Sabouri 
+  Status: Draft
+  Type: Standards Track
+  Created: 2023-10-21
+  Comments-URI: https://github.com/bitcoin/bips/wiki/Comments:BIP-op-cat
+  License: BSD-3-Clause
+
+ +==Abstract== + +This BIP defines OP_CAT a new tapscript opcode which allows the concatenation of two values on the stack. This opcode would be activated via a soft fork by redefining the opcode OP_SUCCESS126. + +When evaluated the OP_CAT instruction: +# Pops the top two values off the stack, +# concatenate the popped values together, +# and then pushes the concatenated value on the top of the stack. + +OP_CAT fails if there are less than two values on the stack or if a concatenated value would have a combined size of greater than the maximum script element size of 520 Bytes. + +==Motivation== +Bitcoin tapscript lacks a general purpose way of combining objects on the stack restricting the expressiveness and power of tapscript. For instance this prevents among many other things the ability to construct and evaluate merkle trees and other hashed data structures in tapscript. OP_CAT by adding a general purpose way to concatenate stack values would overcome this limitation and greatly increase the functionality of tapscript. + +OP_CAT aims to expands the toolbox of the tapscript developer with a simple, modular and useful opcode in the spirit of Unix R. Pike and B. Kernighan, "Program design in the UNIX environment", 1983, https://harmful.cat-v.org/cat-v/unix_prog_design.pdf. To demonstrate the usefulness of OP_CAT below we provide a non-exhaustive list of some usecases that OP_CAT would enable: + +* Bitstream, a protocol for the atomic swap (fair exchange) of bitcoins for decryption keys, that enables decentralized file hosting systems paid in Bitcoin. While such swaps are currently possible on Bitcoin without OP_CAT they require the use of complex and computationally expensive Verifiable Computation cryptographic techniques. OP_CAT would remove this requirement on Verifiable Computation, making such protocols far more practical to build in Bitcoin. R. Linus, "BitStream: Decentralized File Hosting Incentivised via Bitcoin Payments", 2023, https://robinlinus.com/bitstream.pdf +* Tree Signatures provide a multisignature script whose size can be logarithmic in the number of public keys and can encode spend conditions beyond n-of-m. For instance a transaction less than 1KB in size could support tree signatures with a thousand public keys. This also enables generalized logical spend conditions. P. Wuille, "Multisig on steroids using tree signatures", 2015, https://blog.blockstream.com/en-treesignatures/ +* Post-Quantum Lamport Signatures in Bitcoin transactions. Lamport signatures merely requires the ability to hash and concatenate values on the stack. J. Rubin, "[bitcoin-dev] OP_CAT Makes Bitcoin Quantum Secure [was CheckSigFromStack for Arithmetic Values]", 2021, https://lists.linuxfoundation.org/pipermail/bitcoin-dev/2021-July/019233.html +* Non-equivocation contracts T. Ruffing, A. Kate, D. Schröder, "Liar, Liar, Coins on Fire: Penalizing Equivocation by Loss of Bitcoins", 2015, https://citeseerx.ist.psu.edu/viewdoc/download?doi=10.1.1.727.6262&rep=rep1&type=pdf in tapscript provide a mechanism to punish equivocation/double spending in Bitcoin payment channels. OP_CAT enables this by enforcing rules on the spending transaction's nonce. The capability is a useful building block for payment channels and other Bitcoin protocols. +* Vaults M. Moser, I. Eyal, and E. G. Sirer, Bitcoin Covenants, http://fc16.ifca.ai/bitcoin/papers/MES16.pdf which are a specialized covenant that allows a user to block a malicious party who has compromised the user's secret key from stealing the funds in that output. As shown in A. Poelstra, "CAT and Schnorr Tricks II", 2021, https://www.wpsoftware.net/andrew/blog/cat-and-schnorr-tricks-ii.html OP_CAT is sufficent to build vaults in Bitcoin. +* Replicating CheckSigFromStack A. Poelstra, "CAT and Schnorr Tricks I", 2021, https://medium.com/blockstream/cat-and-schnorr-tricks-i-faf1b59bd298 which would allow the creation of simple covenants and other advanced contracts without having to presign spending transactions, possibly reducing complexity and the amount of data that needs to be stored. Originally shown to work with Schnorr signatures, this result has been extended to ECDSA signatures R. Linus, "Covenants with CAT and ECDSA", 2023, https://gist.github.com/RobinLinus/9a69f5552be94d13170ec79bf34d5e85#file-covenants_cat_ecdsa-md. + +The opcode OP_CAT was available in early versions of Bitcoin. However OP_CAT was removed because it enabled the construction of a script for which an evaluation could have memory usage exponential in the size of the script. +For instance a script which pushed an 1 Byte value on the stack then repeated the opcodes OP_DUP, OP_CAT 40 times would result in a stack value whose size was greater than 1 Terabyte. This is no longer an issue because tapscript enforces a maximum stack element size of 520 Bytes. + +==Specification== + +OP_CAT pops two elements of the stack, concatenates them together in stack order and pushes the resultant element onto the stack. Given the stack [x1,x2], where x2 is at the top of the stack, OP_CAT will push x1||x2 onto the stack. By '||' we denote concatenation. + +Implementation +
+case OP_CAT:
+{
+    if (stack.size() < 2)
+        return set_error(serror, SCRIPT_ERR_INVALID_STACK_OPERATION);
+    valtype& vch1 = stacktop(-2);
+    valtype& vch2 = stacktop(-1);
+    if (vch1.size() + vch2.size() > MAX_SCRIPT_ELEMENT_SIZE)
+        return set_error(serror, SCRIPT_ERR_INVALID_STACK_OPERATION);
+    vch1.insert(vch1.end(), vch2.begin(), vch2.end());
+    stack.pop_back();
+}
+break;
+
+This implementation is inspired by the original implementation of OP_CAT as shown below. Alternative implementation of OP_CAT can be found in Elements Roose S., Elements Project, "Re-enable several disabled opcodes", 2019, https://github.com/ElementsProject/elements/commit/13e1103abe3e328c5a4e2039b51a546f8be6c60a#diff-a0337ffd7259e8c7c9a7786d6dbd420c80abfa1afdb34ebae3261109d9ae3c19R740-R759. + +The value of MAX_SCRIPT_ELEMENT_SIZE is 520 Bytes + +==Notes== + +OP_CAT as it existed in the Bitcoin codebase prior to the commit "misc changes" 4bd188cS. Nakamoto, "misc changes", Aug 25 2010, https://github.com/bitcoin/bitcoin/commit/4bd188c4383d6e614e18f79dc337fbabe8464c82#diff-27496895958ca30c47bbb873299a2ad7a7ea1003a9faa96b317250e3b7aa1fefL381 which disabled it. + +
+  // (x1 x2 -- out)
+  if (stack.size() < 2)
+    return false;
+  valtype& vch1 = stacktop(-2);
+  valtype& vch2 = stacktop(-1);
+  vch1.insert(vch1.end(), vch2.begin(), vch2.end());
+  stack.pop_back();
+  if (stacktop(-1).size() > 5000)
+    return false;
+  }
+
+ +==References== + + + +==Acknowledgements== + +We wish to acknowledge Dan Gould for encouraging and helping review this effort. + +== Copyright == +This document is placed in the public domain. From f1169dd1fc067825c56016379a8b84c033b6eeb2 Mon Sep 17 00:00:00 2001 From: Ethan Heilman Date: Tue, 12 Dec 2023 08:24:39 -0500 Subject: [PATCH 130/454] Fixes typo Co-authored-by: kallewoof --- bip-???-cat.mediawiki | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/bip-???-cat.mediawiki b/bip-???-cat.mediawiki index 8cd7baae1b..281fa3c535 100644 --- a/bip-???-cat.mediawiki +++ b/bip-???-cat.mediawiki @@ -39,7 +39,7 @@ For instance a script which pushed an 1 Byte value on the stack then repeated th ==Specification== -OP_CAT pops two elements of the stack, concatenates them together in stack order and pushes the resultant element onto the stack. Given the stack [x1,x2], where x2 is at the top of the stack, OP_CAT will push x1||x2 onto the stack. By '||' we denote concatenation. +OP_CAT pops two elements off the stack, concatenates them together in stack order and pushes the resulting element onto the stack. Given the stack [x1,x2], where x2 is at the top of the stack, OP_CAT will push x1||x2 onto the stack. By '||' we denote concatenation. Implementation

From 26e8e5f7fc1f51e6ba861de7a25524e1b561a08d Mon Sep 17 00:00:00 2001
From: Ethan Heilman 
Date: Tue, 12 Dec 2023 08:26:36 -0500
Subject: [PATCH 131/454] Better fits bitcoin style guide

"If an if only has a single-statement then-clause, it can appear on the same line as the if, without braces. In every other case, braces are required, and the then and else clauses must appear correctly indented on a new line."

Co-authored-by: kallewoof 
---
 bip-???-cat.mediawiki | 3 ++-
 1 file changed, 2 insertions(+), 1 deletion(-)

diff --git a/bip-???-cat.mediawiki b/bip-???-cat.mediawiki
index 281fa3c535..05f16d651b 100644
--- a/bip-???-cat.mediawiki
+++ b/bip-???-cat.mediawiki
@@ -45,8 +45,9 @@ Implementation
 
 case OP_CAT:
 {
-    if (stack.size() < 2)
+    if (stack.size() < 2) {
         return set_error(serror, SCRIPT_ERR_INVALID_STACK_OPERATION);
+    }
     valtype& vch1 = stacktop(-2);
     valtype& vch2 = stacktop(-1);
     if (vch1.size() + vch2.size() > MAX_SCRIPT_ELEMENT_SIZE)

From 0335c9d18813f3a18cff9f9b776432114f6a570c Mon Sep 17 00:00:00 2001
From: Ethan Heilman 
Date: Tue, 12 Dec 2023 08:27:35 -0500
Subject: [PATCH 132/454] Grammar fix

Co-authored-by: kallewoof 
---
 bip-???-cat.mediawiki | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/bip-???-cat.mediawiki b/bip-???-cat.mediawiki
index 05f16d651b..6833621100 100644
--- a/bip-???-cat.mediawiki
+++ b/bip-???-cat.mediawiki
@@ -57,7 +57,7 @@ case OP_CAT:
 }
 break;
 
-This implementation is inspired by the original implementation of OP_CAT as shown below. Alternative implementation of OP_CAT can be found in Elements Roose S., Elements Project, "Re-enable several disabled opcodes", 2019, https://github.com/ElementsProject/elements/commit/13e1103abe3e328c5a4e2039b51a546f8be6c60a#diff-a0337ffd7259e8c7c9a7786d6dbd420c80abfa1afdb34ebae3261109d9ae3c19R740-R759. +This implementation is inspired by the original implementation of OP_CAT as shown below. An alternative implementation of OP_CAT can be found in Elements Roose S., Elements Project, "Re-enable several disabled opcodes", 2019, https://github.com/ElementsProject/elements/commit/13e1103abe3e328c5a4e2039b51a546f8be6c60a#diff-a0337ffd7259e8c7c9a7786d6dbd420c80abfa1afdb34ebae3261109d9ae3c19R740-R759. The value of MAX_SCRIPT_ELEMENT_SIZE is 520 Bytes From 3d31e5c8947bf5d2d8ba02dc22c5302085b9f91b Mon Sep 17 00:00:00 2001 From: Ethan Heilman Date: Tue, 12 Dec 2023 08:59:03 -0500 Subject: [PATCH 133/454] Adds brackets Co-authored-by: kallewoof --- bip-???-cat.mediawiki | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/bip-???-cat.mediawiki b/bip-???-cat.mediawiki index 6833621100..584f697f60 100644 --- a/bip-???-cat.mediawiki +++ b/bip-???-cat.mediawiki @@ -50,8 +50,9 @@ case OP_CAT: } valtype& vch1 = stacktop(-2); valtype& vch2 = stacktop(-1); - if (vch1.size() + vch2.size() > MAX_SCRIPT_ELEMENT_SIZE) + if (vch1.size() + vch2.size() > MAX_SCRIPT_ELEMENT_SIZE) { return set_error(serror, SCRIPT_ERR_INVALID_STACK_OPERATION); + } vch1.insert(vch1.end(), vch2.begin(), vch2.end()); stack.pop_back(); } From a28b021b9933cb6b035cbb94fc1a15c30da3f6fd Mon Sep 17 00:00:00 2001 From: Ava Chow Date: Wed, 13 Dec 2023 11:12:08 -0500 Subject: [PATCH 134/454] Update contact info for achow101 --- README.mediawiki | 24 ++++++++++++------------ bip-0086.mediawiki | 2 +- bip-0129.mediawiki | 2 +- bip-0174.mediawiki | 2 +- bip-0370.mediawiki | 2 +- bip-0371.mediawiki | 2 +- bip-0380.mediawiki | 2 +- bip-0381.mediawiki | 2 +- bip-0382.mediawiki | 2 +- bip-0383.mediawiki | 2 +- bip-0384.mediawiki | 2 +- bip-0385.mediawiki | 2 +- bip-0386.mediawiki | 2 +- bip-0389.mediawiki | 2 +- 14 files changed, 25 insertions(+), 25 deletions(-) diff --git a/README.mediawiki b/README.mediawiki index 96b8df3372..6dbd798420 100644 --- a/README.mediawiki +++ b/README.mediawiki @@ -452,7 +452,7 @@ Those proposing changes should consider that ultimately consent may rest with th | [[bip-0086.mediawiki|86]] | Applications | Key Derivation for Single Key P2TR Outputs -| Andrew Chow +| Ava Chow | Standard | Draft |- style="background-color: #ffffcf" @@ -900,7 +900,7 @@ Those proposing changes should consider that ultimately consent may rest with th | [[bip-0174.mediawiki|174]] | Applications | Partially Signed Bitcoin Transaction Format -| Andrew Chow +| Ava Chow | Standard | Final |- style="background-color: #ffcfcf" @@ -1089,14 +1089,14 @@ Those proposing changes should consider that ultimately consent may rest with th | [[bip-0370.mediawiki|370]] | Applications | PSBT Version 2 -| Andrew Chow +| Ava Chow | Standard | Draft |- | [[bip-0371.mediawiki|371]] | Applications | Taproot Fields for PSBT -| Andrew Chow +| Ava Chow | Standard | Draft |- @@ -1110,56 +1110,56 @@ Those proposing changes should consider that ultimately consent may rest with th | [[bip-0380.mediawiki|380]] | Applications | Output Script Descriptors General Operation -| Pieter Wuille, Andrew Chow +| Pieter Wuille, Ava Chow | Informational | Draft |- | [[bip-0381.mediawiki|381]] | Applications | Non-Segwit Output Script Descriptors -| Pieter Wuille, Andrew Chow +| Pieter Wuille, Ava Chow | Informational | Draft |- | [[bip-0382.mediawiki|382]] | Applications | Segwit Output Script Descriptors -| Pieter Wuille, Andrew Chow +| Pieter Wuille, Ava Chow | Informational | Draft |- | [[bip-0383.mediawiki|383]] | Applications | Multisig Output Script Descriptors -| Pieter Wuille, Andrew Chow +| Pieter Wuille, Ava Chow | Informational | Draft |- | [[bip-0384.mediawiki|384]] | Applications | combo() Output Script Descriptors -| Pieter Wuille, Andrew Chow +| Pieter Wuille, Ava Chow | Informational | Draft |- | [[bip-0385.mediawiki|385]] | Applications | raw() and addr() Output Script Descriptors -| Pieter Wuille, Andrew Chow +| Pieter Wuille, Ava Chow | Informational | Draft |- | [[bip-0386.mediawiki|386]] | Applications | tr() Output Script Descriptors -| Pieter Wuille, Andrew Chow +| Pieter Wuille, Ava Chow | Informational | Draft |- | [[bip-0389.mediawiki|389]] | Applications | Multipath Descriptor Key Expressions -| Andrew Chow +| Ava Chow | Informational | Draft |} diff --git a/bip-0086.mediawiki b/bip-0086.mediawiki index f724884e8a..529f0946f2 100644 --- a/bip-0086.mediawiki +++ b/bip-0086.mediawiki @@ -2,7 +2,7 @@ BIP: 86 Layer: Applications Title: Key Derivation for Single Key P2TR Outputs - Author: Andrew Chow + Author: Ava Chow Comments-Summary: No comments yet. Comments-URI: https://github.com/bitcoin/bips/wiki/Comments:BIP-0086 Status: Draft diff --git a/bip-0129.mediawiki b/bip-0129.mediawiki index 8719fe420f..608c724ec4 100644 --- a/bip-0129.mediawiki +++ b/bip-0129.mediawiki @@ -452,7 +452,7 @@ sh(wsh(multi(2,[793cc70b/48'/0'/0'/1']xpub6ErVmcYYHmavsMgxEcTZyzN5sqth1ZyRpFNJC2 ==Acknowledgement== -Special thanks to Pavol Rusnak, Dmitry Petukhov, Christopher Allen, Craig Raw, Robert Spigler, Gregory Sanders, Ta Tat Tai, Michael Flaxman, Pieter Wuille, Salvatore Ingala, Andrew Chow and others for their feedback on the specification. +Special thanks to Pavol Rusnak, Dmitry Petukhov, Christopher Allen, Craig Raw, Robert Spigler, Gregory Sanders, Ta Tat Tai, Michael Flaxman, Pieter Wuille, Salvatore Ingala, Ava Chow and others for their feedback on the specification. ==References== diff --git a/bip-0174.mediawiki b/bip-0174.mediawiki index f4c0807c94..5e70a110f7 100644 --- a/bip-0174.mediawiki +++ b/bip-0174.mediawiki @@ -2,7 +2,7 @@ BIP: 174 Layer: Applications Title: Partially Signed Bitcoin Transaction Format - Author: Andrew Chow + Author: Ava Chow Comments-Summary: No comments yet. Comments-URI: https://github.com/bitcoin/bips/wiki/Comments:BIP-0174 Status: Final diff --git a/bip-0370.mediawiki b/bip-0370.mediawiki index cb5980144b..cd448cc0b0 100644 --- a/bip-0370.mediawiki +++ b/bip-0370.mediawiki @@ -2,7 +2,7 @@ BIP: 370 Layer: Applications Title: PSBT Version 2 - Author: Andrew Chow + Author: Ava Chow Comments-Summary: No comments yet. Comments-URI: https://github.com/bitcoin/bips/wiki/Comments:BIP-0370 Status: Draft diff --git a/bip-0371.mediawiki b/bip-0371.mediawiki index 599aa546a6..45b69f8a66 100644 --- a/bip-0371.mediawiki +++ b/bip-0371.mediawiki @@ -2,7 +2,7 @@ BIP: 371 Layer: Applications Title: Taproot Fields for PSBT - Author: Andrew Chow + Author: Ava Chow Comments-Summary: No comments yet. Comments-URI: https://github.com/bitcoin/bips/wiki/Comments:BIP-0371 Status: Draft diff --git a/bip-0380.mediawiki b/bip-0380.mediawiki index 48dd93f9e8..4e73b5fc71 100644 --- a/bip-0380.mediawiki +++ b/bip-0380.mediawiki @@ -3,7 +3,7 @@ Layer: Applications Title: Output Script Descriptors General Operation Author: Pieter Wuille - Andrew Chow + Ava Chow Comments-Summary: No comments yet. Comments-URI: https://github.com/bitcoin/bips/wiki/Comments:BIP-0380 Status: Draft diff --git a/bip-0381.mediawiki b/bip-0381.mediawiki index 769b42d268..4b94278498 100644 --- a/bip-0381.mediawiki +++ b/bip-0381.mediawiki @@ -3,7 +3,7 @@ Layer: Applications Title: Non-Segwit Output Script Descriptors Author: Pieter Wuille - Andrew Chow + Ava Chow Comments-Summary: No comments yet. Comments-URI: https://github.com/bitcoin/bips/wiki/Comments:BIP-0381 Status: Draft diff --git a/bip-0382.mediawiki b/bip-0382.mediawiki index 1b7c1562c3..942f62c183 100644 --- a/bip-0382.mediawiki +++ b/bip-0382.mediawiki @@ -3,7 +3,7 @@ Layer: Applications Title: Segwit Output Script Descriptors Author: Pieter Wuille - Andrew Chow + Ava Chow Comments-Summary: No comments yet. Comments-URI: https://github.com/bitcoin/bips/wiki/Comments:BIP-0382 Status: Draft diff --git a/bip-0383.mediawiki b/bip-0383.mediawiki index 27fb74b58c..66e2f16090 100644 --- a/bip-0383.mediawiki +++ b/bip-0383.mediawiki @@ -3,7 +3,7 @@ Layer: Applications Title: Multisig Output Script Descriptors Author: Pieter Wuille - Andrew Chow + Ava Chow Comments-Summary: No comments yet. Comments-URI: https://github.com/bitcoin/bips/wiki/Comments:BIP-0383 Status: Draft diff --git a/bip-0384.mediawiki b/bip-0384.mediawiki index 98dca77864..02d6f765ec 100644 --- a/bip-0384.mediawiki +++ b/bip-0384.mediawiki @@ -3,7 +3,7 @@ Layer: Applications Title: combo() Output Script Descriptors Author: Pieter Wuille - Andrew Chow + Ava Chow Comments-Summary: No comments yet. Comments-URI: https://github.com/bitcoin/bips/wiki/Comments:BIP-0384 Status: Draft diff --git a/bip-0385.mediawiki b/bip-0385.mediawiki index f97a3316ec..3e922b3bd1 100644 --- a/bip-0385.mediawiki +++ b/bip-0385.mediawiki @@ -3,7 +3,7 @@ Layer: Applications Title: raw() and addr() Output Script Descriptors Author: Pieter Wuille - Andrew Chow + Ava Chow Comments-Summary: No comments yet. Comments-URI: https://github.com/bitcoin/bips/wiki/Comments:BIP-0385 Status: Draft diff --git a/bip-0386.mediawiki b/bip-0386.mediawiki index 782a6f8fed..759887d41d 100644 --- a/bip-0386.mediawiki +++ b/bip-0386.mediawiki @@ -3,7 +3,7 @@ Layer: Applications Title: tr() Output Script Descriptors Author: Pieter Wuille - Andrew Chow + Ava Chow Comments-Summary: No comments yet. Comments-URI: https://github.com/bitcoin/bips/wiki/Comments:BIP-0386 Status: Draft diff --git a/bip-0389.mediawiki b/bip-0389.mediawiki index fe14b629cd..500d7e3cf8 100644 --- a/bip-0389.mediawiki +++ b/bip-0389.mediawiki @@ -2,7 +2,7 @@ BIP: 389 Layer: Applications Title: Multipath Descriptor Key Expressions - Author: Andrew Chow + Author: Ava Chow Comments-Summary: No comments yet. Comments-URI: https://github.com/bitcoin/bips/wiki/Comments:BIP-0389 Status: Draft From bb725e652357f2502fba3cd8e2e8fa92e40ca706 Mon Sep 17 00:00:00 2001 From: Ethan Heilman Date: Thu, 14 Dec 2023 23:43:42 -0500 Subject: [PATCH 135/454] Wording Co-authored-by: kallewoof --- bip-???-cat.mediawiki | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/bip-???-cat.mediawiki b/bip-???-cat.mediawiki index 584f697f60..40b4cc55a8 100644 --- a/bip-???-cat.mediawiki +++ b/bip-???-cat.mediawiki @@ -13,7 +13,7 @@ ==Abstract== -This BIP defines OP_CAT a new tapscript opcode which allows the concatenation of two values on the stack. This opcode would be activated via a soft fork by redefining the opcode OP_SUCCESS126. +This BIP reintroduces OP_CAT in the form of a new tapscript opcode which allows the concatenation of two values on the stack. This opcode would be activated via a soft fork by redefining the opcode OP_SUCCESS126. When evaluated the OP_CAT instruction: # Pops the top two values off the stack, From 9779dc9920eeacbf39a9b53e5165423551de209e Mon Sep 17 00:00:00 2001 From: Ethan Heilman Date: Thu, 14 Dec 2023 23:44:14 -0500 Subject: [PATCH 136/454] Keeps past tense consistant Co-authored-by: kallewoof --- bip-???-cat.mediawiki | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/bip-???-cat.mediawiki b/bip-???-cat.mediawiki index 40b4cc55a8..1beb7c565e 100644 --- a/bip-???-cat.mediawiki +++ b/bip-???-cat.mediawiki @@ -17,7 +17,7 @@ This BIP reintroduces OP_CAT in the form of a new tapscript opcode which allows When evaluated the OP_CAT instruction: # Pops the top two values off the stack, -# concatenate the popped values together, +# concatenates the popped values together, # and then pushes the concatenated value on the top of the stack. OP_CAT fails if there are less than two values on the stack or if a concatenated value would have a combined size of greater than the maximum script element size of 520 Bytes. From c5d66d670671dbac8265b5588f3de8e1ca4f3972 Mon Sep 17 00:00:00 2001 From: Ethan Heilman Date: Thu, 14 Dec 2023 23:44:44 -0500 Subject: [PATCH 137/454] Better phrasing Co-authored-by: kallewoof --- bip-???-cat.mediawiki | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/bip-???-cat.mediawiki b/bip-???-cat.mediawiki index 1beb7c565e..c84680acaf 100644 --- a/bip-???-cat.mediawiki +++ b/bip-???-cat.mediawiki @@ -20,7 +20,7 @@ When evaluated the OP_CAT instruction: # concatenates the popped values together, # and then pushes the concatenated value on the top of the stack. -OP_CAT fails if there are less than two values on the stack or if a concatenated value would have a combined size of greater than the maximum script element size of 520 Bytes. +OP_CAT fails if there are less than two values on the stack or if a concatenated value would have a combined size greater than the maximum script element size of 520 Bytes. ==Motivation== Bitcoin tapscript lacks a general purpose way of combining objects on the stack restricting the expressiveness and power of tapscript. For instance this prevents among many other things the ability to construct and evaluate merkle trees and other hashed data structures in tapscript. OP_CAT by adding a general purpose way to concatenate stack values would overcome this limitation and greatly increase the functionality of tapscript. From 848352f40875e43ba7fd5ecabb63272f165fcd4a Mon Sep 17 00:00:00 2001 From: Ethan Heilman Date: Thu, 14 Dec 2023 23:45:04 -0500 Subject: [PATCH 138/454] Phrasing Co-authored-by: kallewoof --- bip-???-cat.mediawiki | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/bip-???-cat.mediawiki b/bip-???-cat.mediawiki index c84680acaf..d921524315 100644 --- a/bip-???-cat.mediawiki +++ b/bip-???-cat.mediawiki @@ -23,7 +23,7 @@ When evaluated the OP_CAT instruction: OP_CAT fails if there are less than two values on the stack or if a concatenated value would have a combined size greater than the maximum script element size of 520 Bytes. ==Motivation== -Bitcoin tapscript lacks a general purpose way of combining objects on the stack restricting the expressiveness and power of tapscript. For instance this prevents among many other things the ability to construct and evaluate merkle trees and other hashed data structures in tapscript. OP_CAT by adding a general purpose way to concatenate stack values would overcome this limitation and greatly increase the functionality of tapscript. +Bitcoin tapscript lacks a general purpose way of combining objects on the stack restricting the expressiveness and power of tapscript. This prevents among many other things the ability to construct and evaluate merkle trees and other hashed data structures in tapscript. OP_CAT by adding a general purpose way to concatenate stack values would overcome this limitation and greatly increase the functionality of tapscript. OP_CAT aims to expands the toolbox of the tapscript developer with a simple, modular and useful opcode in the spirit of Unix R. Pike and B. Kernighan, "Program design in the UNIX environment", 1983, https://harmful.cat-v.org/cat-v/unix_prog_design.pdf. To demonstrate the usefulness of OP_CAT below we provide a non-exhaustive list of some usecases that OP_CAT would enable: From a2b0100671f492628ce219d706fa71a506ca0475 Mon Sep 17 00:00:00 2001 From: Ethan Heilman Date: Thu, 14 Dec 2023 23:47:36 -0500 Subject: [PATCH 139/454] Typo Co-authored-by: kallewoof --- bip-???-cat.mediawiki | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/bip-???-cat.mediawiki b/bip-???-cat.mediawiki index d921524315..32595c33c8 100644 --- a/bip-???-cat.mediawiki +++ b/bip-???-cat.mediawiki @@ -29,7 +29,7 @@ OP_CAT aims to expands the toolbox of the tapscript developer with a simple, mod * Bitstream, a protocol for the atomic swap (fair exchange) of bitcoins for decryption keys, that enables decentralized file hosting systems paid in Bitcoin. While such swaps are currently possible on Bitcoin without OP_CAT they require the use of complex and computationally expensive Verifiable Computation cryptographic techniques. OP_CAT would remove this requirement on Verifiable Computation, making such protocols far more practical to build in Bitcoin. R. Linus, "BitStream: Decentralized File Hosting Incentivised via Bitcoin Payments", 2023, https://robinlinus.com/bitstream.pdf * Tree Signatures provide a multisignature script whose size can be logarithmic in the number of public keys and can encode spend conditions beyond n-of-m. For instance a transaction less than 1KB in size could support tree signatures with a thousand public keys. This also enables generalized logical spend conditions. P. Wuille, "Multisig on steroids using tree signatures", 2015, https://blog.blockstream.com/en-treesignatures/ -* Post-Quantum Lamport Signatures in Bitcoin transactions. Lamport signatures merely requires the ability to hash and concatenate values on the stack. J. Rubin, "[bitcoin-dev] OP_CAT Makes Bitcoin Quantum Secure [was CheckSigFromStack for Arithmetic Values]", 2021, https://lists.linuxfoundation.org/pipermail/bitcoin-dev/2021-July/019233.html +* Post-Quantum Lamport Signatures in Bitcoin transactions. Lamport signatures merely require the ability to hash and concatenate values on the stack. J. Rubin, "[bitcoin-dev] OP_CAT Makes Bitcoin Quantum Secure [was CheckSigFromStack for Arithmetic Values]", 2021, https://lists.linuxfoundation.org/pipermail/bitcoin-dev/2021-July/019233.html * Non-equivocation contracts T. Ruffing, A. Kate, D. Schröder, "Liar, Liar, Coins on Fire: Penalizing Equivocation by Loss of Bitcoins", 2015, https://citeseerx.ist.psu.edu/viewdoc/download?doi=10.1.1.727.6262&rep=rep1&type=pdf in tapscript provide a mechanism to punish equivocation/double spending in Bitcoin payment channels. OP_CAT enables this by enforcing rules on the spending transaction's nonce. The capability is a useful building block for payment channels and other Bitcoin protocols. * Vaults M. Moser, I. Eyal, and E. G. Sirer, Bitcoin Covenants, http://fc16.ifca.ai/bitcoin/papers/MES16.pdf which are a specialized covenant that allows a user to block a malicious party who has compromised the user's secret key from stealing the funds in that output. As shown in A. Poelstra, "CAT and Schnorr Tricks II", 2021, https://www.wpsoftware.net/andrew/blog/cat-and-schnorr-tricks-ii.html OP_CAT is sufficent to build vaults in Bitcoin. * Replicating CheckSigFromStack A. Poelstra, "CAT and Schnorr Tricks I", 2021, https://medium.com/blockstream/cat-and-schnorr-tricks-i-faf1b59bd298 which would allow the creation of simple covenants and other advanced contracts without having to presign spending transactions, possibly reducing complexity and the amount of data that needs to be stored. Originally shown to work with Schnorr signatures, this result has been extended to ECDSA signatures R. Linus, "Covenants with CAT and ECDSA", 2023, https://gist.github.com/RobinLinus/9a69f5552be94d13170ec79bf34d5e85#file-covenants_cat_ecdsa-md. From 6a790ec52635a7aa52cc2c20dc25a9236daae5f8 Mon Sep 17 00:00:00 2001 From: Ethan Heilman Date: Thu, 14 Dec 2023 23:47:50 -0500 Subject: [PATCH 140/454] Removes space in ref Co-authored-by: kallewoof --- bip-???-cat.mediawiki | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/bip-???-cat.mediawiki b/bip-???-cat.mediawiki index 32595c33c8..cd952c82e7 100644 --- a/bip-???-cat.mediawiki +++ b/bip-???-cat.mediawiki @@ -31,7 +31,7 @@ OP_CAT aims to expands the toolbox of the tapscript developer with a simple, mod * Tree Signatures provide a multisignature script whose size can be logarithmic in the number of public keys and can encode spend conditions beyond n-of-m. For instance a transaction less than 1KB in size could support tree signatures with a thousand public keys. This also enables generalized logical spend conditions. P. Wuille, "Multisig on steroids using tree signatures", 2015, https://blog.blockstream.com/en-treesignatures/ * Post-Quantum Lamport Signatures in Bitcoin transactions. Lamport signatures merely require the ability to hash and concatenate values on the stack. J. Rubin, "[bitcoin-dev] OP_CAT Makes Bitcoin Quantum Secure [was CheckSigFromStack for Arithmetic Values]", 2021, https://lists.linuxfoundation.org/pipermail/bitcoin-dev/2021-July/019233.html * Non-equivocation contracts T. Ruffing, A. Kate, D. Schröder, "Liar, Liar, Coins on Fire: Penalizing Equivocation by Loss of Bitcoins", 2015, https://citeseerx.ist.psu.edu/viewdoc/download?doi=10.1.1.727.6262&rep=rep1&type=pdf in tapscript provide a mechanism to punish equivocation/double spending in Bitcoin payment channels. OP_CAT enables this by enforcing rules on the spending transaction's nonce. The capability is a useful building block for payment channels and other Bitcoin protocols. -* Vaults M. Moser, I. Eyal, and E. G. Sirer, Bitcoin Covenants, http://fc16.ifca.ai/bitcoin/papers/MES16.pdf which are a specialized covenant that allows a user to block a malicious party who has compromised the user's secret key from stealing the funds in that output. As shown in A. Poelstra, "CAT and Schnorr Tricks II", 2021, https://www.wpsoftware.net/andrew/blog/cat-and-schnorr-tricks-ii.html OP_CAT is sufficent to build vaults in Bitcoin. +* Vaults M. Moser, I. Eyal, and E. G. Sirer, Bitcoin Covenants, http://fc16.ifca.ai/bitcoin/papers/MES16.pdf which are a specialized covenant that allows a user to block a malicious party who has compromised the user's secret key from stealing the funds in that output. As shown in A. Poelstra, "CAT and Schnorr Tricks II", 2021, https://www.wpsoftware.net/andrew/blog/cat-and-schnorr-tricks-ii.html OP_CAT is sufficent to build vaults in Bitcoin. * Replicating CheckSigFromStack A. Poelstra, "CAT and Schnorr Tricks I", 2021, https://medium.com/blockstream/cat-and-schnorr-tricks-i-faf1b59bd298 which would allow the creation of simple covenants and other advanced contracts without having to presign spending transactions, possibly reducing complexity and the amount of data that needs to be stored. Originally shown to work with Schnorr signatures, this result has been extended to ECDSA signatures R. Linus, "Covenants with CAT and ECDSA", 2023, https://gist.github.com/RobinLinus/9a69f5552be94d13170ec79bf34d5e85#file-covenants_cat_ecdsa-md. The opcode OP_CAT was available in early versions of Bitcoin. However OP_CAT was removed because it enabled the construction of a script for which an evaluation could have memory usage exponential in the size of the script. From 01db3acab0830a43b526c6c5c0a8daad77704d7b Mon Sep 17 00:00:00 2001 From: Ethan Heilman Date: Thu, 14 Dec 2023 23:47:58 -0500 Subject: [PATCH 141/454] Removes space in ref Co-authored-by: kallewoof --- bip-???-cat.mediawiki | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/bip-???-cat.mediawiki b/bip-???-cat.mediawiki index cd952c82e7..9e98da0fd9 100644 --- a/bip-???-cat.mediawiki +++ b/bip-???-cat.mediawiki @@ -32,7 +32,7 @@ OP_CAT aims to expands the toolbox of the tapscript developer with a simple, mod * Post-Quantum Lamport Signatures in Bitcoin transactions. Lamport signatures merely require the ability to hash and concatenate values on the stack. J. Rubin, "[bitcoin-dev] OP_CAT Makes Bitcoin Quantum Secure [was CheckSigFromStack for Arithmetic Values]", 2021, https://lists.linuxfoundation.org/pipermail/bitcoin-dev/2021-July/019233.html * Non-equivocation contracts T. Ruffing, A. Kate, D. Schröder, "Liar, Liar, Coins on Fire: Penalizing Equivocation by Loss of Bitcoins", 2015, https://citeseerx.ist.psu.edu/viewdoc/download?doi=10.1.1.727.6262&rep=rep1&type=pdf in tapscript provide a mechanism to punish equivocation/double spending in Bitcoin payment channels. OP_CAT enables this by enforcing rules on the spending transaction's nonce. The capability is a useful building block for payment channels and other Bitcoin protocols. * Vaults M. Moser, I. Eyal, and E. G. Sirer, Bitcoin Covenants, http://fc16.ifca.ai/bitcoin/papers/MES16.pdf which are a specialized covenant that allows a user to block a malicious party who has compromised the user's secret key from stealing the funds in that output. As shown in A. Poelstra, "CAT and Schnorr Tricks II", 2021, https://www.wpsoftware.net/andrew/blog/cat-and-schnorr-tricks-ii.html OP_CAT is sufficent to build vaults in Bitcoin. -* Replicating CheckSigFromStack A. Poelstra, "CAT and Schnorr Tricks I", 2021, https://medium.com/blockstream/cat-and-schnorr-tricks-i-faf1b59bd298 which would allow the creation of simple covenants and other advanced contracts without having to presign spending transactions, possibly reducing complexity and the amount of data that needs to be stored. Originally shown to work with Schnorr signatures, this result has been extended to ECDSA signatures R. Linus, "Covenants with CAT and ECDSA", 2023, https://gist.github.com/RobinLinus/9a69f5552be94d13170ec79bf34d5e85#file-covenants_cat_ecdsa-md. +* Replicating CheckSigFromStack A. Poelstra, "CAT and Schnorr Tricks I", 2021, https://medium.com/blockstream/cat-and-schnorr-tricks-i-faf1b59bd298 which would allow the creation of simple covenants and other advanced contracts without having to presign spending transactions, possibly reducing complexity and the amount of data that needs to be stored. Originally shown to work with Schnorr signatures, this result has been extended to ECDSA signatures R. Linus, "Covenants with CAT and ECDSA", 2023, https://gist.github.com/RobinLinus/9a69f5552be94d13170ec79bf34d5e85#file-covenants_cat_ecdsa-md. The opcode OP_CAT was available in early versions of Bitcoin. However OP_CAT was removed because it enabled the construction of a script for which an evaluation could have memory usage exponential in the size of the script. For instance a script which pushed an 1 Byte value on the stack then repeated the opcodes OP_DUP, OP_CAT 40 times would result in a stack value whose size was greater than 1 Terabyte. This is no longer an issue because tapscript enforces a maximum stack element size of 520 Bytes. From 945e2a374249114c313d6204d7db61dfe496fe97 Mon Sep 17 00:00:00 2001 From: Ethan Heilman Date: Thu, 14 Dec 2023 23:48:46 -0500 Subject: [PATCH 142/454] Typos TIL that it is "a one" rather than "an one" Co-authored-by: kallewoof --- bip-???-cat.mediawiki | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/bip-???-cat.mediawiki b/bip-???-cat.mediawiki index 9e98da0fd9..ef026fd6fe 100644 --- a/bip-???-cat.mediawiki +++ b/bip-???-cat.mediawiki @@ -35,7 +35,7 @@ OP_CAT aims to expands the toolbox of the tapscript developer with a simple, mod * Replicating CheckSigFromStack A. Poelstra, "CAT and Schnorr Tricks I", 2021, https://medium.com/blockstream/cat-and-schnorr-tricks-i-faf1b59bd298 which would allow the creation of simple covenants and other advanced contracts without having to presign spending transactions, possibly reducing complexity and the amount of data that needs to be stored. Originally shown to work with Schnorr signatures, this result has been extended to ECDSA signatures R. Linus, "Covenants with CAT and ECDSA", 2023, https://gist.github.com/RobinLinus/9a69f5552be94d13170ec79bf34d5e85#file-covenants_cat_ecdsa-md. The opcode OP_CAT was available in early versions of Bitcoin. However OP_CAT was removed because it enabled the construction of a script for which an evaluation could have memory usage exponential in the size of the script. -For instance a script which pushed an 1 Byte value on the stack then repeated the opcodes OP_DUP, OP_CAT 40 times would result in a stack value whose size was greater than 1 Terabyte. This is no longer an issue because tapscript enforces a maximum stack element size of 520 Bytes. +For instance a script which pushed a 1 Byte value on the stack and then repeated the opcodes OP_DUP, OP_CAT 40 times would result in a stack value whose size was greater than 1 Terabyte. This is no longer an issue because tapscript enforces a maximum stack element size of 520 Bytes. ==Specification== From b434f1813ca2d4c270b51e53a4b7acd52f69bf60 Mon Sep 17 00:00:00 2001 From: Alexander Nemish Date: Fri, 15 Dec 2023 11:00:10 +0100 Subject: [PATCH 143/454] Update bip-0085.mediawiki Fix doublicated word --- bip-0085.mediawiki | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/bip-0085.mediawiki b/bip-0085.mediawiki index 06277555d9..d5557fbf7b 100644 --- a/bip-0085.mediawiki +++ b/bip-0085.mediawiki @@ -364,7 +364,7 @@ The resulting RSA key can be used to create a GPG key where the creation date MU Note on GPG key capabilities on smartcard/hardware devices: -GPG capable smart-cards SHOULD be be loaded as follows: The encryption slot SHOULD be loaded with the ENCRYPTION capable key; the authentication slot SHOULD be loaded with the AUTHENTICATION capable key. The signature capable slot SHOULD be loaded with the SIGNATURE capable key. +GPG capable smart-cards SHOULD be loaded as follows: The encryption slot SHOULD be loaded with the ENCRYPTION capable key; the authentication slot SHOULD be loaded with the AUTHENTICATION capable key. The signature capable slot SHOULD be loaded with the SIGNATURE capable key. However, depending on available slots on the smart-card, and preferred policy, the CERTIFY capable key MAY be flagged with CERTIFY and SIGNATURE capabilities and loaded into the SIGNATURE capable slot (for example where the smart-card has only three slots and the CERTIFY capability is required on the same card). In this case, the SIGNATURE capable sub-key would be disregarded because the CERTIFY capable key serves a dual purpose. From 7180c1cf8c478ed53ee65705e34fc61975f96239 Mon Sep 17 00:00:00 2001 From: Ethan Heilman Date: Fri, 15 Dec 2023 09:54:50 -0500 Subject: [PATCH 144/454] Prefer bytes to Bytes MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Co-authored-by: Vojtěch Strnad <43024885+vostrnad@users.noreply.github.com> --- bip-???-cat.mediawiki | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/bip-???-cat.mediawiki b/bip-???-cat.mediawiki index ef026fd6fe..2a39158b98 100644 --- a/bip-???-cat.mediawiki +++ b/bip-???-cat.mediawiki @@ -20,7 +20,7 @@ When evaluated the OP_CAT instruction: # concatenates the popped values together, # and then pushes the concatenated value on the top of the stack. -OP_CAT fails if there are less than two values on the stack or if a concatenated value would have a combined size greater than the maximum script element size of 520 Bytes. +OP_CAT fails if there are less than two values on the stack or if a concatenated value would have a combined size greater than the maximum script element size of 520 bytes. ==Motivation== Bitcoin tapscript lacks a general purpose way of combining objects on the stack restricting the expressiveness and power of tapscript. This prevents among many other things the ability to construct and evaluate merkle trees and other hashed data structures in tapscript. OP_CAT by adding a general purpose way to concatenate stack values would overcome this limitation and greatly increase the functionality of tapscript. From 6f5a74d83e621ded090f436a3cc407dc705ad132 Mon Sep 17 00:00:00 2001 From: Ethan Heilman Date: Fri, 15 Dec 2023 10:04:36 -0500 Subject: [PATCH 145/454] Increases conciseness and clarity MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Co-authored-by: Vojtěch Strnad <43024885+vostrnad@users.noreply.github.com> --- bip-???-cat.mediawiki | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/bip-???-cat.mediawiki b/bip-???-cat.mediawiki index 2a39158b98..92b2588e8a 100644 --- a/bip-???-cat.mediawiki +++ b/bip-???-cat.mediawiki @@ -34,7 +34,7 @@ OP_CAT aims to expands the toolbox of the tapscript developer with a simple, mod * Vaults M. Moser, I. Eyal, and E. G. Sirer, Bitcoin Covenants, http://fc16.ifca.ai/bitcoin/papers/MES16.pdf which are a specialized covenant that allows a user to block a malicious party who has compromised the user's secret key from stealing the funds in that output. As shown in A. Poelstra, "CAT and Schnorr Tricks II", 2021, https://www.wpsoftware.net/andrew/blog/cat-and-schnorr-tricks-ii.html OP_CAT is sufficent to build vaults in Bitcoin. * Replicating CheckSigFromStack A. Poelstra, "CAT and Schnorr Tricks I", 2021, https://medium.com/blockstream/cat-and-schnorr-tricks-i-faf1b59bd298 which would allow the creation of simple covenants and other advanced contracts without having to presign spending transactions, possibly reducing complexity and the amount of data that needs to be stored. Originally shown to work with Schnorr signatures, this result has been extended to ECDSA signatures R. Linus, "Covenants with CAT and ECDSA", 2023, https://gist.github.com/RobinLinus/9a69f5552be94d13170ec79bf34d5e85#file-covenants_cat_ecdsa-md. -The opcode OP_CAT was available in early versions of Bitcoin. However OP_CAT was removed because it enabled the construction of a script for which an evaluation could have memory usage exponential in the size of the script. +The opcode OP_CAT was available in early versions of Bitcoin. However OP_CAT was removed because it enabled the construction of a script whose evaluation could have memory usage exponential in the size of the script. For instance a script which pushed a 1 Byte value on the stack and then repeated the opcodes OP_DUP, OP_CAT 40 times would result in a stack value whose size was greater than 1 Terabyte. This is no longer an issue because tapscript enforces a maximum stack element size of 520 Bytes. ==Specification== From d4f85b11464a60961962960b306cac72461a977f Mon Sep 17 00:00:00 2001 From: Ethan Heilman Date: Fri, 15 Dec 2023 14:44:07 -0500 Subject: [PATCH 146/454] Lowercase bytes MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Co-authored-by: Vojtěch Strnad <43024885+vostrnad@users.noreply.github.com> --- bip-???-cat.mediawiki | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/bip-???-cat.mediawiki b/bip-???-cat.mediawiki index 92b2588e8a..ec4834a2e9 100644 --- a/bip-???-cat.mediawiki +++ b/bip-???-cat.mediawiki @@ -35,7 +35,7 @@ OP_CAT aims to expands the toolbox of the tapscript developer with a simple, mod * Replicating CheckSigFromStack A. Poelstra, "CAT and Schnorr Tricks I", 2021, https://medium.com/blockstream/cat-and-schnorr-tricks-i-faf1b59bd298 which would allow the creation of simple covenants and other advanced contracts without having to presign spending transactions, possibly reducing complexity and the amount of data that needs to be stored. Originally shown to work with Schnorr signatures, this result has been extended to ECDSA signatures R. Linus, "Covenants with CAT and ECDSA", 2023, https://gist.github.com/RobinLinus/9a69f5552be94d13170ec79bf34d5e85#file-covenants_cat_ecdsa-md. The opcode OP_CAT was available in early versions of Bitcoin. However OP_CAT was removed because it enabled the construction of a script whose evaluation could have memory usage exponential in the size of the script. -For instance a script which pushed a 1 Byte value on the stack and then repeated the opcodes OP_DUP, OP_CAT 40 times would result in a stack value whose size was greater than 1 Terabyte. This is no longer an issue because tapscript enforces a maximum stack element size of 520 Bytes. +For example, a script that pushed a 1-byte value on the stack and then repeated the opcodes OP_DUP, OP_CAT 40 times would result in a stack value whose size was greater than 1 terabyte. This is no longer an issue because tapscript enforces a maximum stack element size of 520 bytes. ==Specification== From beb5802cc6c5f28da1aeaf0f75eb59738a004fb9 Mon Sep 17 00:00:00 2001 From: Ethan Heilman Date: Fri, 15 Dec 2023 15:27:22 -0500 Subject: [PATCH 147/454] Adds subsection header MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Co-authored-by: Vojtěch Strnad <43024885+vostrnad@users.noreply.github.com> --- bip-???-cat.mediawiki | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/bip-???-cat.mediawiki b/bip-???-cat.mediawiki index ec4834a2e9..6a5c54a05a 100644 --- a/bip-???-cat.mediawiki +++ b/bip-???-cat.mediawiki @@ -41,7 +41,7 @@ For example, a script that pushed a 1-byte value on the stack and then repeated OP_CAT pops two elements off the stack, concatenates them together in stack order and pushes the resulting element onto the stack. Given the stack [x1,x2], where x2 is at the top of the stack, OP_CAT will push x1||x2 onto the stack. By '||' we denote concatenation. -Implementation +===Implementation===
 case OP_CAT:
 {

From 0a143d396910a49225c6fc2f487a968dc6e96035 Mon Sep 17 00:00:00 2001
From: Ethan Heilman 
Date: Fri, 15 Dec 2023 15:46:49 -0500
Subject: [PATCH 148/454] Use BSD-3 license

---
 bip-???-cat.mediawiki | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/bip-???-cat.mediawiki b/bip-???-cat.mediawiki
index 6a5c54a05a..61428e34c2 100644
--- a/bip-???-cat.mediawiki
+++ b/bip-???-cat.mediawiki
@@ -88,4 +88,4 @@ OP_CAT as it existed in the Bitcoin codebase prior to the commit "misc changes"
 We wish to acknowledge Dan Gould for encouraging and helping review this effort. 
 
 == Copyright ==
-This document is placed in the public domain.
+This document is licensed under the 3-clause BSD license.

From 82198302cd1d36f841f1bb6cd93c3c97ecbb8a31 Mon Sep 17 00:00:00 2001
From: Ethan Heilman 
Date: Fri, 15 Dec 2023 15:52:05 -0500
Subject: [PATCH 149/454] Code formatting
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit

Co-authored-by: Vojtěch Strnad <43024885+vostrnad@users.noreply.github.com>
---
 bip-???-cat.mediawiki | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/bip-???-cat.mediawiki b/bip-???-cat.mediawiki
index 61428e34c2..cd5b86a533 100644
--- a/bip-???-cat.mediawiki
+++ b/bip-???-cat.mediawiki
@@ -60,7 +60,7 @@ break;
 
This implementation is inspired by the original implementation of OP_CAT as shown below. An alternative implementation of OP_CAT can be found in Elements Roose S., Elements Project, "Re-enable several disabled opcodes", 2019, https://github.com/ElementsProject/elements/commit/13e1103abe3e328c5a4e2039b51a546f8be6c60a#diff-a0337ffd7259e8c7c9a7786d6dbd420c80abfa1afdb34ebae3261109d9ae3c19R740-R759. -The value of MAX_SCRIPT_ELEMENT_SIZE is 520 Bytes +The value of MAX_SCRIPT_ELEMENT_SIZE is 520. ==Notes== From 0b8a7e4b64458821d474fa08976a1d38d33d3004 Mon Sep 17 00:00:00 2001 From: Ethan Heilman Date: Fri, 15 Dec 2023 15:56:12 -0500 Subject: [PATCH 150/454] Code formatting MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Co-authored-by: Vojtěch Strnad <43024885+vostrnad@users.noreply.github.com> --- bip-???-cat.mediawiki | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/bip-???-cat.mediawiki b/bip-???-cat.mediawiki index cd5b86a533..d3af82f5ed 100644 --- a/bip-???-cat.mediawiki +++ b/bip-???-cat.mediawiki @@ -39,7 +39,7 @@ For example, a script that pushed a 1-byte value on the stack and then repeated ==Specification== -OP_CAT pops two elements off the stack, concatenates them together in stack order and pushes the resulting element onto the stack. Given the stack [x1,x2], where x2 is at the top of the stack, OP_CAT will push x1||x2 onto the stack. By '||' we denote concatenation. +OP_CAT pops two elements off the stack, concatenates them together in stack order and pushes the resulting element onto the stack. Given the stack _[x1, x2]_, where _x2_ is at the top of the stack, OP_CAT will push _x1 || x2_ onto the stack. By _||_ we denote concatenation. ===Implementation===

From 77509f6c23a6036a3e4ac929ab2fe7c6d8dbdeec Mon Sep 17 00:00:00 2001
From: Ethan Heilman 
Date: Fri, 15 Dec 2023 15:57:08 -0500
Subject: [PATCH 151/454] Period to colon
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit

Co-authored-by: Vojtěch Strnad <43024885+vostrnad@users.noreply.github.com>
---
 bip-???-cat.mediawiki | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/bip-???-cat.mediawiki b/bip-???-cat.mediawiki
index d3af82f5ed..707cf79719 100644
--- a/bip-???-cat.mediawiki
+++ b/bip-???-cat.mediawiki
@@ -64,7 +64,7 @@ The value of MAX_SCRIPT_ELEMENT_SIZE is 520.
 
 ==Notes==
 
-OP_CAT as it existed in the Bitcoin codebase prior to the commit "misc changes" 4bd188cS. Nakamoto, "misc changes", Aug 25 2010, https://github.com/bitcoin/bitcoin/commit/4bd188c4383d6e614e18f79dc337fbabe8464c82#diff-27496895958ca30c47bbb873299a2ad7a7ea1003a9faa96b317250e3b7aa1fefL381 which disabled it.
+OP_CAT as it existed in the Bitcoin codebase prior to the commit "misc changes" 4bd188cS. Nakamoto, "misc changes", Aug 25 2010, https://github.com/bitcoin/bitcoin/commit/4bd188c4383d6e614e18f79dc337fbabe8464c82#diff-27496895958ca30c47bbb873299a2ad7a7ea1003a9faa96b317250e3b7aa1fefL381 which disabled it:
 
 
   // (x1 x2 -- out)

From 4f39e4b9d55960432d5548fa7e52568d3051428a Mon Sep 17 00:00:00 2001
From: Ethan Heilman 
Date: Sat, 16 Dec 2023 16:23:49 -0500
Subject: [PATCH 152/454] Avoids designing or discussing how to add
 post-quantum commitments to Bitcoin

---
 bip-???-cat.mediawiki | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/bip-???-cat.mediawiki b/bip-???-cat.mediawiki
index 707cf79719..8709f7b607 100644
--- a/bip-???-cat.mediawiki
+++ b/bip-???-cat.mediawiki
@@ -29,7 +29,7 @@ OP_CAT aims to expands the toolbox of the tapscript developer with a simple, mod
 
 * Bitstream, a protocol for the atomic swap (fair exchange) of bitcoins for decryption keys, that enables decentralized file hosting systems paid in Bitcoin. While such swaps are currently possible on Bitcoin without OP_CAT they require the use of complex and computationally expensive Verifiable Computation cryptographic techniques. OP_CAT would remove this requirement on Verifiable Computation, making such protocols far more practical to build in Bitcoin. R. Linus, "BitStream: Decentralized File Hosting Incentivised via Bitcoin Payments", 2023, https://robinlinus.com/bitstream.pdf
 * Tree Signatures provide a multisignature script whose size can be logarithmic in the number of public keys and can encode spend conditions beyond n-of-m. For instance a transaction less than 1KB in size could support tree signatures with a thousand public keys. This also enables generalized logical spend conditions.  P. Wuille, "Multisig on steroids using tree signatures", 2015, https://blog.blockstream.com/en-treesignatures/
-* Post-Quantum Lamport Signatures in Bitcoin transactions. Lamport signatures merely require the ability to hash and concatenate values on the stack. J. Rubin, "[bitcoin-dev] OP_CAT Makes Bitcoin Quantum Secure [was CheckSigFromStack for Arithmetic Values]", 2021, https://lists.linuxfoundation.org/pipermail/bitcoin-dev/2021-July/019233.html
+* Post-Quantum Lamport Signatures in Bitcoin transactions. Lamport signatures merely require the ability to hash and concatenate values on the stack. J. Rubin, "[bitcoin-dev] OP_CAT Makes Bitcoin Quantum Secure [was CheckSigFromStack for Arithmetic Values]", 2021, https://lists.linuxfoundation.org/pipermail/bitcoin-dev/2021-July/019233.html It is an open question if the quantum resistance of Lamport Signatures can be preserved when used in a taproot output.
 * Non-equivocation contracts T. Ruffing, A. Kate, D. Schröder, "Liar, Liar, Coins on Fire: Penalizing Equivocation by Loss of Bitcoins", 2015, https://citeseerx.ist.psu.edu/viewdoc/download?doi=10.1.1.727.6262&rep=rep1&type=pdf in tapscript provide a mechanism to punish equivocation/double spending in Bitcoin payment channels. OP_CAT enables this by enforcing rules on the spending transaction's nonce. The capability is a useful building block for payment channels and other Bitcoin protocols.
 * Vaults M. Moser, I. Eyal, and E. G. Sirer, Bitcoin Covenants, http://fc16.ifca.ai/bitcoin/papers/MES16.pdf which are a specialized covenant that allows a user to block a malicious party who has compromised the user's secret key from stealing the funds in that output. As shown in A. Poelstra, "CAT and Schnorr Tricks II", 2021, https://www.wpsoftware.net/andrew/blog/cat-and-schnorr-tricks-ii.html OP_CAT is sufficent to build vaults in Bitcoin.
 * Replicating CheckSigFromStack A. Poelstra, "CAT and Schnorr Tricks I", 2021, https://medium.com/blockstream/cat-and-schnorr-tricks-i-faf1b59bd298 which would allow the creation of simple covenants and other advanced contracts without having to presign spending transactions, possibly reducing complexity and the amount of data that needs to be stored. Originally shown to work with Schnorr signatures, this result has been extended to ECDSA signatures R. Linus, "Covenants with CAT and ECDSA", 2023, https://gist.github.com/RobinLinus/9a69f5552be94d13170ec79bf34d5e85#file-covenants_cat_ecdsa-md.

From 97635f5c094709dd18f4afee017e33face886f5b Mon Sep 17 00:00:00 2001
From: Ethan Heilman 
Date: Sun, 17 Dec 2023 12:49:46 -0500
Subject: [PATCH 153/454] Lowercase the signatures

---
 bip-???-cat.mediawiki | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)

diff --git a/bip-???-cat.mediawiki b/bip-???-cat.mediawiki
index 8709f7b607..68c24c962a 100644
--- a/bip-???-cat.mediawiki
+++ b/bip-???-cat.mediawiki
@@ -28,8 +28,8 @@ Bitcoin tapscript lacks a general purpose way of combining objects on the stack
 OP_CAT aims to expands the toolbox of the tapscript developer with a simple, modular and useful opcode in the spirit of Unix R. Pike and B. Kernighan, "Program design in the UNIX environment", 1983, https://harmful.cat-v.org/cat-v/unix_prog_design.pdf. To demonstrate the usefulness of OP_CAT below we provide a non-exhaustive list of some usecases that OP_CAT would enable:
 
 * Bitstream, a protocol for the atomic swap (fair exchange) of bitcoins for decryption keys, that enables decentralized file hosting systems paid in Bitcoin. While such swaps are currently possible on Bitcoin without OP_CAT they require the use of complex and computationally expensive Verifiable Computation cryptographic techniques. OP_CAT would remove this requirement on Verifiable Computation, making such protocols far more practical to build in Bitcoin. R. Linus, "BitStream: Decentralized File Hosting Incentivised via Bitcoin Payments", 2023, https://robinlinus.com/bitstream.pdf
-* Tree Signatures provide a multisignature script whose size can be logarithmic in the number of public keys and can encode spend conditions beyond n-of-m. For instance a transaction less than 1KB in size could support tree signatures with a thousand public keys. This also enables generalized logical spend conditions.  P. Wuille, "Multisig on steroids using tree signatures", 2015, https://blog.blockstream.com/en-treesignatures/
-* Post-Quantum Lamport Signatures in Bitcoin transactions. Lamport signatures merely require the ability to hash and concatenate values on the stack. J. Rubin, "[bitcoin-dev] OP_CAT Makes Bitcoin Quantum Secure [was CheckSigFromStack for Arithmetic Values]", 2021, https://lists.linuxfoundation.org/pipermail/bitcoin-dev/2021-July/019233.html It is an open question if the quantum resistance of Lamport Signatures can be preserved when used in a taproot output.
+* Tree signatures provide a multisignature script whose size can be logarithmic in the number of public keys and can encode spend conditions beyond n-of-m. For instance a transaction less than 1KB in size could support tree signatures with a thousand public keys. This also enables generalized logical spend conditions.  P. Wuille, "Multisig on steroids using tree signatures", 2015, https://blog.blockstream.com/en-treesignatures/
+* Post-Quantum Lamport signatures in Bitcoin transactions. Lamport signatures merely require the ability to hash and concatenate values on the stack. J. Rubin, "[bitcoin-dev] OP_CAT Makes Bitcoin Quantum Secure [was CheckSigFromStack for Arithmetic Values]", 2021, https://lists.linuxfoundation.org/pipermail/bitcoin-dev/2021-July/019233.html It is an open question if the quantum resistance of Lamport signatures can be preserved when used in a taproot output.
 * Non-equivocation contracts T. Ruffing, A. Kate, D. Schröder, "Liar, Liar, Coins on Fire: Penalizing Equivocation by Loss of Bitcoins", 2015, https://citeseerx.ist.psu.edu/viewdoc/download?doi=10.1.1.727.6262&rep=rep1&type=pdf in tapscript provide a mechanism to punish equivocation/double spending in Bitcoin payment channels. OP_CAT enables this by enforcing rules on the spending transaction's nonce. The capability is a useful building block for payment channels and other Bitcoin protocols.
 * Vaults M. Moser, I. Eyal, and E. G. Sirer, Bitcoin Covenants, http://fc16.ifca.ai/bitcoin/papers/MES16.pdf which are a specialized covenant that allows a user to block a malicious party who has compromised the user's secret key from stealing the funds in that output. As shown in A. Poelstra, "CAT and Schnorr Tricks II", 2021, https://www.wpsoftware.net/andrew/blog/cat-and-schnorr-tricks-ii.html OP_CAT is sufficent to build vaults in Bitcoin.
 * Replicating CheckSigFromStack A. Poelstra, "CAT and Schnorr Tricks I", 2021, https://medium.com/blockstream/cat-and-schnorr-tricks-i-faf1b59bd298 which would allow the creation of simple covenants and other advanced contracts without having to presign spending transactions, possibly reducing complexity and the amount of data that needs to be stored. Originally shown to work with Schnorr signatures, this result has been extended to ECDSA signatures R. Linus, "Covenants with CAT and ECDSA", 2023, https://gist.github.com/RobinLinus/9a69f5552be94d13170ec79bf34d5e85#file-covenants_cat_ecdsa-md.

From e3dc3ba3617d33dc1c434196f5f7b4e463254e49 Mon Sep 17 00:00:00 2001
From: Ethan Heilman 
Date: Sun, 17 Dec 2023 12:53:07 -0500
Subject: [PATCH 154/454] Italicize variables
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit

Co-authored-by: Vojtěch Strnad <43024885+vostrnad@users.noreply.github.com>
---
 bip-???-cat.mediawiki | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/bip-???-cat.mediawiki b/bip-???-cat.mediawiki
index 68c24c962a..334cc2022a 100644
--- a/bip-???-cat.mediawiki
+++ b/bip-???-cat.mediawiki
@@ -39,7 +39,7 @@ For example, a script that pushed a 1-byte value on the stack and then repeated
 
 ==Specification==
 
-OP_CAT pops two elements off the stack, concatenates them together in stack order and pushes the resulting element onto the stack. Given the stack _[x1, x2]_, where _x2_ is at the top of the stack, OP_CAT will push _x1 || x2_ onto the stack. By _||_ we denote concatenation.
+OP_CAT pops two elements off the stack, concatenates them together in stack order and pushes the resulting element onto the stack. Given the stack ''[x1, x2]'', where ''x2'' is at the top of the stack, OP_CAT will push ''x1 || x2'' onto the stack. By ''||'' we denote concatenation.
 
 ===Implementation===
 

From e492a90fec53ceb1839080024cc90a41ce503906 Mon Sep 17 00:00:00 2001
From: Ethan Heilman 
Date: Mon, 18 Dec 2023 20:28:22 -0500
Subject: [PATCH 155/454] Better reference for OP_CAT removal

---
 bip-???-cat.mediawiki | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/bip-???-cat.mediawiki b/bip-???-cat.mediawiki
index 334cc2022a..ea2213dd0a 100644
--- a/bip-???-cat.mediawiki
+++ b/bip-???-cat.mediawiki
@@ -64,7 +64,7 @@ The value of MAX_SCRIPT_ELEMENT_SIZE is 520.
 
 ==Notes==
 
-OP_CAT as it existed in the Bitcoin codebase prior to the commit "misc changes" 4bd188cS. Nakamoto, "misc changes", Aug 25 2010, https://github.com/bitcoin/bitcoin/commit/4bd188c4383d6e614e18f79dc337fbabe8464c82#diff-27496895958ca30c47bbb873299a2ad7a7ea1003a9faa96b317250e3b7aa1fefL381 which disabled it:
+[OP_CAT as it existed in the Bitcoin codebase](https://github.com/bitcoin/bitcoin/blob/01cd2fdaf3ac6071304ceb80fb7436ac02b1059e/script.cpp#L381-L393) prior to the commit "misc changes" 4bd188cS. Nakamoto, "misc changes", Aug 25 2010, https://github.com/bitcoin/bitcoin/commit/4bd188c4383d6e614e18f79dc337fbabe8464c82#diff-27496895958ca30c47bbb873299a2ad7a7ea1003a9faa96b317250e3b7aa1fefR94 which disabled it:
 
 
   // (x1 x2 -- out)

From 3671465ce62f91c6e115ec870b2b66e91b0cac43 Mon Sep 17 00:00:00 2001
From: momodaka <463435681@qq.com>
Date: Thu, 9 Nov 2023 21:06:22 +0800
Subject: [PATCH 156/454] Update BIP-380: fix typo

revert: fix
---
 bip-0380.mediawiki | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)

diff --git a/bip-0380.mediawiki b/bip-0380.mediawiki
index 48dd93f9e8..3f17755883 100644
--- a/bip-0380.mediawiki
+++ b/bip-0380.mediawiki
@@ -26,7 +26,7 @@ This BIP is licensed under the BSD 2-clause license.
 
 Bitcoin wallets traditionally have stored a set of keys which are later serialized and mutated to produce the output scripts that the wallet watches and the addresses it provides to users.
 Typically backups have consisted of solely the private keys, nowadays primarily in the form of BIP 39 mnemonics.
-However this backup solution is insuffient, especially since the introduction of Segregated Witness which added new output types.
+However this backup solution is insufficient, especially since the introduction of Segregated Witness which added new output types.
 Given just the private keys, it is not possible for restored wallets to know which kinds of output scripts and addresses to produce.
 This has lead to incompatibilities between wallets when restoring a backup or exporting data for a watch only wallet.
 
@@ -238,7 +238,7 @@ Valid expressions:
 * Extended private key with hardened derivation and children: xprvA1RpRA33e1JQ7ifknakTFpgNXPmW2YvmhqLQYMmrj4xJXXWYpDPS3xz7iAxn8L39njGVyuoseXzU6rcxFLJ8HFsTjSyQbLYnMpCqE2VbFWc/3h/4h/5h/*h
 * Extended private key with key origin, hardened derivation and children: [deadbeef/0h/1h/2]xprvA1RpRA33e1JQ7ifknakTFpgNXPmW2YvmhqLQYMmrj4xJXXWYpDPS3xz7iAxn8L39njGVyuoseXzU6rcxFLJ8HFsTjSyQbLYnMpCqE2VbFWc/3h/4h/5h/*h
 
-Invalid expressiosn:
+Invalid expression:
 
 * Children indicator in key origin: [deadbeef/0h/0h/0h/*]0260b2003c386519fc9eadf2b5cf124dd8eea4c4e68d5e154050a9346ea98ce600
 * Trailing slash in key origin: [deadbeef/0h/0h/0h/]0260b2003c386519fc9eadf2b5cf124dd8eea4c4e68d5e154050a9346ea98ce600

From 785b11e8616cf0a15cb19107c0dba7e2b80ffd53 Mon Sep 17 00:00:00 2001
From: Armin Sabouri 
Date: Fri, 29 Dec 2023 12:14:45 -0500
Subject: [PATCH 157/454] Add backwards compatibility section

---
 bip-???-cat.mediawiki | 3 +++
 1 file changed, 3 insertions(+)

diff --git a/bip-???-cat.mediawiki b/bip-???-cat.mediawiki
index ea2213dd0a..8efe002d7e 100644
--- a/bip-???-cat.mediawiki
+++ b/bip-???-cat.mediawiki
@@ -79,6 +79,9 @@ The value of MAX_SCRIPT_ELEMENT_SIZE is 520.
   }
 
+==Backwards Compatibility== +OP_CAT usage in any Non-SegWitV1 script will continue to trigger the SCRIPT_ERR_DISABLED_OPCODE. + ==References== From 82fe9fc3dba07d51533dbce4de4b5eb58ddbed55 Mon Sep 17 00:00:00 2001 From: Ethan Heilman Date: Fri, 29 Dec 2023 18:29:00 -0500 Subject: [PATCH 158/454] specify the hex value of the opcode --- bip-???-cat.mediawiki | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/bip-???-cat.mediawiki b/bip-???-cat.mediawiki index 8efe002d7e..6ae466e8a6 100644 --- a/bip-???-cat.mediawiki +++ b/bip-???-cat.mediawiki @@ -13,7 +13,7 @@ ==Abstract== -This BIP reintroduces OP_CAT in the form of a new tapscript opcode which allows the concatenation of two values on the stack. This opcode would be activated via a soft fork by redefining the opcode OP_SUCCESS126. +This BIP reintroduces OP_CAT in the form of a new tapscript opcode which allows the concatenation of two values on the stack. This opcode would be activated via a soft fork by redefining the opcode OP_SUCCESS126 (the opcode 0x7e). When evaluated the OP_CAT instruction: # Pops the top two values off the stack, From c2cec65937881131bcaa45b52de6e1fbce5433d5 Mon Sep 17 00:00:00 2001 From: James O'Beirne Date: Wed, 3 Jan 2024 15:33:50 -0500 Subject: [PATCH 159/454] fixup! rename `n-pushes` -> `push-count` --- bip-0345.mediawiki | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/bip-0345.mediawiki b/bip-0345.mediawiki index 73b265e5db..2bcf7bd4a0 100644 --- a/bip-0345.mediawiki +++ b/bip-0345.mediawiki @@ -231,8 +231,8 @@ When evaluating OP_VAULT (OP_SUCCESS187, - -[ n leaf-update script data items ... ] + +[ leaf-update script data items ... ] @@ -243,12 +243,12 @@ where * is a minimally-encoded data push of a serialized script. In conjunction with the leaf-update data items, it dictates the tapleaf script in the output taptree that will replace the one currently executing. ** Otherwise, script execution MUST fail and terminate immediately. -* is an up to 4-byte CScriptNum-encoded number indicating how many leaf-update script items should be popped off the stack. '''Why only prepending with data pushes?''' Prepending the leaf-update-script-body with opcodes opens up the door to prepending OP_SUCCESSX opcodes, to name a single issue only, side-stepping the validation that was meant to be run by the committed script. +* is an up to 4-byte CScriptNum-encoded number indicating how many leaf-update script items should be popped off the stack. '''Why only prepending with data pushes?''' Prepending the leaf-update-script-body with opcodes opens up the door to prepending OP_SUCCESSX opcodes, to name a single issue only, side-stepping the validation that was meant to be run by the committed script. ** If this value does not decode to a valid CScriptNum, script execution when spending this output MUST fail and terminate immediately. ** If this value is less than 0, script execution when spending this output MUST fail and terminate immediately. -** If there are fewer than 3 items following the items on the stack, script execution when spending this output MUST fail and terminate immediately. In other words, after popping , there must be at least 3 + items remaining on the stack. +** If there are fewer than 3 items following the items on the stack, script execution when spending this output MUST fail and terminate immediately. In other words, after popping , there must be at least 3 + items remaining on the stack. -* The following stack items are popped off the stack and prefixed as minimally-encoded push-data arguments to the to construct the expected tapleaf replacement script. +* The following stack items are popped off the stack and prefixed as minimally-encoded push-data arguments to the to construct the expected tapleaf replacement script. * is an up to 4-byte CScriptNum-encoded number indicating the index of the output which, in conjunction with an optional revault output, carries forward the value of this input, and has an identical taptree aside from the currently executing leaf. ** If this value does not decode to a valid CScriptNum, script execution when spending this output MUST fail and terminate immediately. @@ -269,7 +269,7 @@ After the stack is parsed, the following validation checks are performed: * Decrement the per-script sigops budget (see [https://github.com/bitcoin/bips/blob/master/bip-0342.mediawiki#user-content-Resource_limits BIP-0342]) by 60'''Why is the sigops cost for OP_VAULT set to 60?''' To determine the validity of a trigger output, OP_VAULT must perform an EC multiplication and hashing proportional to the length of the control block in order to generate the output's expected TapTweak. This has been measured to have a cost in the worst case (max length control block) of roughly twice a Schnorr verification. Because the hashing cost could be mitigated by caching midstate, the cost is 60 and not 100.; if the budget is brought below zero, script execution MUST fail and terminate immediately. * Let the output designated by be called ''triggerOut''. * If the scriptPubKey of ''triggerOut'' is not a version 1 witness program, script execution MUST fail and terminate immediately. -* Let the script constructed by taking the and prefixing it with minimally-encoded data pushes of the leaf-update script data items be called the ''leaf-update-script''. +* Let the script constructed by taking the and prefixing it with minimally-encoded data pushes of the leaf-update script data items be called the ''leaf-update-script''. ** Note: the leaf-update data items will be in the same order in the ''leaf-update-script'' as they appeared on the stack. * If the scriptPubKey of ''triggerOut'' does not match that of a taptree that is identical to that of the currently evaluated input, but with the leaf script substituted for ''leaf-update-script'', script execution when spending this output MUST fail and terminate immediately. ** Note: the parity bit of the resulting taproot output is allowed to vary, so both values for the new output must be checked. From 327025b369ea5c1623e7695e4b7b79d4a79e733e Mon Sep 17 00:00:00 2001 From: James O'Beirne Date: Wed, 3 Jan 2024 16:11:50 -0500 Subject: [PATCH 160/454] fixup! misc. feedback from AJ and twhit223 --- bip-0345.mediawiki | 48 +++++++++++++++++++++++----------------------- 1 file changed, 24 insertions(+), 24 deletions(-) diff --git a/bip-0345.mediawiki b/bip-0345.mediawiki index 2bcf7bd4a0..d57610b795 100644 --- a/bip-0345.mediawiki +++ b/bip-0345.mediawiki @@ -243,26 +243,27 @@ where * is a minimally-encoded data push of a serialized script. In conjunction with the leaf-update data items, it dictates the tapleaf script in the output taptree that will replace the one currently executing. ** Otherwise, script execution MUST fail and terminate immediately. -* is an up to 4-byte CScriptNum-encoded number indicating how many leaf-update script items should be popped off the stack. '''Why only prepending with data pushes?''' Prepending the leaf-update-script-body with opcodes opens up the door to prepending OP_SUCCESSX opcodes, to name a single issue only, side-stepping the validation that was meant to be run by the committed script. -** If this value does not decode to a valid CScriptNum, script execution when spending this output MUST fail and terminate immediately. -** If this value is less than 0, script execution when spending this output MUST fail and terminate immediately. -** If there are fewer than 3 items following the items on the stack, script execution when spending this output MUST fail and terminate immediately. In other words, after popping , there must be at least 3 + items remaining on the stack. +* is an up to 4-byte minimally encoded CScriptNum indicating how many leaf-update script items should be popped off the stack. '''Why only prefix with data pushes?''' Prefixing the leaf-update-script-body with opcodes opens up the door to prefix OP_SUCCESSX opcodes, to name a single issue only, side-stepping the validation that was meant to be run by the committed script. +** If this value does not decode to a valid CScriptNum, script execution MUST fail and terminate immediately. +** If this value is less than 0, script execution MUST fail and terminate immediately. +** If there are fewer than 3 items following the items on the stack, script execution MUST fail and terminate immediately. In other words, after popping , there must be at least 3 + items remaining on the stack. * The following stack items are popped off the stack and prefixed as minimally-encoded push-data arguments to the to construct the expected tapleaf replacement script. -* is an up to 4-byte CScriptNum-encoded number indicating the index of the output which, in conjunction with an optional revault output, carries forward the value of this input, and has an identical taptree aside from the currently executing leaf. -** If this value does not decode to a valid CScriptNum, script execution when spending this output MUST fail and terminate immediately. -** If this value is less than 0 or is greater than or equal to the number of outputs, script execution when spending this output MUST fail and terminate immediately. +* is an up to 4-byte minimally encoded CScriptNum indicating the index of the output which, in conjunction with an optional revault output, carries forward the value of this input, and has an identical taptree aside from the currently executing leaf. +** If this value does not decode to a valid CScriptNum, script execution MUST fail and terminate immediately. +** If this value is less than 0 or is greater than or equal to the number of outputs, script execution MUST fail and terminate immediately. -* is an up to 4-byte CScriptNum-encoded number optionally indicating the index of an output which, in conjunction with the trigger output, carries forward the value of this input, and has an identical scriptPubKey to the current input. -** If this value does not decode to a valid CScriptNum, script execution when spending this output MUST fail and terminate immediately. -** If this value is greater than or equal to the number of outputs, script execution when spending this output MUST fail and terminate immediately. -** If this value is negative and not equal to -1, script execution when spending this output MUST fail and terminate immediately.'''Why is -1 the only allowable negative value for revault-vout-idx?''' A negative revault index indicates that no revault output exists; if this value were allowed to be any negative number, the witness could be malleated (and bloated) while a transaction is waiting for confirmation. +* is an up to 4-byte minimally encoded CScriptNum optionally indicating the index of an output which, in conjunction with the trigger output, carries forward the value of this input, and has an identical scriptPubKey to the current input. +** If this value does not decode to a valid CScriptNum, script execution MUST fail and terminate immediately. +** If this value is greater than or equal to the number of outputs, script execution MUST fail and terminate immediately. +** If this value is negative and not equal to -1, script execution MUST fail and terminate immediately.'''Why is -1 the only allowable negative value for revault-vout-idx?''' A negative revault index indicates that no revault output exists; if this value were allowed to be any negative number, the witness could be malleated (and bloated) while a transaction is waiting for confirmation. -* is an up to 7-byte CScriptNum-encoded number indicating the number of satoshis being revaulted. -** If this value does not decode to a valid CScriptNum, script execution when spending this output MUST fail and terminate immediately. -** If this value is not greater than or equal to 0, script execution when spending this output MUST fail and terminate immediately. -** If this value is non-zero but is negative, script execution when spending this output MUST fail and terminate immediately. +* is an up to 7-byte minimally encoded CScriptNum indicating the number of satoshis being revaulted. +** If this value does not decode to a valid CScriptNum, script execution MUST fail and terminate immediately. +** If this value is not greater than or equal to 0, script execution MUST fail and terminate immediately. +** If this value is non-zero but is negative, script execution MUST fail and terminate immediately. +** If this value is zero but is not -1, script execution MUST fail and terminate immediately. After the stack is parsed, the following validation checks are performed: @@ -270,12 +271,11 @@ After the stack is parsed, the following validation checks are performed: * Let the output designated by be called ''triggerOut''. * If the scriptPubKey of ''triggerOut'' is not a version 1 witness program, script execution MUST fail and terminate immediately. * Let the script constructed by taking the and prefixing it with minimally-encoded data pushes of the leaf-update script data items be called the ''leaf-update-script''. -** Note: the leaf-update data items will be in the same order in the ''leaf-update-script'' as they appeared on the stack. -* If the scriptPubKey of ''triggerOut'' does not match that of a taptree that is identical to that of the currently evaluated input, but with the leaf script substituted for ''leaf-update-script'', script execution when spending this output MUST fail and terminate immediately. +* If the scriptPubKey of ''triggerOut'' does not match that of a taptree that is identical to that of the currently evaluated input, but with the leaf script substituted for ''leaf-update-script'', script execution MUST fail and terminate immediately. ** Note: the parity bit of the resulting taproot output is allowed to vary, so both values for the new output must be checked. * Let the output designated by (if the index value is non-negative) be called ''revaultOut''. -* If the scriptPubKey of ''revaultOut'' is not equal to the scriptPubKey of the input being spent, script execution when spending this output MUST fail and terminate immediately. -* Implemetation recommendation: if the sum of the amounts of ''triggerOut'' and ''revaultOut'' (if any) are not greater than or equal to the value of this input, script execution when spending this output SHOULD fail and terminate immediately. +* If the scriptPubKey of ''revaultOut'' is not equal to the scriptPubKey of the input being spent, script execution MUST fail and terminate immediately. +* Implementation recommendation: if the sum of the amounts of ''triggerOut'' and ''revaultOut'' (if any) are not greater than or equal to the value of this input, script execution SHOULD fail and terminate immediately. This ensures that (at a minimum) the vaulted value for this input is carried through. ** Amount checks are ultimately done with deferred checks, but this check can help short-circuit obviously invalid spends. * Queue a deferred check'''What is a deferred check and why does this proposal require them for correct script evaluation?''' A deferred check is a validation check that is executed only after all input scripts have been validated, and is based on aggregate information collected during each input's EvalScript run.

Currently, the validity of each input is (usually) checked concurrently across all inputs in a transaction. Because this proposal allows batching the spend of multiple vault inputs into a single recovery or withdrawal output, we need a mechanism to ensure that all expected values per output can be summed and then checked. This necessitates the introduction of an "aggregating" set of checks which can only be executed after each input's script is evaluated. Note that similar functionality would be required for batch input validation or cross-input signature aggregation.
that ensures the satoshis for this input's nValue minus are included within the output nValue found at . * Queue a deferred check that ensures satoshis, if non-zero, are included within the output's nValue found at . @@ -296,15 +296,15 @@ When evaluating OP_VAULT_RECOVER (OP_SUCCESS188, where * is a 32-byte data push. -** If this is not 32 bytes in length, script execution when spending this output MUST fail and terminate immediately. -* is an up to 4-byte CScriptNum-encoded number indicating the index of the recovery output. -** If this value does not decode to a valid CScriptNum, script execution when spending this output MUST fail and terminate immediately. -** If this value is less than 0 or is greater than or equal to the number of outputs, script execution when spending this output MUST fail and terminate immediately. +** If this is not 32 bytes in length, script execution MUST fail and terminate immediately. +* is an up to 4-byte minimally encoded CScriptNum indicating the index of the recovery output. +** If this value does not decode to a valid CScriptNum, script execution MUST fail and terminate immediately. +** If this value is less than 0 or is greater than or equal to the number of outputs, script execution MUST fail and terminate immediately. After the stack is parsed, the following validation checks are performed: * Let the output at index be called ''recoveryOut''. -* If the scriptPubKey of ''recoveryOut'' does not have a tagged hash equal to (tagged_hash("VaultRecoverySPK", recoveryOut.scriptPubKey) == recovery-sPK-hash, where tagged_hash() is from the [https://github.com/bitcoin/bips/blob/master/bip-0340/reference.py BIP-0340 reference code]), script execution when spending this output MUST fail and terminate immediately. +* If the scriptPubKey of ''recoveryOut'' does not have a tagged hash equal to (tagged_hash("VaultRecoverySPK", recoveryOut.scriptPubKey) == recovery-sPK-hash, where tagged_hash() is from the [https://github.com/bitcoin/bips/blob/master/bip-0340/reference.py BIP-0340 reference code]), script execution MUST fail and terminate immediately. ** Implementation recommendation: if ''recoveryOut'' does not have an nValue greater than or equal to this input's amount, the script SHOULD fail and terminate immediately. * Queue a deferred check that ensures the nValue of ''recoveryOut'' contains the entire nValue of this input.'''How do recovery transactions pay for fees?''' If the recovery is unauthorized, fees are attached either via CPFP with an ephemeral anchor or as inputs which are solely spent to fees (i.e. no change output). If the recovery is authorized, fees can be attached in any manner, e.g. unrelated inputs and outputs or CPFP via anchor. ** This deferred check could be characterized in terms of the pseudocode below as RecoveryCheck(, input_amount). From de9ef59307f5d94883eefd2c6691c67d358d915a Mon Sep 17 00:00:00 2001 From: James O'Beirne Date: Wed, 3 Jan 2024 16:12:17 -0500 Subject: [PATCH 161/454] fixup! remove unused diagram --- bip-0345/batch-sweep.drawio.png | Bin 62296 -> 0 bytes 1 file changed, 0 insertions(+), 0 deletions(-) delete mode 100644 bip-0345/batch-sweep.drawio.png diff --git a/bip-0345/batch-sweep.drawio.png b/bip-0345/batch-sweep.drawio.png deleted file mode 100644 index 8f142545793e10484148d50abffc7066a4510c2c..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 62296 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%0Df84U&UeU(b*=co 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
}q2Cf7sc+g>-iR9ziC6tq28_xtBz|^ttE5Zs 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 Date: Sun, 7 Jan 2024 13:24:04 -0500 Subject: [PATCH 162/454] add clarifying note about the current opcode And some grammar + spelling cleanup --- bip-???-cat.mediawiki | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) diff --git a/bip-???-cat.mediawiki b/bip-???-cat.mediawiki index 6ae466e8a6..59f13802a4 100644 --- a/bip-???-cat.mediawiki +++ b/bip-???-cat.mediawiki @@ -14,6 +14,7 @@ ==Abstract== This BIP reintroduces OP_CAT in the form of a new tapscript opcode which allows the concatenation of two values on the stack. This opcode would be activated via a soft fork by redefining the opcode OP_SUCCESS126 (the opcode 0x7e). +Note that the currently disabled opcode also uses `0x7e` in a non-tapscript context and will continue to be disabled. When evaluated the OP_CAT instruction: # Pops the top two values off the stack, @@ -25,21 +26,21 @@ OP_CAT fails if there are less than two values on the stack or if a concatenated ==Motivation== Bitcoin tapscript lacks a general purpose way of combining objects on the stack restricting the expressiveness and power of tapscript. This prevents among many other things the ability to construct and evaluate merkle trees and other hashed data structures in tapscript. OP_CAT by adding a general purpose way to concatenate stack values would overcome this limitation and greatly increase the functionality of tapscript. -OP_CAT aims to expands the toolbox of the tapscript developer with a simple, modular and useful opcode in the spirit of Unix R. Pike and B. Kernighan, "Program design in the UNIX environment", 1983, https://harmful.cat-v.org/cat-v/unix_prog_design.pdf. To demonstrate the usefulness of OP_CAT below we provide a non-exhaustive list of some usecases that OP_CAT would enable: +OP_CAT aims to expand the toolbox of the tapscript developer with a simple, modular, and useful opcode in the spirit of Unix R. Pike and B. Kernighan, "Program design in the UNIX environment", 1983, https://harmful.cat-v.org/cat-v/unix_prog_design.pdf. To demonstrate the usefulness of OP_CAT below we provide a non-exhaustive list of some usecases that OP_CAT would enable: * Bitstream, a protocol for the atomic swap (fair exchange) of bitcoins for decryption keys, that enables decentralized file hosting systems paid in Bitcoin. While such swaps are currently possible on Bitcoin without OP_CAT they require the use of complex and computationally expensive Verifiable Computation cryptographic techniques. OP_CAT would remove this requirement on Verifiable Computation, making such protocols far more practical to build in Bitcoin. R. Linus, "BitStream: Decentralized File Hosting Incentivised via Bitcoin Payments", 2023, https://robinlinus.com/bitstream.pdf * Tree signatures provide a multisignature script whose size can be logarithmic in the number of public keys and can encode spend conditions beyond n-of-m. For instance a transaction less than 1KB in size could support tree signatures with a thousand public keys. This also enables generalized logical spend conditions. P. Wuille, "Multisig on steroids using tree signatures", 2015, https://blog.blockstream.com/en-treesignatures/ * Post-Quantum Lamport signatures in Bitcoin transactions. Lamport signatures merely require the ability to hash and concatenate values on the stack. J. Rubin, "[bitcoin-dev] OP_CAT Makes Bitcoin Quantum Secure [was CheckSigFromStack for Arithmetic Values]", 2021, https://lists.linuxfoundation.org/pipermail/bitcoin-dev/2021-July/019233.html It is an open question if the quantum resistance of Lamport signatures can be preserved when used in a taproot output. * Non-equivocation contracts T. Ruffing, A. Kate, D. Schröder, "Liar, Liar, Coins on Fire: Penalizing Equivocation by Loss of Bitcoins", 2015, https://citeseerx.ist.psu.edu/viewdoc/download?doi=10.1.1.727.6262&rep=rep1&type=pdf in tapscript provide a mechanism to punish equivocation/double spending in Bitcoin payment channels. OP_CAT enables this by enforcing rules on the spending transaction's nonce. The capability is a useful building block for payment channels and other Bitcoin protocols. -* Vaults M. Moser, I. Eyal, and E. G. Sirer, Bitcoin Covenants, http://fc16.ifca.ai/bitcoin/papers/MES16.pdf which are a specialized covenant that allows a user to block a malicious party who has compromised the user's secret key from stealing the funds in that output. As shown in A. Poelstra, "CAT and Schnorr Tricks II", 2021, https://www.wpsoftware.net/andrew/blog/cat-and-schnorr-tricks-ii.html OP_CAT is sufficent to build vaults in Bitcoin. +* Vaults M. Moser, I. Eyal, and E. G. Sirer, Bitcoin Covenants, http://fc16.ifca.ai/bitcoin/papers/MES16.pdf which are a specialized covenant that allows a user to block a malicious party who has compromised the user's secret key from stealing the funds in that output. As shown in A. Poelstra, "CAT and Schnorr Tricks II", 2021, https://www.wpsoftware.net/andrew/blog/cat-and-schnorr-tricks-ii.html OP_CAT is sufficient to build vaults in Bitcoin. * Replicating CheckSigFromStack A. Poelstra, "CAT and Schnorr Tricks I", 2021, https://medium.com/blockstream/cat-and-schnorr-tricks-i-faf1b59bd298 which would allow the creation of simple covenants and other advanced contracts without having to presign spending transactions, possibly reducing complexity and the amount of data that needs to be stored. Originally shown to work with Schnorr signatures, this result has been extended to ECDSA signatures R. Linus, "Covenants with CAT and ECDSA", 2023, https://gist.github.com/RobinLinus/9a69f5552be94d13170ec79bf34d5e85#file-covenants_cat_ecdsa-md. -The opcode OP_CAT was available in early versions of Bitcoin. However OP_CAT was removed because it enabled the construction of a script whose evaluation could have memory usage exponential in the size of the script. +The opcode OP_CAT was available in early versions of Bitcoin. However, OP_CAT was removed because it enabled the construction of a script whose evaluation could have memory usage exponential in the size of the script. For example, a script that pushed a 1-byte value on the stack and then repeated the opcodes OP_DUP, OP_CAT 40 times would result in a stack value whose size was greater than 1 terabyte. This is no longer an issue because tapscript enforces a maximum stack element size of 520 bytes. ==Specification== -OP_CAT pops two elements off the stack, concatenates them together in stack order and pushes the resulting element onto the stack. Given the stack ''[x1, x2]'', where ''x2'' is at the top of the stack, OP_CAT will push ''x1 || x2'' onto the stack. By ''||'' we denote concatenation. +OP_CAT pops two elements off the stack, concatenates them together in stack order, and pushes the resulting element onto the stack. Given the stack ''[x1, x2]'', where ''x2'' is at the top of the stack, OP_CAT will push ''x1 || x2'' onto the stack. By ''||'' we denote concatenation. ===Implementation===

From f9e100e9de0091be99d06b196a189733e9fe353d Mon Sep 17 00:00:00 2001
From: Ethan Heilman 
Date: Sun, 7 Jan 2024 16:34:23 -0500
Subject: [PATCH 163/454] Notes that the opcode used is the same as the
 original cat opcode

---
 bip-???-cat.mediawiki | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/bip-???-cat.mediawiki b/bip-???-cat.mediawiki
index 6ae466e8a6..ae73ed5813 100644
--- a/bip-???-cat.mediawiki
+++ b/bip-???-cat.mediawiki
@@ -13,7 +13,7 @@
 
 ==Abstract==
 
-This BIP reintroduces OP_CAT in the form of a new tapscript opcode which allows the concatenation of two values on the stack. This opcode would be activated via a soft fork by redefining the opcode OP_SUCCESS126 (the opcode 0x7e).
+This BIP reintroduces OP_CAT in the form of a new tapscript opcode which allows the concatenation of two values on the stack. This opcode would be activated via a soft fork by redefining the opcode OP_SUCCESS126 (126 in decimal and 0x7e in hexidecimal). This is same opcode value used by the original OP_CAT.
 
 When evaluated the OP_CAT instruction:
 # Pops the top two values off the stack,

From 2cec73a5b437cc4e3c108cb482de09b0e87edb8d Mon Sep 17 00:00:00 2001
From: Armin Sabouri 
Date: Sun, 7 Jan 2024 18:18:09 -0500
Subject: [PATCH 164/454] rm comment on disabled CAT opcode

---
 bip-???-cat.mediawiki | 1 -
 1 file changed, 1 deletion(-)

diff --git a/bip-???-cat.mediawiki b/bip-???-cat.mediawiki
index 59f13802a4..7b214d63ce 100644
--- a/bip-???-cat.mediawiki
+++ b/bip-???-cat.mediawiki
@@ -14,7 +14,6 @@
 ==Abstract==
 
 This BIP reintroduces OP_CAT in the form of a new tapscript opcode which allows the concatenation of two values on the stack. This opcode would be activated via a soft fork by redefining the opcode OP_SUCCESS126 (the opcode 0x7e).
-Note that the currently disabled opcode also uses `0x7e` in a non-tapscript context and will continue to be disabled.
 
 When evaluated the OP_CAT instruction:
 # Pops the top two values off the stack,

From 5dde7ea5cfe2b046dde7f9e7ecf40730f2005697 Mon Sep 17 00:00:00 2001
From: Armin Sabouri 
Date: Sun, 7 Jan 2024 18:18:46 -0500
Subject: [PATCH 165/454] revert changes to abstract

---
 bip-???-cat.mediawiki | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/bip-???-cat.mediawiki b/bip-???-cat.mediawiki
index 7b214d63ce..4875820a46 100644
--- a/bip-???-cat.mediawiki
+++ b/bip-???-cat.mediawiki
@@ -13,7 +13,7 @@
 
 ==Abstract==
 
-This BIP reintroduces OP_CAT in the form of a new tapscript opcode which allows the concatenation of two values on the stack. This opcode would be activated via a soft fork by redefining the opcode OP_SUCCESS126 (the opcode 0x7e).
+This BIP reintroduces OP_CAT in the form of a new tapscript opcode which allows the concatenation of two values on the stack. This opcode would be activated via a soft fork by redefining the opcode OP_SUCCESS126 (126 in decimal and 0x7e in hexidecimal). This is same opcode value used by the original OP_CAT.
 
 When evaluated the OP_CAT instruction:
 # Pops the top two values off the stack,

From 181875217114843e71f82adcc87dedf23611262d Mon Sep 17 00:00:00 2001
From: 2014 <116435491+5atoshiNakamoto@users.noreply.github.com>
Date: Mon, 29 Jan 2024 23:45:16 +0200
Subject: [PATCH 166/454] Update bip-0039-wordlists.md

typos, grammar, clarity
---
 bip-0039/bip-0039-wordlists.md | 14 +++++++-------
 1 file changed, 7 insertions(+), 7 deletions(-)

diff --git a/bip-0039/bip-0039-wordlists.md b/bip-0039/bip-0039-wordlists.md
index f2c173c58d..5acf87d1f1 100644
--- a/bip-0039/bip-0039-wordlists.md
+++ b/bip-0039/bip-0039-wordlists.md
@@ -53,7 +53,7 @@ Credits: @Kirvx @NicolasDorier @ecdsa @EricLarch
 7.  No words in the plural (except invariable words like "univers", or same spelling than singular like "heureux").
 8.  No female adjectives (except words with same spelling for male and female adjectives like "magique").
 9.  No words with several senses AND different spelling in speaking like "verre-vert", unless a word has a meaning much more popular than another like "perle" and "pairle".
-10. No very similar words with 1 letter of difference.
+10. No very similar words with only 1 letter of difference.
 11. No essentially reflexive verbs (unless a verb is also a noun like "souvenir").
 12. No words with "ô;â;ç;ê;œ;æ;î;ï;û;ù;à;ë;ÿ".
 13. No words ending by "é;ée;è;et;ai;ait".
@@ -93,12 +93,12 @@ Words chosen using the following rules:
 
 1.  Words are 4-8 letters long.
 2.  Words can be uniquely determined typing the first 4 letters.
-3.  Only words containing all letters without diacritical marks. (It was the hardest task, because in one third of all Czech letters has diacritical marks.)
+3.  Only words containing all letters without diacritical marks. (It was the hardest task, because one third of all Czech letters has diacritical marks.)
 4.  Only nouns, verbs and adverbs, no other word types. All words are in basic form.
 5.  No personal names or geographical names.
 6.  No very similar words with 1 letter of difference.
-7. Words are sorting according English alphabet (Czech sorting has difference in "ch").
-8.  No words already used in other language mnemonic sets (english, italian, french, spanish). Letters with diacritical marks from these sets are counted as analogous  letters without diacritical marks.
+7.  Words are sorted according to English alphabet (Czech sorting has difference in "ch").
+8.  No words already used in other language mnemonic sets (english, italian, french, spanish). Letters with diacritical marks from these sets are counted as analogous letters without diacritical marks.
 
 ### Portuguese
 
@@ -109,9 +109,9 @@ Credits: @alegotardo @bitmover-studio @brenorb @kuthullu @ninjastic @sabotag3x @
 3. No complex verb forms.
 4. No plural words, unless there's no singular form.
 5. No words with double spelling.
-6. No words with the exact sound of another word with different spelling.
+6. No words with the exact sound as another word with different spelling.
 7. No offensive words.
 8. No words already used in other language mnemonic sets.
 9. The words which have not the same spelling in Brazil and in Portugal are excluded.
-10. No words that remind negative/sad/bad things.
-11. No very similar words with 1 letter of difference.
+10. No words that remind one of negative/sad/bad things.
+11. No very similar words with only 1 letter of difference.

From eccf3db13963f1df625c1dd69fb73c6d29680c83 Mon Sep 17 00:00:00 2001
From: James O'Beirne 
Date: Fri, 23 Feb 2024 15:15:32 -0500
Subject: [PATCH 167/454] BIP-0345: add copyright

---
 bip-0345.mediawiki | 4 ++++
 1 file changed, 4 insertions(+)

diff --git a/bip-0345.mediawiki b/bip-0345.mediawiki
index d57610b795..a6ead3158d 100644
--- a/bip-0345.mediawiki
+++ b/bip-0345.mediawiki
@@ -26,6 +26,10 @@ an arbitrary destination, with the exception of a prespecified "recovery" path.
 At any time prior to final withdrawal, the coins can be spent to the
 recovery path.
 
+=== Copyright ===
+
+This document is licensed under the 3-clause BSD license.
+
 
 === Motivation ===
 

From b3701faef2bdb98a0d7ace4eedbeefa2da4c89ed Mon Sep 17 00:00:00 2001
From: Luke Dashjr 
Date: Fri, 23 Feb 2024 20:21:08 +0000
Subject: [PATCH 168/454] README: Update table

---
 README.mediawiki | 13 ++++++++++---
 1 file changed, 10 insertions(+), 3 deletions(-)

diff --git a/README.mediawiki b/README.mediawiki
index 6dbd798420..43e60a4093 100644
--- a/README.mediawiki
+++ b/README.mediawiki
@@ -434,7 +434,7 @@ Those proposing changes should consider that ultimately consent may rest with th
 | Eric Lombrozo
 | Standard
 | Rejected
-|-
+|- style="background-color: #cfffcf"
 | [[bip-0084.mediawiki|84]]
 | Applications
 | Derivation scheme for P2WPKH based accounts
@@ -487,7 +487,7 @@ Those proposing changes should consider that ultimately consent may rest with th
 | [[bip-0093.mediawiki|93]]
 | Applications
 | codex32: Checksummed SSSS-aware BIP32 seeds
-| Leon Olsson Curr, Pearlwort Sneed
+| Leon Olsson Curr, Pearlwort Sneed, Andrew Poelstra
 | Informational
 | Draft
 |-
@@ -627,7 +627,7 @@ Those proposing changes should consider that ultimately consent may rest with th
 | [[bip-0119.mediawiki|119]]
 | Consensus (soft fork)
 | CHECKTEMPLATEVERIFY
-| Jeremy Rubin
+| Jeremy Rubin, James O'Beirne
 | Standard
 | Draft
 |- style="background-color: #ffcfcf"
@@ -1072,6 +1072,13 @@ Those proposing changes should consider that ultimately consent may rest with th
 | Standard
 | Final
 |-
+| [[bip-0345.mediawiki|345]]
+| Consensus (soft fork)
+| OP_VAULT
+| James O'Beirne, Greg Sanders, Anthony Towns
+| Standard
+| Draft
+|- style="background-color: #cfffcf"
 | [[bip-0350.mediawiki|350]]
 | Applications
 | Bech32m format for v1+ witness addresses

From 55ec890fca8cc892f49be8d11898890cc8485f6d Mon Sep 17 00:00:00 2001
From: Luke Dashjr 
Date: Fri, 23 Feb 2024 23:03:27 +0000
Subject: [PATCH 169/454] Update for Google Groups ML

---
 bip-0002.mediawiki | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)

diff --git a/bip-0002.mediawiki b/bip-0002.mediawiki
index af8bb3090a..d4cb7e1fb4 100644
--- a/bip-0002.mediawiki
+++ b/bip-0002.mediawiki
@@ -32,13 +32,13 @@ The BIP process begins with a new idea for Bitcoin. Each potential BIP must have
 Small enhancements or patches to a particular piece of software often don't require standardisation between multiple projects; these don't need a BIP and should be injected into the relevant project-specific development workflow with a patch submission to the applicable issue tracker.
 Additionally, many ideas have been brought forward for changing Bitcoin that have been rejected for various reasons.
 The first step should be to search past discussions to see if an idea has been considered before, and if so, what issues arose in its progression.
-After investigating past work, the best way to proceed is by posting about the new idea to the [https://lists.linuxfoundation.org/mailman/listinfo/bitcoin-dev Bitcoin development mailing list].
+After investigating past work, the best way to proceed is by posting about the new idea to the [https://groups.google.com/g/bitcoindev Bitcoin development mailing list].
 
 Vetting an idea publicly before going as far as writing a BIP is meant to save both the potential author and the wider community time.
 Asking the Bitcoin community first if an idea is original helps prevent too much time being spent on something that is guaranteed to be rejected based on prior discussions (searching the internet does not always do the trick).
 It also helps to make sure the idea is applicable to the entire community and not just the author. Just because an idea sounds good to the author does not mean it will work for most people in most areas where Bitcoin is used.
 
-Once the champion has asked the Bitcoin community as to whether an idea has any chance of acceptance, a draft BIP should be presented to the [https://lists.linuxfoundation.org/mailman/listinfo/bitcoin-dev Bitcoin development mailing list].
+Once the champion has asked the Bitcoin community as to whether an idea has any chance of acceptance, a draft BIP should be presented to the [https://groups.google.com/g/bitcoindev Bitcoin development mailing list].
 This gives the author a chance to flesh out the draft BIP to make it properly formatted, of high quality, and to address additional concerns about the proposal.
 Following a discussion, the proposal should be submitted to the [https://github.com/bitcoin/bips BIPs git repository] as a pull request.
 This draft must be written in BIP style as described below, and named with an alias such as "bip-johndoe-infinitebitcoins" until an editor has assigned it a BIP number (authors MUST NOT self-assign BIP numbers).

From 79c1ec02a78aeaa9cf53da623e41363f92cff7bb Mon Sep 17 00:00:00 2001
From: Luke Dashjr 
Date: Fri, 23 Feb 2024 23:04:31 +0000
Subject: [PATCH 170/454] README: Update for Google Groups ML

---
 README.mediawiki | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/README.mediawiki b/README.mediawiki
index 43e60a4093..4ecc207b90 100644
--- a/README.mediawiki
+++ b/README.mediawiki
@@ -1,4 +1,4 @@
-People wishing to submit BIPs, first should propose their idea or document to the [https://lists.linuxfoundation.org/mailman/listinfo/bitcoin-dev bitcoin-dev@lists.linuxfoundation.org] mailing list (do not assign a number - read BIP 2 for the full process). After discussion, please open a PR. After copy-editing and acceptance, it will be published here.
+People wishing to submit BIPs, first should propose their idea or document to the [https://groups.google.com/g/bitcoindev bitcoindev@googlegroups.com] mailing list (do not assign a number - read BIP 2 for the full process). After discussion, please open a PR. After copy-editing and acceptance, it will be published here.
 
 We are fairly liberal with approving BIPs, and try not to be too involved in decision making on behalf of the community. The exception is in very rare cases of dispute resolution when a decision is contentious and cannot be agreed upon. In those cases, the conservative option will always be preferred.
 

From ddf5b25fc7f8009fa46ccb94f9ea73e85feffbf5 Mon Sep 17 00:00:00 2001
From: siv2r 
Date: Thu, 1 Feb 2024 11:14:27 +0530
Subject: [PATCH 171/454] bip327: fix broken links

---
 bip-0327.mediawiki | 8 ++++----
 1 file changed, 4 insertions(+), 4 deletions(-)

diff --git a/bip-0327.mediawiki b/bip-0327.mediawiki
index 07b40f53e7..b5600ab3a3 100644
--- a/bip-0327.mediawiki
+++ b/bip-0327.mediawiki
@@ -123,7 +123,7 @@ This is by design: All algorithms in this proposal handle multiple signers who (
 and applications are not required to check for duplicate individual public keys.
 In fact, applications are recommended to omit checks for duplicate individual public keys in order to simplify error handling.
 Moreover, it is often impossible to tell at key aggregation which signer is to blame for the duplicate, i.e., which signer came up with an individual public key honestly and which disruptive signer copied it.
-In contrast, MuSig2 is designed to identify disruptive signers at signing time (see [[#identifiying-disruptive-signers|Identifiying Disruptive Signers]]).
+In contrast, MuSig2 is designed to identify disruptive signers at signing time (see [[#identifying-disruptive-signers|Identifying Disruptive Signers]]).
 
 While the algorithms in this proposal are able to handle duplicate individual public keys, there are scenarios where applications may choose to abort when encountering duplicates.
 For example, we can imagine a scenario where a single entity creates a MuSig2 setup with multiple signing devices.
@@ -211,7 +211,7 @@ The bit can be obtained with ''GetPlainPubkey(keyagg_ctx)[0] & 1''.
 
 The following specification of the algorithms has been written with a focus on clarity.
 As a result, the specified algorithms are not always optimal in terms of computation and space.
-In particular, some values are recomputed but can be cached in actual implementations (see [[#signing-flow|Signing Flow]]).
+In particular, some values are recomputed but can be cached in actual implementations (see [[#general-signing-flow|General Signing Flow]]).
 
 === Notation ===
 
@@ -367,7 +367,7 @@ Algorithm ''ApplyTweak(keyagg_ctx, tweak, is_xonly_t)'':
 Algorithm ''NonceGen(sk, pk, aggpk, m, extra_in)'':
 * Inputs:
 ** The secret signing key ''sk'': a 32-byte array (optional argument)
-** The individual public key ''pk'': a 33-byte array (see [[#modifications-to-nonce-generation|Modifications to Nonce Generation]] for the reason that this argument is mandatory)
+** The individual public key ''pk'': a 33-byte array (see [[#signing-with-tweaked-individual-keys|Signing with Tweaked Individual Keys]] for the reason that this argument is mandatory)
 ** The x-only aggregate public key ''aggpk'': a 32-byte array (optional argument)
 ** The message ''m'': a byte array (optional argument)In theory, the allowed message size is restricted because SHA256 accepts byte strings only up to size of 2^61-1 bytes (and because of the 8-byte length encoding).
 ** The auxiliary input ''extra_in'': a byte array with ''0 ≤ len(extra_in) ≤ 232-1'' (optional argument)
@@ -465,7 +465,7 @@ Algorithm ''Sign(secnonce, sk, session_ctx)'':
 * Fail if ''pk ≠ secnonce[64:97]''
 * Let ''a = GetSessionKeyAggCoeff(session_ctx, P)''; fail if that failsFailing ''Sign'' when ''GetSessionKeyAggCoeff(session_ctx, P)'' fails is not necessary for unforgeability. It merely indicates to the caller that the scheme is not being used correctly.
 * Let ''g = 1'' if ''has_even_y(Q)'', otherwise let ''g = -1 mod n''
-* 
Let ''d = g⋅gacc⋅d' mod n'' (See [[negation-of-the-secret-key-when-signing|Negation Of The Secret Key When Signing]]) +*
Let ''d = g⋅gacc⋅d' mod n'' (See [[#negation-of-the-secret-key-when-signing|Negation Of The Secret Key When Signing]]) * Let ''s = (k1 + b⋅k2 + e⋅a⋅d) mod n'' * Let ''psig = bytes(32, s)'' * Let ''pubnonce = cbytes(k1'⋅G) || cbytes(k2'⋅G)'' From 5658236e6c9d9b39e99022674817925b18ea29d9 Mon Sep 17 00:00:00 2001 From: Pavol Rusnak Date: Mon, 18 Mar 2024 23:48:22 +0100 Subject: [PATCH 172/454] BIP-00{43,49,84}: move to Standards Track --- README.mediawiki | 6 +++--- bip-0043.mediawiki | 2 +- bip-0049.mediawiki | 2 +- bip-0084.mediawiki | 2 +- 4 files changed, 6 insertions(+), 6 deletions(-) diff --git a/README.mediawiki b/README.mediawiki index 43e60a4093..5379bbe094 100644 --- a/README.mediawiki +++ b/README.mediawiki @@ -235,7 +235,7 @@ Those proposing changes should consider that ultimately consent may rest with th | Applications | Purpose Field for Deterministic Wallets | Marek Palatinus, Pavol Rusnak -| Informational +| Standard | Final |- style="background-color: #ffffcf" | [[bip-0044.mediawiki|44]] @@ -270,7 +270,7 @@ Those proposing changes should consider that ultimately consent may rest with th | Applications | Derivation scheme for P2WPKH-nested-in-P2SH based accounts | Daniel Weigl -| Informational +| Standard | Final |- style="background-color: #cfffcf" | [[bip-0050.mediawiki|50]] @@ -439,7 +439,7 @@ Those proposing changes should consider that ultimately consent may rest with th | Applications | Derivation scheme for P2WPKH based accounts | Pavol Rusnak -| Informational +| Standard | Final |- | [[bip-0085.mediawiki|85]] diff --git a/bip-0043.mediawiki b/bip-0043.mediawiki index 32e02b1e63..f07c94aa11 100644 --- a/bip-0043.mediawiki +++ b/bip-0043.mediawiki @@ -7,7 +7,7 @@ Comments-Summary: No comments yet. Comments-URI: https://github.com/bitcoin/bips/wiki/Comments:BIP-0043 Status: Final - Type: Informational + Type: Standards Track Created: 2014-04-24
diff --git a/bip-0049.mediawiki b/bip-0049.mediawiki index 7d8d2c7496..a13b437b92 100644 --- a/bip-0049.mediawiki +++ b/bip-0049.mediawiki @@ -6,7 +6,7 @@ Comments-Summary: No comments yet. Comments-URI: https://github.com/bitcoin/bips/wiki/Comments:BIP-0049 Status: Final - Type: Informational + Type: Standards Track Created: 2016-05-19 License: PD
diff --git a/bip-0084.mediawiki b/bip-0084.mediawiki index 7f20217dcd..e1e458c83a 100644 --- a/bip-0084.mediawiki +++ b/bip-0084.mediawiki @@ -6,7 +6,7 @@ Comments-Summary: No comments yet. Comments-URI: https://github.com/bitcoin/bips/wiki/Comments:BIP-0084 Status: Final - Type: Informational + Type: Standards Track Created: 2017-12-28 License: CC0-1.0
From 0278bf3d7111bab8f0ef8dd08f16fd7b5ac6cbd6 Mon Sep 17 00:00:00 2001 From: Pavol Rusnak Date: Mon, 18 Mar 2024 23:48:44 +0100 Subject: [PATCH 173/454] BIP-0044: mark as Final --- README.mediawiki | 2 +- bip-0044.mediawiki | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/README.mediawiki b/README.mediawiki index 5379bbe094..ef51adb5f8 100644 --- a/README.mediawiki +++ b/README.mediawiki @@ -243,7 +243,7 @@ Those proposing changes should consider that ultimately consent may rest with th | Multi-Account Hierarchy for Deterministic Wallets | Marek Palatinus, Pavol Rusnak | Standard -| Proposed +| Final |- style="background-color: #ffffcf" | [[bip-0045.mediawiki|45]] | Applications diff --git a/bip-0044.mediawiki b/bip-0044.mediawiki index 4ddd56b2cc..5db540c70a 100644 --- a/bip-0044.mediawiki +++ b/bip-0044.mediawiki @@ -6,7 +6,7 @@ Pavol Rusnak Comments-Summary: Mixed review (one person) Comments-URI: https://github.com/bitcoin/bips/wiki/Comments:BIP-0044 - Status: Proposed + Status: Final Type: Standards Track Created: 2014-04-24
From b3493746b1a1208ddaae52682f98cdfff1e2d563 Mon Sep 17 00:00:00 2001 From: Armin Sabouri Date: Wed, 20 Mar 2024 18:33:02 -0400 Subject: [PATCH 174/454] update OP_CAT implementation --- bip-???-cat.mediawiki | 21 +++++++++------------ 1 file changed, 9 insertions(+), 12 deletions(-) diff --git a/bip-???-cat.mediawiki b/bip-???-cat.mediawiki index 4875820a46..111519d63d 100644 --- a/bip-???-cat.mediawiki +++ b/bip-???-cat.mediawiki @@ -43,18 +43,15 @@ OP_CAT pops two elements off the stack, concatenates them together in stack orde ===Implementation===
-case OP_CAT:
-{
-    if (stack.size() < 2) {
-        return set_error(serror, SCRIPT_ERR_INVALID_STACK_OPERATION);
-    }
-    valtype& vch1 = stacktop(-2);
-    valtype& vch2 = stacktop(-1);
-    if (vch1.size() + vch2.size() > MAX_SCRIPT_ELEMENT_SIZE) {
-        return set_error(serror, SCRIPT_ERR_INVALID_STACK_OPERATION);
-    }
-    vch1.insert(vch1.end(), vch2.begin(), vch2.end());
-    stack.pop_back();
+case OP_CAT: {
+  if (stack.size() < 2)
+    return set_error(serror, SCRIPT_ERR_INVALID_STACK_OPERATION);
+  valtype& vch1 = stacktop(-2);
+  valtype& vch2 = stacktop(-1);
+  if (vch1.size() + vch2.size() > MAX_SCRIPT_ELEMENT_SIZE)
+    return set_error(serror, SCRIPT_ERR_PUSH_SIZE);
+  vch1.insert(vch1.end(), vch2.begin(), vch2.end());
+  stack.pop_back();
 }
 break;
 
From ac231a17c2e6839d9af6576d9aa1c79fb8c16eca Mon Sep 17 00:00:00 2001 From: Ethan Heilman Date: Wed, 20 Mar 2024 23:53:53 -0400 Subject: [PATCH 175/454] Fixes broken mediawiki link --- bip-???-cat.mediawiki | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/bip-???-cat.mediawiki b/bip-???-cat.mediawiki index 111519d63d..1f803ba5c4 100644 --- a/bip-???-cat.mediawiki +++ b/bip-???-cat.mediawiki @@ -61,7 +61,7 @@ The value of MAX_SCRIPT_ELEMENT_SIZE is 520. ==Notes== -[OP_CAT as it existed in the Bitcoin codebase](https://github.com/bitcoin/bitcoin/blob/01cd2fdaf3ac6071304ceb80fb7436ac02b1059e/script.cpp#L381-L393) prior to the commit "misc changes" 4bd188cS. Nakamoto, "misc changes", Aug 25 2010, https://github.com/bitcoin/bitcoin/commit/4bd188c4383d6e614e18f79dc337fbabe8464c82#diff-27496895958ca30c47bbb873299a2ad7a7ea1003a9faa96b317250e3b7aa1fefR94 which disabled it: +[https://github.com/bitcoin/bitcoin/blob/01cd2fdaf3ac6071304ceb80fb7436ac02b1059e/script.cpp#L381-L393 OP_CAT as it existed in the Bitcoin codebase] prior to the commit "misc changes" 4bd188cS. Nakamoto, "misc changes", Aug 25 2010, https://github.com/bitcoin/bitcoin/commit/4bd188c4383d6e614e18f79dc337fbabe8464c82#diff-27496895958ca30c47bbb873299a2ad7a7ea1003a9faa96b317250e3b7aa1fefR94 which disabled it:
   // (x1 x2 -- out)

From c235aa493933dfff82ef3ba46a5e56eecb80d3c6 Mon Sep 17 00:00:00 2001
From: Ethan Heilman 
Date: Tue, 26 Mar 2024 20:36:19 -0400
Subject: [PATCH 176/454] Adds more acknowledgements

---
 bip-???-cat.mediawiki | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/bip-???-cat.mediawiki b/bip-???-cat.mediawiki
index 1f803ba5c4..3d3b73444f 100644
--- a/bip-???-cat.mediawiki
+++ b/bip-???-cat.mediawiki
@@ -85,7 +85,7 @@ OP_CAT usage in any Non-SegWitV1 script will continue to trigger the SCRIPT_ERR_
 
 ==Acknowledgements==
 
-We wish to acknowledge Dan Gould for encouraging and helping review this effort. 
+We wish to acknowledge Dan Gould for encouraging and helping review this effort. We also want to thank Madars Virza, Jeremy Rubin, Andrew Poelstra, Bob Summerwill for their feedback and helpful comments.
 
 == Copyright ==
 This document is licensed under the 3-clause BSD license.

From 109811e4b95168159155a98afb6229c8065a65ea Mon Sep 17 00:00:00 2001
From: Chris Stewart 
Date: Mon, 1 Apr 2024 13:33:48 -0500
Subject: [PATCH 177/454] Fix BIP380 typos

---
 bip-0380.mediawiki | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)

diff --git a/bip-0380.mediawiki b/bip-0380.mediawiki
index c457a34dea..a5743d5821 100644
--- a/bip-0380.mediawiki
+++ b/bip-0380.mediawiki
@@ -249,8 +249,8 @@ Invalid expressiosn:
 * Invalid hardened indicators: [deadbeef/-0/-0/-0]0260b2003c386519fc9eadf2b5cf124dd8eea4c4e68d5e154050a9346ea98ce600
 * Private key with derivation: L4rK1yDtCWekvXuE6oXD9jCYfFNV2cWRpVuPLBcCU2z8TrisoyY1/0
 * Private key with derivation children: L4rK1yDtCWekvXuE6oXD9jCYfFNV2cWRpVuPLBcCU2z8TrisoyY1/*
-* Derivation index out of range: xprv9s21ZrQH143K31xYSDQpPDxsXRTUcvj2iNHm5NUtrGiGG5e2DtALGdso3pGz6ssrdK4PFmM8NSpSBHNqPqm55Qn3LqFtT2emdEXVYsCzC2U/2147483648)", "pkh(xpub661MyMwAqRbcFW31YEwpkMuc5THy2PSt5bDMsktWQcFF8syAmRUapSCGu8ED9W6oDMSgv6Zz8idoc4a6mr8BDzTJY47LJhkJ8UB7WEGuduB/2147483648
-* Invalid derivation index: xprv9s21ZrQH143K31xYSDQpPDxsXRTUcvj2iNHm5NUtrGiGG5e2DtALGdso3pGz6ssrdK4PFmM8NSpSBHNqPqm55Qn3LqFtT2emdEXVYsCzC2U/1aa)", "pkh(xpub661MyMwAqRbcFW31YEwpkMuc5THy2PSt5bDMsktWQcFF8syAmRUapSCGu8ED9W6oDMSgv6Zz8idoc4a6mr8BDzTJY47LJhkJ8UB7WEGuduB/1aa
+* Derivation index out of range: xprv9s21ZrQH143K31xYSDQpPDxsXRTUcvj2iNHm5NUtrGiGG5e2DtALGdso3pGz6ssrdK4PFmM8NSpSBHNqPqm55Qn3LqFtT2emdEXVYsCzC2U/2147483648
+* Invalid derivation index: xprv9s21ZrQH143K31xYSDQpPDxsXRTUcvj2iNHm5NUtrGiGG5e2DtALGdso3pGz6ssrdK4PFmM8NSpSBHNqPqm55Qn3LqFtT2emdEXVYsCzC2U/1aa
 * Multiple key origins: [aaaaaaaa][aaaaaaaa]xprv9s21ZrQH143K31xYSDQpPDxsXRTUcvj2iNHm5NUtrGiGG5e2DtALGdso3pGz6ssrdK4PFmM8NSpSBHNqPqm55Qn3LqFtT2emdEXVYsCzC2U/2147483647'/0
 * Missing key origin start: aaaaaaaa]xprv9s21ZrQH143K31xYSDQpPDxsXRTUcvj2iNHm5NUtrGiGG5e2DtALGdso3pGz6ssrdK4PFmM8NSpSBHNqPqm55Qn3LqFtT2emdEXVYsCzC2U/2147483647'/0
 * Non hex fingerprint: [gaaaaaaa]xprv9s21ZrQH143K31xYSDQpPDxsXRTUcvj2iNHm5NUtrGiGG5e2DtALGdso3pGz6ssrdK4PFmM8NSpSBHNqPqm55Qn3LqFtT2emdEXVYsCzC2U/2147483647'/0

From 8795003831279c9af60f4a32bbc4af8b4b19cbc0 Mon Sep 17 00:00:00 2001
From: Chris Stewart 
Date: Wed, 3 Apr 2024 10:02:10 -0500
Subject: [PATCH 178/454] Fix unsatisfiable test vector in BIP382

---
 bip-0382.mediawiki | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/bip-0382.mediawiki b/bip-0382.mediawiki
index 942f62c183..bb1951d63e 100644
--- a/bip-0382.mediawiki
+++ b/bip-0382.mediawiki
@@ -73,7 +73,7 @@ Valid descriptors followed by the scripts they produce. Descriptors involving de
 ** a9149a4d9901d6af519b2a23d4a2f51650fcba87ce7b87
 ** a914bed59fc0024fae941d6e20a3b44a109ae740129287
 ** a9148483aa1116eb9c05c482a72bada4b1db24af654387
-* sh(wpkh(xpub661MyMwAqRbcFtXgS5sYJABqqG9YLmC4Q1Rdap9gSE8NqtwybGhePY2gZ29ESFjqJoCu1Rupje8YtGqsefD265TMg7usUDFdp6W1EGMcet8/10/20/30/40/*h))
+* sh(wpkh(xprv9s21ZrQH143K3QTDL4LXw2F7HEK3wJUD2nW2nRk4stbPy6cq3jPPqjiChkVvvNKmPGJxWUtg6LnF5kejMRNNU3TGtRBeJgk33yuGBxrMPHi/10/20/30/40/*h))
 ** a9149a4d9901d6af519b2a23d4a2f51650fcba87ce7b87
 ** a914bed59fc0024fae941d6e20a3b44a109ae740129287
 ** a9148483aa1116eb9c05c482a72bada4b1db24af654387

From 8a9e5744140222a4be238bbaa78f2512cf0102b5 Mon Sep 17 00:00:00 2001
From: Chris Stewart 
Date: Wed, 3 Apr 2024 15:00:42 -0500
Subject: [PATCH 179/454] Fix unsatisfiable test vector in BIP381

---
 bip-0381.mediawiki | 2 --
 1 file changed, 2 deletions(-)

diff --git a/bip-0381.mediawiki b/bip-0381.mediawiki
index 4b94278498..bfda2c8ecc 100644
--- a/bip-0381.mediawiki
+++ b/bip-0381.mediawiki
@@ -100,8 +100,6 @@ Valid descriptors followed by the scripts they produce. Descriptors involving de
 ** a9141a31ad23bf49c247dd531a623c2ef57da3c400c587
 * pkh(xprv9s21ZrQH143K31xYSDQpPDxsXRTUcvj2iNHm5NUtrGiGG5e2DtALGdso3pGz6ssrdK4PFmM8NSpSBHNqPqm55Qn3LqFtT2emdEXVYsCzC2U/2147483647'/0)
 ** 76a914ebdc90806a9c4356c1c88e42216611e1cb4c1c1788ac
-* pkh(xpub661MyMwAqRbcFW31YEwpkMuc5THy2PSt5bDMsktWQcFF8syAmRUapSCGu8ED9W6oDMSgv6Zz8idoc4a6mr8BDzTJY47LJhkJ8UB7WEGuduB/2147483647'/0)
-** 76a914ebdc90806a9c4356c1c88e42216611e1cb4c1c1788ac
 * pkh([bd16bee5/2147483647h]xpub69H7F5dQzmVd3vPuLKtcXJziMEQByuDidnX3YdwgtNsecY5HRGtAAQC5mXTt4dsv9RzyjgDjAQs9VGVV6ydYCHnprc9vvaA5YtqWyL6hyds/0)
 ** 76a914ebdc90806a9c4356c1c88e42216611e1cb4c1c1788ac
 * pk(xprv9uPDJpEQgRQfDcW7BkF7eTya6RPxXeJCqCJGHuCJ4GiRVLzkTXBAJMu2qaMWPrS7AANYqdq6vcBcBUdJCVVFceUvJFjaPdGZ2y9WACViL4L/0)

From 0092a4318f2201793f46cd71d3e465d143a5ae19 Mon Sep 17 00:00:00 2001
From: Murch 
Date: Thu, 4 Apr 2024 16:27:56 -0400
Subject: [PATCH 180/454] Clarify permitted status of markdown

Originally BIP-2 disallowed markdown, but markdown formatting was
permitted via #1504.
---
 bip-0002.mediawiki | 1 -
 1 file changed, 1 deletion(-)

diff --git a/bip-0002.mediawiki b/bip-0002.mediawiki
index af8bb3090a..7de5175419 100644
--- a/bip-0002.mediawiki
+++ b/bip-0002.mediawiki
@@ -409,7 +409,6 @@ Why is Public Domain no longer acceptable for new BIPs?
 * Non-image auxiliary files are permitted in the bip-XXXX subdirectory.
 * Email addresses are now required for authors.
 * The Post-History header may be provided as a link instead of a simple date.
-* Markdown format is no longer permitted for BIPs.
 * The Resolution header has been dropped, as it is not applicable to a decentralised system where no authority exists to make final decisions.
 
 ==See Also==

From 4a937e1887891b58eb5a1c5bebc3eda00d3ba5c9 Mon Sep 17 00:00:00 2001
From: Chris Stewart 
Date: Sat, 6 Apr 2024 09:26:59 -0500
Subject: [PATCH 181/454] Fix typo in BIP384 expected descriptors

---
 bip-0384.mediawiki | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/bip-0384.mediawiki b/bip-0384.mediawiki
index 02d6f765ec..ba12b55d7b 100644
--- a/bip-0384.mediawiki
+++ b/bip-0384.mediawiki
@@ -55,7 +55,7 @@ Valid descriptors followed by the scripts they produce. Descriptors involving de
 *** 2102df12b7035bdac8e3bab862a3a83d06ea6b17b6753d52edecba9be46f5d09e076ac
 *** 76a914f90e3178ca25f2c808dc76624032d352fdbdfaf288ac
 *** 0014f90e3178ca25f2c808dc76624032d352fdbdfaf2
-*** a91473e39884cb71ae4e5ac9739e9225026c99763e6687
+*** a91408f3ea8c68d4a7585bf9e8bda226723f70e445f087
 ** Child 1
 *** 21032869a233c9adff9a994e4966e5b821fd5bac066da6c3112488dc52383b4a98ecac
 *** 76a914a8409d1b6dfb1ed2a3e8aa5e0ef2ff26b15b75b788ac

From f8ad6ede5753b51bfd8a782f7de6d74a7e06cd95 Mon Sep 17 00:00:00 2001
From: Ethan Heilman 
Date: Fri, 12 Apr 2024 08:48:54 -0400
Subject: [PATCH 182/454] Changes OP_CAT BIP based on feedback given by Bob
 Summerwill

Bob Summerwill proposed a number of changes to the OP_CAT BIP to better follow BIP-2. This commit makes these changes:

* Using the section order specified in BIP-2
* Adding a Rationale section
* Expand the specification section by moving details from the abstract into the specification

Additionally this commit as rewords some confusing language.

Thanks Bob
---
 bip-???-cat.mediawiki | 72 ++++++++++++++++++++++++++-----------------
 1 file changed, 43 insertions(+), 29 deletions(-)

diff --git a/bip-???-cat.mediawiki b/bip-???-cat.mediawiki
index 3d3b73444f..d7746fe4c0 100644
--- a/bip-???-cat.mediawiki
+++ b/bip-???-cat.mediawiki
@@ -1,26 +1,33 @@
 
-  BIP: ???
+  BIP: ?
   Layer: Consensus (soft fork)
   Title: OP_CAT
   Author: Ethan Heilman 
           Armin Sabouri 
+  Comments-URI: https://github.com/bitcoin/bips/wiki/Comments:BIP-op-cat
   Status: Draft
   Type: Standards Track
   Created: 2023-10-21
-  Comments-URI: https://github.com/bitcoin/bips/wiki/Comments:BIP-op-cat
   License: BSD-3-Clause
 
==Abstract== -This BIP reintroduces OP_CAT in the form of a new tapscript opcode which allows the concatenation of two values on the stack. This opcode would be activated via a soft fork by redefining the opcode OP_SUCCESS126 (126 in decimal and 0x7e in hexidecimal). This is same opcode value used by the original OP_CAT. +This BIP introduces OP_CAT as a tapscript opcode which allows the concatenation of two values on the stack. OP_CAT would be activated via a soft fork by redefining the opcode OP_SUCCESS126 (126 in decimal and 0x7e in hexadecimal). This is the same opcode value used by the original OP_CAT. + +== Copyright == +This document is licensed under the 3-clause BSD license. + +==Specification== When evaluated the OP_CAT instruction: # Pops the top two values off the stack, -# concatenates the popped values together, +# concatenates the popped values together in stack order, # and then pushes the concatenated value on the top of the stack. -OP_CAT fails if there are less than two values on the stack or if a concatenated value would have a combined size greater than the maximum script element size of 520 bytes. +Given the stack ''[x1, x2]'', where ''x2'' is at the top of the stack, OP_CAT will push ''x1 || x2'' onto the stack. By ''||'' we denote concatenation. OP_CAT fails if there are fewer than two values on the stack or if a concatenated value would have a combined size greater than the maximum script element size of 520 bytes. + +This opcode would be activated via a soft fork by redefining the tapscript opcode OP_SUCCESS126 (126 in decimal and 0x7e in hexadecimal) to OP_CAT. ==Motivation== Bitcoin tapscript lacks a general purpose way of combining objects on the stack restricting the expressiveness and power of tapscript. This prevents among many other things the ability to construct and evaluate merkle trees and other hashed data structures in tapscript. OP_CAT by adding a general purpose way to concatenate stack values would overcome this limitation and greatly increase the functionality of tapscript. @@ -37,13 +44,23 @@ OP_CAT aims to expand the toolbox of the tapscript developer with a simple, modu The opcode OP_CAT was available in early versions of Bitcoin. However, OP_CAT was removed because it enabled the construction of a script whose evaluation could have memory usage exponential in the size of the script. For example, a script that pushed a 1-byte value on the stack and then repeated the opcodes OP_DUP, OP_CAT 40 times would result in a stack value whose size was greater than 1 terabyte. This is no longer an issue because tapscript enforces a maximum stack element size of 520 bytes. -==Specification== +==Rationale== + +Our decision to reenable OP_CAT by redefining a tapscript OP_SUCCESSx opcode to OP_CAT was motivated to leverage the tapscript softfork opcode upgrade path introduced in [[bip-0342.mediawiki|BIP342]]. + +We specifically choose to use OP_SUCCESS126 rather than another OP_SUCCESSx as OP_SUCCESS126 uses the same opcode value (126 in decimal and 0x7e in hexadecimal) that was used for OP_CAT prior to it being disabled in Bitcoin. This removes a potential source of confusion that would exist if we had a opcode value different from the one used in the original OP_CAT opcode. + +While the OP_SUCCESSx opcode upgrade path could enable us to increase the stack element size while reenabling OP_CAT, we wanted to separate the decision to change the stack element size limit from the decision to reenable OP_CAT. This BIP takes no position in favor or against increasing the stack element size limit. + +==Backwards Compatibility== -OP_CAT pops two elements off the stack, concatenates them together in stack order, and pushes the resulting element onto the stack. Given the stack ''[x1, x2]'', where ''x2'' is at the top of the stack, OP_CAT will push ''x1 || x2'' onto the stack. By ''||'' we denote concatenation. +OP_CAT usage in an non-tapscript script will continue to trigger the SCRIPT_ERR_DISABLED_OPCODE. The only change would be to OP_CAT usage in tapscript. This change to tapscript would be activated a soft fork that redefines an OP_SUCCESSx opcode (OP_SUCCESS126) to OP_CAT. + +==Reference implementation== -===Implementation===
-case OP_CAT: {
+case OP_CAT:
+{
   if (stack.size() < 2)
     return set_error(serror, SCRIPT_ERR_INVALID_STACK_OPERATION);
   valtype& vch1 = stacktop(-2);
@@ -55,29 +72,29 @@ case OP_CAT: {
 }
 break;
 
-This implementation is inspired by the original implementation of OP_CAT as shown below. An alternative implementation of OP_CAT can be found in Elements Roose S., Elements Project, "Re-enable several disabled opcodes", 2019, https://github.com/ElementsProject/elements/commit/13e1103abe3e328c5a4e2039b51a546f8be6c60a#diff-a0337ffd7259e8c7c9a7786d6dbd420c80abfa1afdb34ebae3261109d9ae3c19R740-R759. -The value of MAX_SCRIPT_ELEMENT_SIZE is 520. -==Notes== +The value of MAX_SCRIPT_ELEMENT_SIZE is 520. -[https://github.com/bitcoin/bitcoin/blob/01cd2fdaf3ac6071304ceb80fb7436ac02b1059e/script.cpp#L381-L393 OP_CAT as it existed in the Bitcoin codebase] prior to the commit "misc changes" 4bd188cS. Nakamoto, "misc changes", Aug 25 2010, https://github.com/bitcoin/bitcoin/commit/4bd188c4383d6e614e18f79dc337fbabe8464c82#diff-27496895958ca30c47bbb873299a2ad7a7ea1003a9faa96b317250e3b7aa1fefR94 which disabled it: +This implementation is inspired by the original implementation of [https://github.com/bitcoin/bitcoin/blob/01cd2fdaf3ac6071304ceb80fb7436ac02b1059e/script.cpp#L381-L393 OP_CAT as it existed in the Bitcoin codebase] prior to the commit "misc changes" 4bd188cS. Nakamoto, "misc changes", Aug 25 2010, https://github.com/bitcoin/bitcoin/commit/4bd188c4383d6e614e18f79dc337fbabe8464c82#diff-27496895958ca30c47bbb873299a2ad7a7ea1003a9faa96b317250e3b7aa1fefR94 which disabled it:
-  // (x1 x2 -- out)
-  if (stack.size() < 2)
-    return false;
-  valtype& vch1 = stacktop(-2);
-  valtype& vch2 = stacktop(-1);
-  vch1.insert(vch1.end(), vch2.begin(), vch2.end());
-  stack.pop_back();
-  if (stacktop(-1).size() > 5000)
-    return false;
-  }
+case OP_CAT:
+{
+    // (x1 x2 -- out)
+    if (stack.size() < 2)
+        return false;
+    valtype& vch1 = stacktop(-2);
+    valtype& vch2 = stacktop(-1);
+    vch1.insert(vch1.end(), vch2.begin(), vch2.end());
+    stack.pop_back();
+    if (stacktop(-1).size() > 5000)
+        return false;
+}
+break;
 
-==Backwards Compatibility== -OP_CAT usage in any Non-SegWitV1 script will continue to trigger the SCRIPT_ERR_DISABLED_OPCODE. +An alternative implementation of OP_CAT can be found in Elements Roose S., Elements Project, "Re-enable several disabled opcodes", 2019, https://github.com/ElementsProject/elements/commit/13e1103abe3e328c5a4e2039b51a546f8be6c60a#diff-a0337ffd7259e8c7c9a7786d6dbd420c80abfa1afdb34ebae3261109d9ae3c19R740-R759. ==References== @@ -85,7 +102,4 @@ OP_CAT usage in any Non-SegWitV1 script will continue to trigger the SCRIPT_ERR_ ==Acknowledgements== -We wish to acknowledge Dan Gould for encouraging and helping review this effort. We also want to thank Madars Virza, Jeremy Rubin, Andrew Poelstra, Bob Summerwill for their feedback and helpful comments. - -== Copyright == -This document is licensed under the 3-clause BSD license. +We wish to acknowledge Dan Gould for encouraging and helping review this effort. We also want to thank Madars Virza, Jeremy Rubin, Andrew Poelstra, Bob Summerwill for their feedback, review and helpful comments. From ee0a17ef08924f4cbab5faf30202b03203722a04 Mon Sep 17 00:00:00 2001 From: Jason Dreyzehner Date: Mon, 15 Apr 2024 17:12:02 -0400 Subject: [PATCH 183/454] feat: add TypeScript BIP39 implementation --- bip-0039.mediawiki | 3 +++ 1 file changed, 3 insertions(+) diff --git a/bip-0039.mediawiki b/bip-0039.mediawiki index 5170edd97a..1c4845e580 100644 --- a/bip-0039.mediawiki +++ b/bip-0039.mediawiki @@ -171,6 +171,9 @@ JavaScript: * https://github.com/dashhive/DashPhrase.js * https://github.com/hujiulong/web-bip39 +TypeScript: +* https://github.com/bitauth/libauth + Java: * https://github.com/bitcoinj/bitcoinj/blob/master/core/src/main/java/org/bitcoinj/crypto/MnemonicCode.java From fa95e343886ee28e2c10b5bcbd93e15441bf55a4 Mon Sep 17 00:00:00 2001 From: Jon Atack Date: Mon, 22 Apr 2024 16:38:46 -0600 Subject: [PATCH 184/454] BIP2: update BIP editors --- bip-0002.mediawiki | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/bip-0002.mediawiki b/bip-0002.mediawiki index 71d3812cbe..0462a0069d 100644 --- a/bip-0002.mediawiki +++ b/bip-0002.mediawiki @@ -67,8 +67,12 @@ If you are interested in assuming ownership of a BIP, send a message asking to t The current BIP editors are: +* Bryan Bishop ([[mailto:kanzure@gmail.com|kanzure@gmail.com]]) +* Jon Atack ([[mailto:jon@atack.com|jon@atack.com]]) * Luke Dashjr ([[mailto:luke_bipeditor@dashjr.org|luke_bipeditor@dashjr.org]]) -* Kalle Alm ([[mailto:karljohan-alm@garage.co.jp|karljohan-alm@garage.co.jp]]) +* Mark "Murch" Erhardt ([[mailto:murch@murch.one|murch@murch.one]]) +* Olaoluwa Osuntokun ([[mailto:laolu32@gmail.com|laolu32@gmail.com]]) +* Ruben Somsen ([[mailto:rsomsen@gmail.com|rsomsen@gmail.com]]) ===BIP Editor Responsibilities & Workflow=== From 6ced7dbb5a79cc60ad342e788d998c73eb1ff978 Mon Sep 17 00:00:00 2001 From: Murch Date: Tue, 23 Apr 2024 15:31:27 -0400 Subject: [PATCH 185/454] Fix typos in BIP141 Co-authored-by: Greg Laun --- bip-0141.mediawiki | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/bip-0141.mediawiki b/bip-0141.mediawiki index 2247ef6508..694c86e3a6 100644 --- a/bip-0141.mediawiki +++ b/bip-0141.mediawiki @@ -276,7 +276,7 @@ These commitments could be included in the extensible commitment structure throu Since a version byte is pushed before a witness program, and programs with unknown versions are always considered as anyone-can-spend script, it is possible to introduce any new script system with a soft fork. The witness as a structure is not restricted by any existing script semantics and constraints, the 520-byte push limit in particular, and therefore allows arbitrarily large scripts and signatures. -Examples of new script system include Schnorr signatures which reduce the size of multisig transactions dramatically, Lamport signature which is quantum computing resistance, and Merklized abstract syntax trees which allow very compact witness for conditional scripts with extreme complexity. +Examples of new script systems include Schnorr signatures, which reduce the size of multisig transactions dramatically; Lamport signatures, which are quantum computing resistant; and Merklized abstract syntax trees, which allow very compact witnesses for conditional scripts with extreme complexity. === Per-input lock-time and relative-lock-time === From 979ee894b8a4a2e9bd7c07093273588f0cd241d6 Mon Sep 17 00:00:00 2001 From: Lucas Cullen Date: Sun, 29 Apr 2018 19:52:59 +1000 Subject: [PATCH 186/454] Fix grammar --- bip-0141.mediawiki | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/bip-0141.mediawiki b/bip-0141.mediawiki index 694c86e3a6..eb2fc74abd 100644 --- a/bip-0141.mediawiki +++ b/bip-0141.mediawiki @@ -303,7 +303,7 @@ As a soft fork, older software will continue to operate without modification. N This BIP will be deployed by "version bits" BIP9 with the name "segwit" and using bit 1. -For Bitcoin mainnet, the BIP9 starttime will be midnight 15 november 2016 UTC (Epoch timestamp 1479168000) and BIP9 timeout will be midnight 15 november 2017 UTC (Epoch timestamp 1510704000). +For Bitcoin mainnet, the BIP9 starttime will be midnight 15 November 2016 UTC (Epoch timestamp 1479168000) and BIP9 timeout will be midnight 15 November 2017 UTC (Epoch timestamp 1510704000). For Bitcoin testnet, the BIP9 starttime will be midnight 1 May 2016 UTC (Epoch timestamp 1462060800) and BIP9 timeout will be midnight 1 May 2017 UTC (Epoch timestamp 1493596800). From 632f143fadaed8c91bba12d096e62feb2a308054 Mon Sep 17 00:00:00 2001 From: glozow Date: Wed, 11 May 2022 15:53:37 -0400 Subject: [PATCH 187/454] specify BIP331 Ancestor Package Relay --- README.mediawiki | 7 + bip-0331.mediawiki | 430 ++++++++++++++++++++++++ bip-0331/no_package_info.png | Bin 0 -> 34994 bytes bip-0331/orphan_handling_flow.png | Bin 0 -> 65204 bytes bip-0331/package_cpfp_flow.png | Bin 0 -> 57377 bytes bip-0331/package_erlay.png | Bin 0 -> 45106 bytes bip-0331/package_info_only.png | Bin 0 -> 45150 bytes bip-0331/sender_init_future_version.png | Bin 0 -> 99293 bytes bip-0331/version_negotiation.png | Bin 0 -> 50918 bytes 9 files changed, 437 insertions(+) create mode 100644 bip-0331.mediawiki create mode 100644 bip-0331/no_package_info.png create mode 100644 bip-0331/orphan_handling_flow.png create mode 100644 bip-0331/package_cpfp_flow.png create mode 100644 bip-0331/package_erlay.png create mode 100644 bip-0331/package_info_only.png create mode 100644 bip-0331/sender_init_future_version.png create mode 100644 bip-0331/version_negotiation.png diff --git a/README.mediawiki b/README.mediawiki index 815e8c3c67..bc174cf350 100644 --- a/README.mediawiki +++ b/README.mediawiki @@ -1030,6 +1030,13 @@ Those proposing changes should consider that ultimately consent may rest with th | Standard | Draft |- +| [[bip-0331.mediawiki|331]] +| Peer Services +| Ancestor Package Relay +| Gloria Zhao +| Standard +| Draft +|- | [[bip-0338.mediawiki|338]] | Peer Services | Disable transaction relay message diff --git a/bip-0331.mediawiki b/bip-0331.mediawiki new file mode 100644 index 0000000000..08927a23fb --- /dev/null +++ b/bip-0331.mediawiki @@ -0,0 +1,430 @@ +
+  BIP: 331
+  Layer: Peer Services
+  Title: Ancestor Package Relay
+  Author: Gloria Zhao 
+  Comments-URI: https://github.com/bitcoin/bips/wiki/Comments:BIP-0331
+  Status: Draft
+  Type: Standards Track
+  Created: 2022-08-08
+  License: BSD-3-Clause
+  Post-History: 2022-05-17 https://lists.linuxfoundation.org/pipermail/bitcoin-dev/2022-May/020493.html [bitcoin-dev] post
+
+ +==Abstract== + +Peer-to-peer protocol messages enabling nodes to request and relay the unconfirmed ancestor package +of a given transaction, and to request and relay transactions in batches. + +==Motivation== + +===Propagate High Feerate Transactions=== + +Since v0.13, Bitcoin Core has used ancestor packages instead of individual transactions to evaluate +the incentive compatibility of transactions in the mempool +[https://github.com/bitcoin/bitcoin/pull/7594 Add tracking of ancestor packages] and +selecting them for inclusion in blocks +[https://github.com/bitcoin/bitcoin/pull/7600 Select transactions using feerate-with-ancestors]. +Incentive-compatible mempool and miner policies help create a fair, fee-based market for block +space. While miners maximize transaction fees in order to earn higher block rewards, non-mining +users participating in transaction relay reap many benefits from employing policies that result in a +mempool with similar contents, including faster compact block relay and more accurate fee +estimation. Additionally, users may take advantage of mempool and miner policy to bump the priority +of their transactions by attaching high-fee descendants (Child Pays for Parent or CPFP). + +Only individually considering transactions for submission to the mempool creates a limitation in +the node's ability to determine which transactions to include in the mempool, since it cannot take +into account descendants until all the transactions are in the mempool. Similarly, it cannot use a +transaction's descendants when considering which of two conflicting transactions to keep (Replace by +Fee or RBF). + +When a user's transaction does not meet a mempool's minimum feerate and they cannot create a +replacement transaction directly, their transaction will simply be rejected by this mempool or +evicted if already included. They also cannot attach a descendant to pay for replacing a conflicting +transaction; it would be rejected for spending inputs that do not exist. + +This limitation harms users' ability to fee-bump their transactions. Further, it presents security and complexity +issues in contracting protocols which rely on presigned, time-sensitive transactions'''Examples of time-sensitive pre-signed transactions in L2 protocols.''' +* [https://github.com/lightning/bolts/blob/master/03-transactions.md#htlc-timeout-and-htlc-success-transactions HTCL-Timeout in LN Penalty] +* [https://github.com/revault/practical-revault/blob/master/transactions.md#cancel_tx Unvault Cancel in Revault] +* [https://github.com/discreetlogcontracts/dlcspecs/blob/master/Transactions.md#refund-transaction Refund Transaction in Discreet Log Contracts] +* [https://gist.github.com/instagibbs/60264606e181451e977e439a49f69fe1 Updates in Eltoo] +* [https://github.com/ElementsProject/peerswap/blob/master/docs/peer-protocol.md#claim-transaction Claim Transactions in PeerSwap] + to prevent cheating. +In other words, a key security assumption of many contracting protocols is that all parties can +propagate and confirm transactions in a timely manner. Increasing attention has been brought to +"pinning attacks," a type of censorship in which the attacker uses mempool policy restrictions to +prevent a transaction from being relayed or getting mined. +'''Concerns for pinning attacks in L2 protocols''' +* [https://lists.linuxfoundation.org/pipermail/bitcoin-dev/2022-May/020458.html Greg Sanders, "Bringing a nuke to a knife fight: Transaction introspection to stop RBF pinning"] +* [https://lists.linuxfoundation.org/pipermail/lightning-dev/2020-April/002639.html Matt Corallo, "RBF Pinning with Counterparties and Competing Interest"] +* [https://lists.linuxfoundation.org/pipermail/lightning-dev/2020-June/002758.html Antoine Riard, "Pinning : The Good, The Bad, The Ugly"] +* [https://github.com/t-bast/lightning-docs/blob/master/pinning-attacks.md Bastien Teinturier, "Pinning Attacks"] +* [https://gist.github.com/instagibbs/60264606e181451e977e439a49f69fe1 Greg Sanders, "Eltoo Pinning"] + + +These transactions must meet a certain confirmation target to be effective, but their feerates +are negotiated well ahead of broadcast time. If the forecast feerate was too low and no +fee-bumping options are available, attackers can steal money from their counterparties. Always +overestimating fees may sidestep this issue (but only while mempool traffic is low and +predictable), but this solution is not guaranteed to work and wastes users' money. For some attacks, +the available defenses require nodes to have a bird's-eye view of Bitcoin nodes' mempools, which is +an unreasonable security requirement. + +Part of the solution is to enable nodes to consider packages of transactions as a unit, e.g. one or +more low-fee ancestor transactions with a high-fee descendant, instead of separately. A package-aware +mempool policy can help determine if it would actually be economically rational to accept a +transaction to the mempool if it doesn't meet fee requirements individually. Network-wide adoption +of these policies would create a more purely-feerate-based market for block space and allow +contracting protocols to adjust fees (and therefore mining priority) at broadcast time. + +Theoretically, developing a safe and incentive-compatible package mempool acceptance policy is +sufficient to solve this issue. Nodes could opportunistically accept packages (e.g. by trying +combinations of transactions rejected from their mempools), but this practice would likely be +inefficient at best and open new Denial of Service attacks at worst. As such, this proposal +suggests adding new p2p messages enabling nodes to request and share package-validation-related +information with one another, resulting in a more efficient and reliable way to propagate packages. + +===Handle Orphans Better=== + +Txid-based transaction relay is problematic since a transaction's witness may be malleated without +changing its txid; a node cannot use txid to deduplicate transactions it has already downloaded +or validated. Ideally, two nodes that both support BIP339 wtxid-based transaction relay shouldn't +ever need to use txid-based transaction relay. + +A single use case of txid-based relay remains: handling "orphan" transactions that spend output(s) +from an unconfirmed transaction the receiving node is unaware of. Orphan transactions are very +common for new nodes that have just completed Initial Block Download and do not have an up-to-date +mempool. Nodes also download transactions from multiple peers. If the peer from which a child +transaction was requested responds faster than the peer from which its parent was requested, that +child is seen as an orphan transaction. + +Nodes may handle orphans by storing them in a cache and requesting any missing parent(s) by txid +(prevouts specify txid, not wtxid). These parents may end up being orphans as well, if they also +spend unconfirmed inputs that the node is unaware of. This method of handling orphans is problematic +for two reasons: it requires nodes to allocate memory for unvalidated data received on the p2p +network and it relies on txid-based relay between two wtxid-relay peers. + +This proposal makes orphan resolution more efficient and no longer require txid-based relay. + +==Definitions== + +Given any two transactions Tx0 and Tx1 where Tx1 spends an output of Tx0, Tx0 is a '''parent''' of +Tx1 and Tx1 is a '''child''' of Tx0. + +A transaction's '''ancestors''' include, recursively, its parents, the parents of its parents, etc. +A transaction's '''descendants''' include, recursively, its children, the children of its children, +etc. A transaction's parent is its ancestor, but an ancestor is not necessarily a parent. + +A '''package''' is a list of transactions, representable by a connected Directed Acyclic +Graph (a directed edge exists between a transaction that spends the output of another transaction). +In this proposal, a package is limited to unconfirmed transactions. + +An '''ancestor package''' consists of an unconfirmed transaction with all of its unconfirmed +ancestors. + +In a '''topologically sorted''' package, each parent appears somewhere in the list before its child. + +==Specification== + +Ancestor Package Relay includes two parts: a package information round and a transaction data +download round. +The package information round is used to help a receiver learn what transactions are in a package and +decide whether they want to download them. The transaction data round is used to help a node download +multiple transactions in one message instead of as separate messages. +'''Why are package information and transaction data rounds both necessary?''' + +Several alternative designs were considered. One should measure alternative solutions based on the +resources used to communicate (not necessarily trustworthy) information: We would like to minimize +network bandwidth, avoid downloading a transaction more than once, avoid downloading transactions +that are eventually rejected, and minimize storage allocated for not-yet-validated transactions. + +
+ +'''No Package Information Round:''' One proposal is to just use the child's wtxid to refer to the +package and always send the entire package together, skipping the package information round. +However, this protocol would make it very likely for honest nodes to redownload duplicate +transactions. See the following example, where the high-feerate ancestors were already downloaded +and accepted individually. + +[[File:./bip-0331/no_package_info.png|600px]] +
+ +'''Package Information Only:''' Just having package information gives enough information for the +receiver to accept the packages. That is, rather than using "getpkgtxns" and "pkgtxns" messages, +send "getdata" and download the transactions individually. While this option is a potential fallback +if batched transaction download fails for some reason, it shouldn't be used as the default because +it always requires storage of unvalidated transactions. +[[File:./bip-0331/package_info_only.png|1000px]] +
+ +Package relay is negotiated between two peers during the version handshake using a "sendpackages" +message. The versions field within "sendpackages" is interpreted as a bitfield; peers may relay +multiple versions of packages. Package relay requires both peers to support wtxid-based relay +because package transactions are referenced by their wtxids. +'''Why do we need multiple versions? Why can't we just support arbitrary packages?''' +Attempting to support arbitrary packages in mempool validation may result in very complex logic, new +Denial of Service attack vectors, and policy limitations that could be leveraged to censor +transactions (aka "pinning attacks"). This protocol is extensible to support other types of +packages based on future desired use cases. Future package information messages may describe +different types of packages and/or contain more information than a list of wtxids, e.g. feerate or +relationships between transactions. +'''Why use a bitfield instead of a numbering system?''' +It should be possible to support some subset of the existing package types. + +[[File:./bip-0331/version_negotiation.png|400px]] + +Nodes indicate support for batched transaction data round ("getpkgtxns", "pkgtxns", and +"MSG_PKGTXNS") using the PKG_RELAY_PKGTXNS = (1 << 0) bit in their "sendpackages" +messages during version handshake. They indicate support for the ancestor package information +round ("ancpkginfo", "MSG_ANCPKGINFO") using the PKG_RELAY_ANC = (1 << 1) bit in their +"sendpackages" messages during version handshake. + +===Protocol Flow Examples=== + +This package relay protocol satisfies both use cases (orphan transaction handling and high-feerate +transaction paying for low-feerate ancestors). + +====Orphan Transaction Handling==== + +Upon receiving an orphan transaction, a node may request ancestor package information delineating +the wtxids of the transaction's unconfirmed ancestors. This is done without using txid-based relay. +The package information can be used to request transaction data. As these transactions are dependent +upon one another to be valid, the transactions can be requested and sent as a batch. + +Contrast this protocol with legacy orphan handling, which requires requesting the missing +transactions by their txids and may require new round trips for each generation of missing parents. +[[File:./bip-0331/orphan_handling_flow.png|1000px]] + +====Fee-Bumped Transactions==== + +Too-low-feerate transactions (i.e. below the node's minimum mempool feerate) with high-feerate +descendants can also be relayed this way. If the peers are using BIP133 fee filters and a +low-feerate transaction is below the node's fee filter, the sender will not announce it. The +high-feerate transaction will be sent by the sender, and received and handled as an orphan by the +receiver, the transactions are validated as a package, and so the protocol naturally works for this +use case. + +This does not mean BIP133 is required for package relay to work, provided that nodes do not +immediately reject transactions previously found to be too low feerate. If the low-feerate +transaction was sent and rejected, the receiver should later re-request and accept it after learning +that it is the ancestor of another transaction, and that they meet the receiver's mempool policy +requirements when validated together. + +[[File:./bip-0331/package_cpfp_flow.png|600px]] + +This protocol is receiver-initiated only; nodes do not proactively announce packages to their peers. +'''Why no sender-initiated protocol?''' Sender-initiated package +relay can, theoretically, save a round trip by notifying the receiver ahead of time that they will +probably need to request and validate a group of transactions together in order for them to be +accepted. As with any proactive communication, there is a chance that the receiver already knows +this information, so this network bandwidth may be wasted. Shortened latency is less significant +than wasted bandwidth. + +The logic used to decide when to announce a package proactively determines whether it is a net +increase or decrease for overall bandwidth usage. However, it is difficult to design anything to +save bandwidth without any idea of what its bandwidth usage actually looks like in practice. No +historical data is available, as one of the primary goals of this protocol is to enable +currently-rejected transactions to propagate. After deploying receiver-initiated package relay, we +can observe its usage and then introduce a sender-initiated package relay protocol informed by data +collected from the p2p network. + +===Combined Hash=== + +A "combined hash" serves as a unique "package id" for some list of transactions and helps provide a +meaningful but short "notfound" response to "getpkgtxns." + +The combined hash of a package of transactions is equal to the sha256 hash of each transaction's +wtxid concatenated in lexicographical order. + +===New Messages=== + +Four new protocol messages and two inv types are added. + +====sendpackages==== + +{| +| Field Name || Type || Size || Purpose +|- +|versions || uint64_t || 4 || Bit field that is 64 bits wide, denoting the package versions supported by the sender. +|- +|} + +# The "sendpackages" message has the structure defined above, with pchCommand == "sendpackages". + +# During version handshake, nodes should send one "sendpackages" message indicating they support package relay, with the versions field indicating which versions they support. + +# The "sendpackages" message MUST be sent before sending a "verack" message. If a "sendpackages" message is received after "verack", the sender may be disconnected. + +# Upon successful connection ("verack" sent by both peers), a node may relay packages with the peer if they did not set "fRelay" to false in the "version" message, both peers sent "wtxidrelay", and both peers sent "sendpackages" for matching version bit(s). Unknown bits (including versions==0) should be ignored. Peers should relay packages corresponding to versions that both sent "sendpackages" for.'''Is it ok to send "sendpackages" to a peer that specified fRelay=false in their "version" message?''' +Yes, this is allowed in order to reduce the number of negotiation steps. This means nodes can +announce features without first checking what the other peer has sent, and then apply negotiation +logic at the end based on what was sent and received. See [https://lists.linuxfoundation.org/pipermail/bitcoin-dev/2022-May/020510.html this discussion]. + + +====ancpkginfo==== +{| +| Field Name || Type || Size || Purpose +|- +|txns_length||CompactSize||1 or 3 bytes|| The number of transactions provided. +|- +|txns||List of wtxids||txns_length * 32|| The wtxids of each transaction in the package. +|} + +# The "ancpkginfo" message has the structure defined above, with pchCommand == "ancpkginfo". + +# The "txns" field should contain a list of wtxids which constitute the ancestor package of the last wtxid. For the receiver's convenience, the sender should - but is not required to - sort the wtxids in topological order. The topological sort can be achieved by sorting the transactions by mempool acceptance order (if parents are always accepted before children). Apart from the last wtxid which is used to learn which transaction the message corresponds to, there is no enforced ordering. Nodes should not disconnect or punish a peer who provides a list not sorted in topological order.'''Why not include feerate information to help the receiver decide whether these transactions are worth downloading?''' +A simple feerate is typically insufficient; the receiver must also know the dependency +relationships between transactions and their respective sizes. +'''Should a peer be punished if they provide incorrect package info, e.g. a list of unrelated transactions?''' +Ideally, there should be a way to enforce that peers are providing correct information to each +other. However, two peers may have different views of what a transaction's unconfirmed ancestors +are based on their chainstate. For example, during a reorg or when two blocks are found at the same +time, one peer may see a transaction as confirmed while the other peer does not. +As such, it is impossible to accurately enforce this without also knowing the peer's chainstate. +It was [https://lists.linuxfoundation.org/pipermail/bitcoin-dev/2022-May/020493.html originally proposed] +to include a block hash in "ancpkginfo" to avoid unwarranted disconnections. However, it does not +make much sense to stop or delay transaction data requests due to mismatched chainstates, and the +chainstate may change again between package information and transaction data rounds. Instead, +differences in chainstate should be handled at the validation level. The node has already spent +network bandwidth downloading these transactions; it should make a best effort to validate them. +See [https://lists.linuxfoundation.org/pipermail/bitcoin-dev/2022-June/020558.html discussion]. +'''Why not require topological order?''' +It is not possible to determine whether a list of transactions is topologically sorted without first +establishing that the list contains a full ancestor package. It is not possible to determine whether +a list of transactions contains a full ancestor package without knowing what the chainstate is. + + +# Upon receipt of a "ancpkginfo" message, the node may use it to request the transactions it does not already have (e.g. using "getpkgtxns" or "tx"). + +# Upon receipt of a malformed "ancpkginfo" message, the sender may be disconnected. An "ancpkginfo" message is malformed if it contains duplicate wtxids or conflicting transactions (spending the same inputs). The receiver may learn that a package info was malformed after downloading the transactions. + +# A node MUST NOT send a "ancpkginfo" message that has not been requested by the recipient. Upon receipt of an unsolicited "ancpkginfo", a node may disconnect the sender. + +# This message must only be used if both peers set PKG_RELAY_ANC in their "sendpackages" message. If an "ancpkginfo" message is received from a peer with which this type of package relay was not negotiated, no response should be sent and the sender may be disconnected. + +====MSG_ANCPKGINFO==== + +# A new inv type (MSG_ANCPKGINFO == 0x7) is added, for use only in getdata requests pertaining to ancestor packages. + +# As a getdata request type, it indicates that the sender wants an "ancpkginfo" containing all of the unconfirmed ancestors of a transaction, referenced by wtxid. + +# Upon receipt of a "getdata(MSG_ANCPKGINFO)" request, the node should respond with an "ancpkginfo" message corresponding to the transaction's unconfirmed ancestor package, or with "notfound". The wtxid of the requested transaction must be the last item in the "ancpkginfo" response list, as the last item is used to determine which transaction the "ancpkginfo" pertains to. + +# The inv type must only be used in a "getdata" message. An "inv(MSG_ANCPKGINFO)" must never be sent. If an "inv(MSG_ANCPKGINFO)" is received, the sender may be disconnected. + +# This inv type must only be used if both peers set PKG_RELAY_ANC in their "sendpackages" message. If a "getdata" message with type MSG_ANCPKGINFO is received from a peer with which this type of package relay was not negotiated, no response should be sent and the sender may be disconnected. + +====getpkgtxns==== + +{| +| Field Name || Type || Size || Purpose +|- +|txns_length||CompactSize||1 or 3 bytes|| The number of transactions requested. +|- +|txns||List of wtxids||txns_length * 32|| The wtxids of each transaction in the package. +|} + +# The "getpkgtxns" message has the structure defined above, with pchCommand == "getpkgtxns". + +# A "getpkgtxns" message should be used to request some list of transactions specified by witness transaction id. It indicates that the node wants to receive either all the specified transactions or none of them. This message is intended to allow nodes to avoid downloading and storing transactions that cannot be validated without each other. The list of transactions does not need to correspond to a previously-received ancpkginfo message. + +# Upon receipt of a "getpkgtxns" message, a node should respond with either a "pkgtxns" containing all of the requested transactions in the same order specified in the "getpkgtxns" request or one "notfound" message of type MSG_PKGTXNS and combined hash of all of the wtxids in the "getpkgtxns" request (only one "notfound" message and nothing else), indicating one or more of the transactions is unavailable. + +# A "getpkgtxns" message must contain at most 100 wtxids. Upon receipt of a "getpkgtxns" message with more than 100 wtxids, a node may ignore the message (to avoid calculating the combined hash) and disconnect the sender. + +# This message must only be used if both peers set PKG_RELAY_PKGTXNS in their "sendpackages" message. If a "getpkgtxns" message is received from a peer with which this type of package relay was not negotiated, no response should be sent and the sender may be disconnected. + +====pkgtxns==== + +{| +| Field Name || Type || Size || Purpose +|- +|txns_length||CompactSize||1 or 3 bytes|| The number of transactions provided. +|- +|txns||List of transactions||variable|| The transactions in the package. +|} + +# The "pkgtxns" message has the structure defined above, with pchCommand == "pkgtxns". + +# A "pkgtxns" message should contain the transaction data requested using "getpkgtxns". + +# A "pkgtxns" message should only be sent to a peer that requested the package using "getpkgtxns". If a node receives an unsolicited package, it may choose to validate the transactions or not, and the sender may be disconnected. + +# This message must only be used if both peers set PKG_RELAY_PKGTXNS in their "sendpackages" message. If a "pkgtxns" message is received from a peer with which this type of package relay was not negotiated, no response should be sent and the sender may be disconnected. + +====MSG_PKGTXNS==== + +# A new inv type (MSG_PKGTXNS == 0x6) is added, for use only in "notfound" messages pertaining to package transactions. + +# As a "notfound" type, it indicates that the sender is unable to send all the transactions requested in a prior "getpkgtxns" message. The hash used is equal to the combined hash of the wtxids in the getpkgtxns request. + +# This inv type should only be used in "notfound" messages, i.e. "inv(MSG_PKGTXNS)" and "getdata(MSG_PKGTXNS)" must never be sent. Upon receipt of an "inv" or "getdata" message of this type, the sender may be disconnected. + +# This inv type must only be used if both peers set PKG_RELAY_PKGTXNS in their "sendpackages" message. + +==Compatibility== + +Older clients remain fully compatible and interoperable after this change. Clients implementing this +protocol will only attempt to send and request packages if agreed upon during the version handshake. +'''Will package relay cause non-package relay nodes to waste bandwidth on low-feerate transactions?''' +If a node supports package relay, it may accept low-feerate transactions (e.g. paying zero fees) +into its mempool, but non-package relay nodes would most likely reject them. To mitigate bandwidth +waste, a package relay node should not announce descendants of below-fee-filter transactions to +non-package relay peers. + +'''Is Package Erlay possible?''' +A client using BIP330 reconciliation-based transaction relay (Erlay) is able to use package relay +without interference. After reconciliation, any transaction with unconfirmed ancestors may have +those ancestors resolved using ancestor package relay. +[[File:./bip-0331/package_erlay.png|700px]] + + +==Extensibility== + +This protocol can be extended to include more types of package information in the future, while +continuing to use the same messages for transaction data download. One would define a new package +information message (named "*pkginfo" in the diagram below), allocate its corresponding inv +type (named "*PKGINFO" in the diagram below), and specify how to signal support using the +versions field of "sendpackages" (an additional bit named "PKG_RELAY_*" in the diagram below). A +future version of package relay may allow a sender-initiated dialogue by specifying that the package +info type inv type can be used in an "inv" message. +
+[[File:./bip-0331/sender_init_future_version.png|700px]] + +==Implementation== + +Sample implementation for Bitcoin Core: https://github.com/bitcoin/bitcoin/pull/27742 + +A prerequisite for implementing a safe +package relay protocol is a mempool acceptance policy that safely validates packages of +transactions. +'''Package Mempool Acceptance Policy''' +Accepting packages from peers should not significantly increase a node's DoS attack surface; +processing packages should not permit waste or exhaustion of the node and network's resources. +Additionally, a sensible mempool acceptance policy should result in the most incentive-compatible +subset of the package in the mempool in order to avoid adding more pinning attacks or censorship +vectors. For example, It should not be assumed that packages are CPFPs. An ancestor package may +include a high-feerate parent and low-feerate child; the policy may choose to accept the parent but +not the child. If one or more transactions are policy-invalid, other transactions that are not +dependent upon them should still be considered. + + +==Acknowledgements== + +Thank you to Suhas Daftuar, John Newbery, Anthony Towns, Martin Zumsande, and others for input on the design. + +Thank you to Will Clark, Sergi Delgado, Fabian Jahr, John Newbery, Greg Sanders, Stéphan Vuylsteke, Pieter Wuille, and others for input on this document. + +Much of this work is inspired by ideas and code by Suhas Daftuar and Antoine Riard. +'''Prior Work on Package Relay''' +* [https://gist.github.com/sdaftuar/8756699bfcad4d3806ba9f3396d4e66a Strawman Proposal] +* [https://github.com/bitcoin/bitcoin/issues/14895 Package relay design questions] +* [https://github.com/bitcoin/bitcoin/pull/16401 Add package acceptance logic to mempool] +* [https://github.com/bitcoin/bitcoin/pull/19621 [RFC] Package-relay: sender-initiated] + + +==References and Rationale== + + + diff --git a/bip-0331/no_package_info.png b/bip-0331/no_package_info.png new file mode 100644 index 0000000000000000000000000000000000000000..54b20f97dde2883b82e2361a888d4e8facb45e42 GIT binary patch literal 34994 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 literal 0 HcmV?d00001 diff --git a/bip-0331/orphan_handling_flow.png b/bip-0331/orphan_handling_flow.png new file mode 100644 index 0000000000000000000000000000000000000000..4588de84b1ffd05d90dda042f7c08201718003d7 GIT binary patch literal 65204 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 RMo9Rzc!8G2y?I*>{4a=Wa`FHG literal 0 HcmV?d00001 diff --git a/bip-0331/package_cpfp_flow.png b/bip-0331/package_cpfp_flow.png new file mode 100644 index 0000000000000000000000000000000000000000..6b48c5da65be1ba4fd465b801b1a31b8e614b083 GIT binary patch literal 57377 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�TfQUtYf4_^!B^xH$1s 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 A*#H0l literal 0 HcmV?d00001 diff --git a/bip-0331/package_info_only.png b/bip-0331/package_info_only.png new file mode 100644 index 0000000000000000000000000000000000000000..2bd02726064c9481ee53723039319124ff49fdd6 GIT binary patch literal 45150 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%0A(3NVW~}ceMaXZ5HN5@0 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 XA~c2Aa4IO92>fZN>Z%mqv=040N2XRQ literal 0 HcmV?d00001 diff --git a/bip-0331/sender_init_future_version.png b/bip-0331/sender_init_future_version.png new file mode 100644 index 0000000000000000000000000000000000000000..d4a21050ecb880e4291de1807b722a84f7f8f98e GIT binary patch literal 99293 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

U&L2sxXDrPb;>LQOo|3pBokjH#WH2 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 z zAhRr3gwdPDWOpuZFm_sNbX!%Mu4KMpZ5FN;oavQ%wx!BgcK{iLcn$Fc-#jX!pl%Yr z6uDU9qBlB$+luhWAx5K6d-1f%$dg}I1Va+6Nc?RAD8zpfMF%R*piZ9zgirQ<*WRQ~ z^W&ijHSvY=F)1#6nvxpvr7ditMK{uTkQwK$?^aUZG|pvJpwxgFK`o%{t7`4`w$(uL z6ce#lE`V@Dd;?+PTPi<{v3mEBO(r#poF>Uo3|Y+}QrT8TSBeb8*V7suax$&-8c*;A z0|Q*UddFBBJBwBkjzq8QCvXDzGVx<-3B70TtP`{)j2YlDhmS3&jDwb`x()$3>0mXR z70F^xu|yv9Fts&w>DV6Sdu25#jY&mi=RQ~-GoF=a&w5T$)3rd7DpE zi^{ATF(K$_DSIt(_Ff)eX{J{*@78`TQU~~KHx9en?E(`pykZ1IR74huXY(!W*){7Y zvmyaKHBS#;O@gUl0{Ff1H5Ou*0?NU&;80X-SrEh0Ga_FW4}SBOydUep0Vsv5r=6e8 zeqolrvSQde74|GR=hV6}ke@#WD0ehc*zZBO!9V&HfD6E^w!HZkGr3T?5|&n}rogeq zvP3NuB`zdV-HVFbO7I>b=P;7#7wNrl{=2sH)6iRMP_ZybURBW5Dm1s24JV~ZxEejA zAbsOIs)kh5?dpvWfg|_r@tsz|)JQcyNE@eH4I-Cr)jW3yaDq@ZDb2m41X9l*F%-FG zb$&!0d2pv>gLk^yXk4&rfC_@dYleF?4)8Q>wYB$ z@vd9m-TDCbK$BS?T~;TQWS+>=2^{5YhCDxtV840t) z590mGQNj^iW&1*;GDCFqIj-o%qy4Boni1n73X61RzM4W!7J}Y7h+|SJQ?&~+)1~}h zzgwZI)KcBcA>tNul7MAY)57hAcsvd1jnZS(f1?Xi^erE_O8HdLaq2sY4ldE|ymjEW z7~tH{w98m?d@=AMdj;|!ixb=gt-M!?Hl_8y$5m0M;=_?-6LAM){~{szNQd9UDg5Z? z9TtX+&7do}g3`-R{1AgD=SdjM0TwR>+?>OW5_l`K$Lek^&|3>PR|eN!h%dApj&jvr z)f|*z;(ej}VCeVg#*2rL^G7^bqO zK*U}!(<@()Kz7xH)QL3BQ{%M$i>aw6n4={LnAxoDhuAd4Lxv0zRGF3f%bjfVzt>ho ztj$o$Y71(vjLTQ+@C{(!8!olSUzfC#AYi^`y;PDYP3;0Q`Y`@3FMf^untBK@sGIXy zX`(-JKg$0tll~>XW#)I7rE6pdUet(SGgj(_<_l{*YpybZgclo7kJgT-7b-Jl z$}U1*q87R10Jnm;omtOa-$;<-3B8)b?DN3n9^I_tQM{(EUwek|3dI@`^!A|#ECVHa z-^`;v!f3CqJ{lY`5BJ^-jl1(zEzwAmpifs~oVS%1N!jv~%_ipIaau93t;VDyWGWTe zFt_u|8Ke?l@4HB1%^#gt)0a%TTp;&7Ju=oW8i2)U;6>I0J~}iHGtki9r!u>P!>B7o zwoXi!&|j8Y^GMx%ewSQYipGs5U~^q{PFWtH5jBFgLcrX1Wgg|D*-?;UXK2tNzGmH7 z{xfXpYFXSsXE#&r;u_S**7GC+lOW}Ku^|NH?8(qwdcBDR33jxh$`(zLK(YhW78o|l zZfn^e&T>eHUuNT`tj*9a$;}u6*Baw__M(}%)}sbzuT8wjokl9sFMw=neRsT{D-+3H z3tKdYQ}o>Rlgdik#ZXfTy&61uKBv=y>|QxoQz1a6aM;Sgu!ywXk4c__1e{=Q(=CM} zyq#wEi$pbEAlRk04f`G*7Vb71-QEUVnxR1>=e4-O4haPTsg-E)juo={ zTjI>i9ep9vZXl1|d+AFV1c-%@%Xx}BG}i^ObMEZ33jYKWMKZpTBG}ia!Z~7ZUv-nU zR6J}1m#!V|!_3zxFbyN(Hdl9*$0l2yZsP$7v@7ywFqJcR9iF9w#J#9%Kxs`(#b)d5 zJAp-vhs8I`S6|IS!tS#-Yo<|r|MfMUwOr@T(D!)Bexai!qMp z#Kd)0ebK41#ymm1=-z6CF0RRvcz}ZTL?b9@5b+)psmC64M@XWd(Gb5G&h6KJ@a0K| zQ>WwE8mQ3p&2Q>C_Rl5O;4upZzo62c)F5EiG%&X$Ok8@;jAdrO4<LL8nkw&DRJ~HeA%34h!jsVVA?TB?!^(w4%|LlQtdJ6$2`ScY=iO9!c2+Z9Bs0xtFZ?Q8D6`b@YR3xsHsUv?E<&Dix8}~-YALg=P7pJZ4!A6 z2qfxyNEc^lp+y|Qh5xq*ikCEE@f7%O@-D0@!tAX0H`SLhpIU>r_fzt0L`VNnh^iV) z8_VwyuxJxL?0NYY5~Dbe?g`NAOHw|Eq$owku!J30?WEmM(JbW6H%^cm;PohGf;T;t z(vX{1*jQf|2OQ%G5z#i7efA?BgP#6qwujKso3sataz52Ol@j&uA>oJ|ow#6Z5zMmd zb;w*9$=$26o4 z12M0$)k|!W`=L$oM1zI5mXwLHkA&rQCI;)@??!Gc` zIf#MX9=hm3FW8}T9p$9*Lm%wsf11mGIH!ID;9UftLZj0||9!pZjg`=$+%Y?eC@Jz= z#Df^1fvlGKHVsT{6?5>MarKjL{jh_;5HEyVNNuHe`tQGF1%-H+vy&1r5d$*XR?>X4 zgU{V_hKDim5RSMcSN~JN4TTsL@?iky|K|_KWOqiFGx(pu)KA9N-0BupZ+ym40Rs^T zd-};(F<#z(r{67fet!Or^@fVZ=+1^0i1<8AUI!cvu6Dt-wjW2v@jJhjD1@`sS#^B1>&iA=lJM9Zy1)Jh7fpNart>`Pky!> z56$_Xe|!Q31jEoV{NpgcDZT*w@{dnY$Q(3=j{R;7{qui^!S81bzX@^dcs}umVfJ6Y zs2|o}gL`3WvR+~35?$y1_4{81!Z_PLnSCq^f?m)VWe)-2zm`u;gl3Abyz_~+T55E2 q`LAdDZ>j(V4_so&>yJYn`)Jw?bV8xWik_pvf0CkdBB+~skNzKvvqXXb literal 0 HcmV?d00001 diff --git a/bip-0331/version_negotiation.png b/bip-0331/version_negotiation.png new file mode 100644 index 0000000000000000000000000000000000000000..5b2f48cb60fc52a93671762eb1e243d8cc9abdde GIT binary patch literal 50918 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 literal 0 HcmV?d00001 From 7be25f9fb20631c8c62d268c7f25ebe564a7a8e6 Mon Sep 17 00:00:00 2001 From: Ava Chow Date: Wed, 24 Apr 2024 19:06:23 -0400 Subject: [PATCH 188/454] ci: Fetch depth 2 for diffchecks --- .github/workflows/github-action-checks.yml | 2 ++ 1 file changed, 2 insertions(+) diff --git a/.github/workflows/github-action-checks.yml b/.github/workflows/github-action-checks.yml index bfc014ba5a..0b723e1b93 100644 --- a/.github/workflows/github-action-checks.yml +++ b/.github/workflows/github-action-checks.yml @@ -16,4 +16,6 @@ jobs: runs-on: ubuntu-latest steps: - uses: actions/checkout@v3 + with: + fetch-depth: 2 - run: scripts/diffcheck.sh From eb9007c8690436ea4a60189ab32e36686007e32c Mon Sep 17 00:00:00 2001 From: Ava Chow Date: Wed, 24 Apr 2024 19:13:48 -0400 Subject: [PATCH 189/454] diffchecks.sh: Build table first --- scripts/diffcheck.sh | 1 + 1 file changed, 1 insertion(+) diff --git a/scripts/diffcheck.sh b/scripts/diffcheck.sh index 4e4c4592f3..3d8a9e557d 100755 --- a/scripts/diffcheck.sh +++ b/scripts/diffcheck.sh @@ -1,5 +1,6 @@ #!/bin/bash +scripts/buildtable.pl >/tmp/table.mediawiki 2> /dev/null diff README.mediawiki /tmp/table.mediawiki | grep '^[<>] |' >/tmp/after.diff || true if git checkout HEAD^ && scripts/buildtable.pl >/tmp/table.mediawiki 2>/dev/null; then diff README.mediawiki /tmp/table.mediawiki | grep '^[<>] |' >/tmp/before.diff || true From dd88f24eebe7a42c285fd4d71ad32f6bf763f754 Mon Sep 17 00:00:00 2001 From: Luke Dashjr Date: Wed, 24 Apr 2024 23:20:48 +0000 Subject: [PATCH 190/454] Fix README --- README.mediawiki | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/README.mediawiki b/README.mediawiki index b5ae7bba14..41a93476b7 100644 --- a/README.mediawiki +++ b/README.mediawiki @@ -237,7 +237,7 @@ Those proposing changes should consider that ultimately consent may rest with th | Marek Palatinus, Pavol Rusnak | Standard | Final -|- style="background-color: #ffffcf" +|- style="background-color: #cfffcf" | [[bip-0044.mediawiki|44]] | Applications | Multi-Account Hierarchy for Deterministic Wallets @@ -251,13 +251,13 @@ Those proposing changes should consider that ultimately consent may rest with th | Manuel Araoz, Ryan X. Charles, Matias Alejo Garcia | Standard | Proposed -|- +|- style="background-color: #cfffcf" | [[bip-0047.mediawiki|47]] | Applications | Reusable Payment Codes for Hierarchical Deterministic Wallets | Justus Ranvier | Informational -| Draft +| Final |- style="background-color: #ffffcf" | [[bip-0048.mediawiki|48]] | Applications From fd5d424f551bf740f6f651b0158667d1fd052193 Mon Sep 17 00:00:00 2001 From: Ava Chow Date: Wed, 24 Apr 2024 16:27:24 -0400 Subject: [PATCH 191/454] 39: Remove other implementation sections --- bip-0039.mediawiki | 69 ---------------------------------------------- 1 file changed, 69 deletions(-) diff --git a/bip-0039.mediawiki b/bip-0039.mediawiki index 1c4845e580..51fe33d834 100644 --- a/bip-0039.mediawiki +++ b/bip-0039.mediawiki @@ -138,72 +138,3 @@ Also see https://github.com/bip32JP/bip32JP.github.io/blob/master/test_JP_BIP39. Reference implementation including wordlists is available from http://github.com/trezor/python-mnemonic - -==Other Implementations== - -Go: -* https://github.com/tyler-smith/go-bip39 - -Python: -* https://github.com/meherett/python-hdwallet - -Elixir: -* https://github.com/aerosol/mnemo - -Objective-C: -* https://github.com/nybex/NYMnemonic - -Haskell: -* https://github.com/haskoin/haskoin - -.NET (Standard): -* https://www.nuget.org/packages/dotnetstandard-bip39/ - -.NET C# (PCL): -* https://github.com/Thashiznets/BIP39.NET - -.NET C# (PCL): -* https://github.com/NicolasDorier/NBitcoin - -JavaScript: -* https://github.com/bitpay/bitcore/tree/master/packages/bitcore-mnemonic -* https://github.com/bitcoinjs/bip39 (used by [[https://github.com/blockchain/My-Wallet-V3/blob/v3.8.0/src/hd-wallet.js#L121-L146|blockchain.info]]) -* https://github.com/dashhive/DashPhrase.js -* https://github.com/hujiulong/web-bip39 - -TypeScript: -* https://github.com/bitauth/libauth - -Java: -* https://github.com/bitcoinj/bitcoinj/blob/master/core/src/main/java/org/bitcoinj/crypto/MnemonicCode.java - -Ruby: -* https://github.com/sreekanthgs/bip_mnemonic - -Rust: -* https://github.com/maciejhirsz/tiny-bip39/ -* https://github.com/koushiro/bip0039-rs - -Smalltalk: -* https://github.com/eMaringolo/pharo-bip39mnemonic - -Swift: -* https://github.com/CikeQiu/CKMnemonic -* https://github.com/yuzushioh/WalletKit -* https://github.com/pengpengliu/BIP39 -* https://github.com/matter-labs/web3swift/blob/develop/Sources/web3swift/KeystoreManager/BIP39.swift -* https://github.com/zcash-hackworks/MnemonicSwift -* https://github.com/ShenghaiWang/BIP39 -* https://github.com/anquii/BIP39 - -C++: -* https://github.com/libbitcoin/libbitcoin-system/blob/master/include/bitcoin/system/wallet/mnemonic.hpp - -C (with Python/Java/Javascript bindings): -* https://github.com/ElementsProject/libwally-core - -Python: -* https://github.com/scgbckbone/btc-hd-wallet - -Dart: -* https://github.com/dart-bitcoin/bip39 From 05b626debfa5f862bafd7fc2d1e7dc1e5974940f Mon Sep 17 00:00:00 2001 From: Ava Chow Date: Wed, 24 Apr 2024 16:27:24 -0400 Subject: [PATCH 192/454] 38: Remove other implementation sections --- bip-0038.mediawiki | 3 --- 1 file changed, 3 deletions(-) diff --git a/bip-0038.mediawiki b/bip-0038.mediawiki index 7f99b1a76a..5fd24ada4a 100644 --- a/bip-0038.mediawiki +++ b/bip-0038.mediawiki @@ -214,9 +214,6 @@ Added to alpha version of Casascius Bitcoin Address Utility for Windows availabl Click "Tools" then "PPEC Keygen" (provisional name) -==Other implementations== -* Javascript - https://github.com/bitcoinjs/bip38 - ==Test vectors== ===No compression, no EC multiply=== From a26656133b3ba67bf5073132ab47a357a4ddc9fc Mon Sep 17 00:00:00 2001 From: Ava Chow Date: Thu, 25 Apr 2024 10:17:20 -0400 Subject: [PATCH 193/454] 38: Remove dead reference implementation link --- bip-0038.mediawiki | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/bip-0038.mediawiki b/bip-0038.mediawiki index 5fd24ada4a..986ddeeaf4 100644 --- a/bip-0038.mediawiki +++ b/bip-0038.mediawiki @@ -209,8 +209,7 @@ The preliminary values of 16384, 8, and 8 are hoped to offer the following prope ==Reference implementation== Added to alpha version of Casascius Bitcoin Address Utility for Windows available at: -* via https: https://casascius.com/btcaddress-alpha.zip -* at github: https://github.com/casascius/Bitcoin-Address-Utility +* https://github.com/casascius/Bitcoin-Address-Utility Click "Tools" then "PPEC Keygen" (provisional name) From e3f7a260628bbdbfd4438281193926d2b3bce25f Mon Sep 17 00:00:00 2001 From: Ava Chow Date: Wed, 24 Apr 2024 16:27:24 -0400 Subject: [PATCH 194/454] 85: Remove other implementation sections --- bip-0085.mediawiki | 12 ------------ 1 file changed, 12 deletions(-) diff --git a/bip-0085.mediawiki b/bip-0085.mediawiki index d5557fbf7b..738227ac01 100644 --- a/bip-0085.mediawiki +++ b/bip-0085.mediawiki @@ -96,18 +96,6 @@ OUTPUT * Python library implementation: [https://github.com/ethankosakovsky/bip85] * JavaScript library implementation: [https://github.com/hoganri/bip85-js] -===Other Implementations=== - -* JavaScript library implementation: [https://github.com/hoganri/bip85-js] - -* Coldcard Firmware: [https://github.com/Coldcard/firmware/pull/39] - -* Ian Coleman's Mnemonic Code Converter: [https://github.com/iancoleman/bip39] and [https://iancoleman.io/bip39/] - -* AirGap Vault: [https://github.com/airgap-it/airgap-vault/commit/d64332fc2f332be622a1229acb27f621e23774d6] - -* btc_hd_wallet: [https://github.com/scgbckbone/btc-hd-wallet] - ==Applications== The Application number defines how entropy will be used post processing. Some basic examples follow: From 448de3cafd1c52f2e4b72c608f518e7cd261ca9c Mon Sep 17 00:00:00 2001 From: Ava Chow Date: Thu, 25 Apr 2024 10:23:28 -0400 Subject: [PATCH 195/454] 21: Remove other libraries from reference implementations --- bip-0021.mediawiki | 11 +++-------- 1 file changed, 3 insertions(+), 8 deletions(-) diff --git a/bip-0021.mediawiki b/bip-0021.mediawiki index cdc37baae7..9fa4823256 100644 --- a/bip-0021.mediawiki +++ b/bip-0021.mediawiki @@ -120,11 +120,6 @@ Some future version that has variables which are (currently) not understood but Characters must be URI encoded properly. -== Reference Implementations == -=== Bitcoin clients === -* Bitcoin-Qt supports the old version of Bitcoin URIs (ie without the req- prefix), with Windows and KDE integration as of commit 70f55355e29c8e45b607e782c5d76609d23cc858. - -=== Libraries === -* Javascript - https://github.com/bitcoinjs/bip21 -* Java - https://github.com/SandroMachado/BitcoinPaymentURI -* Swift - https://github.com/SandroMachado/BitcoinPaymentURISwift +== Reference Implementation == + +Bitcoin-Qt supports the old version of Bitcoin URIs (ie without the req- prefix), with Windows and KDE integration as of commit 70f55355e29c8e45b607e782c5d76609d23cc858. From 6c729c4b418006def78caad0d921f1841c4db1ee Mon Sep 17 00:00:00 2001 From: Ethan Heilman Date: Thu, 25 Apr 2024 13:03:00 -0400 Subject: [PATCH 196/454] Renamed to use BIP-0347 --- bip-???-cat.mediawiki => bip-0347.mediawiki | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) rename bip-???-cat.mediawiki => bip-0347.mediawiki (99%) diff --git a/bip-???-cat.mediawiki b/bip-0347.mediawiki similarity index 99% rename from bip-???-cat.mediawiki rename to bip-0347.mediawiki index d7746fe4c0..f85b2e9f34 100644 --- a/bip-???-cat.mediawiki +++ b/bip-0347.mediawiki @@ -1,5 +1,5 @@

-  BIP: ?
+  BIP: 347
   Layer: Consensus (soft fork)
   Title: OP_CAT
   Author: Ethan Heilman 

From 0a3869d1021bfc0e4c5e8779d1ff33fe67846af8 Mon Sep 17 00:00:00 2001
From: Ethan Heilman 
Date: Thu, 25 Apr 2024 13:16:55 -0400
Subject: [PATCH 197/454] Fixes comment URI

---
 bip-0347.mediawiki | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/bip-0347.mediawiki b/bip-0347.mediawiki
index f85b2e9f34..a05c2100e8 100644
--- a/bip-0347.mediawiki
+++ b/bip-0347.mediawiki
@@ -4,7 +4,7 @@
   Title: OP_CAT
   Author: Ethan Heilman 
           Armin Sabouri 
-  Comments-URI: https://github.com/bitcoin/bips/wiki/Comments:BIP-op-cat
+  Comments-URI: https://github.com/bitcoin/bips/wiki/Comments:BIP-0347
   Status: Draft
   Type: Standards Track
   Created: 2023-10-21

From 7ed8f6f38c67ede30e38114632b3fa6bbe396800 Mon Sep 17 00:00:00 2001
From: Ethan Heilman 
Date: Thu, 25 Apr 2024 13:42:24 -0400
Subject: [PATCH 198/454] Better quantum resistant section based Tim's comments

Adds additional acks
---
 bip-0347.mediawiki | 5 +++--
 1 file changed, 3 insertions(+), 2 deletions(-)

diff --git a/bip-0347.mediawiki b/bip-0347.mediawiki
index a05c2100e8..1e75ffc144 100644
--- a/bip-0347.mediawiki
+++ b/bip-0347.mediawiki
@@ -36,7 +36,7 @@ OP_CAT aims to expand the toolbox of the tapscript developer with a simple, modu
 
 * Bitstream, a protocol for the atomic swap (fair exchange) of bitcoins for decryption keys, that enables decentralized file hosting systems paid in Bitcoin. While such swaps are currently possible on Bitcoin without OP_CAT they require the use of complex and computationally expensive Verifiable Computation cryptographic techniques. OP_CAT would remove this requirement on Verifiable Computation, making such protocols far more practical to build in Bitcoin. R. Linus, "BitStream: Decentralized File Hosting Incentivised via Bitcoin Payments", 2023, https://robinlinus.com/bitstream.pdf
 * Tree signatures provide a multisignature script whose size can be logarithmic in the number of public keys and can encode spend conditions beyond n-of-m. For instance a transaction less than 1KB in size could support tree signatures with a thousand public keys. This also enables generalized logical spend conditions.  P. Wuille, "Multisig on steroids using tree signatures", 2015, https://blog.blockstream.com/en-treesignatures/
-* Post-Quantum Lamport signatures in Bitcoin transactions. Lamport signatures merely require the ability to hash and concatenate values on the stack. J. Rubin, "[bitcoin-dev] OP_CAT Makes Bitcoin Quantum Secure [was CheckSigFromStack for Arithmetic Values]", 2021, https://lists.linuxfoundation.org/pipermail/bitcoin-dev/2021-July/019233.html It is an open question if the quantum resistance of Lamport signatures can be preserved when used in a taproot output.
+* Post-Quantum Lamport signatures in Bitcoin transactions. Lamport signatures merely require the ability to hash and concatenate values on the stack. J. Rubin, "[bitcoin-dev] OP_CAT Makes Bitcoin Quantum Secure [was CheckSigFromStack for Arithmetic Values]", 2021, https://lists.linuxfoundation.org/pipermail/bitcoin-dev/2021-July/019233.html It is an open question if a tapscript commitment would preserve the quantum resistance of Lamport signatures. Beyond this question, the use of Lamport Signatures in taproot outputs is unlikely to be quantum resistant even if the script spend-path is made quantum resistant. This is because taproot outputs can also be spent with a key. An attacker with a sufficiently powerful quantum computer could bypass the taproot script spend-path by finding the discrete log of the taproot output and thus spending the output using the key spend-path. The use of "Nothing Up My Sleeve" (NUMS) points as described in [[bip-0341.mediawiki|BIP341]] to disable the key spend-path does not disable the key spend-path against a quantum attacker as NUMS relies on the hardness of finding discrete logs. We are not aware of any mechanism which could disable the key spend-path in a taproot output without a softfork change to taproot.
 * Non-equivocation contracts T. Ruffing, A. Kate, D. Schröder, "Liar, Liar, Coins on Fire: Penalizing Equivocation by Loss of Bitcoins", 2015, https://citeseerx.ist.psu.edu/viewdoc/download?doi=10.1.1.727.6262&rep=rep1&type=pdf in tapscript provide a mechanism to punish equivocation/double spending in Bitcoin payment channels. OP_CAT enables this by enforcing rules on the spending transaction's nonce. The capability is a useful building block for payment channels and other Bitcoin protocols.
 * Vaults M. Moser, I. Eyal, and E. G. Sirer, Bitcoin Covenants, http://fc16.ifca.ai/bitcoin/papers/MES16.pdf which are a specialized covenant that allows a user to block a malicious party who has compromised the user's secret key from stealing the funds in that output. As shown in A. Poelstra, "CAT and Schnorr Tricks II", 2021, https://www.wpsoftware.net/andrew/blog/cat-and-schnorr-tricks-ii.html OP_CAT is sufficient to build vaults in Bitcoin.
 * Replicating CheckSigFromStack A. Poelstra, "CAT and Schnorr Tricks I", 2021, https://medium.com/blockstream/cat-and-schnorr-tricks-i-faf1b59bd298 which would allow the creation of simple covenants and other advanced contracts without having to presign spending transactions, possibly reducing complexity and the amount of data that needs to be stored. Originally shown to work with Schnorr signatures, this result has been extended to ECDSA signatures R. Linus, "Covenants with CAT and ECDSA", 2023, https://gist.github.com/RobinLinus/9a69f5552be94d13170ec79bf34d5e85#file-covenants_cat_ecdsa-md.
@@ -102,4 +102,5 @@ An alternative implementation of OP_CAT can be found in Elements Roose S.,
 
 ==Acknowledgements==
 
-We wish to acknowledge Dan Gould for encouraging and helping review this effort. We also want to thank Madars Virza, Jeremy Rubin, Andrew Poelstra, Bob Summerwill for their feedback, review and helpful comments.
+We wish to acknowledge Dan Gould for encouraging and helping review this effort. We also want to thank Madars Virza, Jeremy Rubin, Andrew Poelstra, Bob Summerwill, 
+Tim Ruffing and Johan T. Halseth for their feedback, review and helpful comments.

From 7a104491862379e88662a39d1a2b613c907e503e Mon Sep 17 00:00:00 2001
From: Murch 
Date: Thu, 25 Apr 2024 14:10:10 -0400
Subject: [PATCH 199/454] Mention that BIP350 reduces scope of bech32 to v0

---
 bip-0173.mediawiki | 10 ++++++++++
 1 file changed, 10 insertions(+)

diff --git a/bip-0173.mediawiki b/bip-0173.mediawiki
index 1fdd8bed3c..7087fffa20 100644
--- a/bip-0173.mediawiki
+++ b/bip-0173.mediawiki
@@ -11,6 +11,7 @@
   Created: 2017-03-20
   License: BSD-2-Clause
   Replaces: 142
+  Superseded-By: 350
 
==Introduction== @@ -403,3 +404,12 @@ separator). This document is inspired by the [https://rusty.ozlabs.org/?p=578 address proposal] by Rusty Russell, the [https://lists.linuxfoundation.org/pipermail/bitcoin-dev/2014-February/004402.html base32] proposal by Mark Friedenbach, and had input from Luke Dashjr, Johnson Lau, Eric Lombrozo, Peter Todd, and various other reviewers. + +==Disclosures (added 2024)== + +Due to an oversight in the design of bech32, this checksum scheme is not always +robust against +[[https://gist.github.com/sipa/a9845b37c1b298a7301c33a04090b2eb|the insertion +and deletion of fewer than 5 consecutive characters]]. Due to this weakness, +[[bip-0350.mediawiki|BIP-350]] proposes using the scheme described in this BIP +only for Native Segwit v0 outputs. From 852502b9cf0568dc4c75d93aaaaee3d102002ec7 Mon Sep 17 00:00:00 2001 From: Ethan Heilman Date: Thu, 25 Apr 2024 20:32:52 -0400 Subject: [PATCH 200/454] Specifies exact tree signature limit (suggested by Ali Sherief) --- bip-0347.mediawiki | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/bip-0347.mediawiki b/bip-0347.mediawiki index 1e75ffc144..e43bd72f0f 100644 --- a/bip-0347.mediawiki +++ b/bip-0347.mediawiki @@ -35,7 +35,7 @@ Bitcoin tapscript lacks a general purpose way of combining objects on the stack OP_CAT aims to expand the toolbox of the tapscript developer with a simple, modular, and useful opcode in the spirit of Unix R. Pike and B. Kernighan, "Program design in the UNIX environment", 1983, https://harmful.cat-v.org/cat-v/unix_prog_design.pdf. To demonstrate the usefulness of OP_CAT below we provide a non-exhaustive list of some usecases that OP_CAT would enable: * Bitstream, a protocol for the atomic swap (fair exchange) of bitcoins for decryption keys, that enables decentralized file hosting systems paid in Bitcoin. While such swaps are currently possible on Bitcoin without OP_CAT they require the use of complex and computationally expensive Verifiable Computation cryptographic techniques. OP_CAT would remove this requirement on Verifiable Computation, making such protocols far more practical to build in Bitcoin. R. Linus, "BitStream: Decentralized File Hosting Incentivised via Bitcoin Payments", 2023, https://robinlinus.com/bitstream.pdf -* Tree signatures provide a multisignature script whose size can be logarithmic in the number of public keys and can encode spend conditions beyond n-of-m. For instance a transaction less than 1KB in size could support tree signatures with a thousand public keys. This also enables generalized logical spend conditions. P. Wuille, "Multisig on steroids using tree signatures", 2015, https://blog.blockstream.com/en-treesignatures/ +* Tree signatures provide a multisignature script whose size can be logarithmic in the number of public keys and can encode spend conditions beyond n-of-m. For instance a transaction less than 1KB in size could support tree signatures with up to 4,294,967,296 public keys. This also enables generalized logical spend conditions. P. Wuille, "Multisig on steroids using tree signatures", 2015, https://blog.blockstream.com/en-treesignatures/ * Post-Quantum Lamport signatures in Bitcoin transactions. Lamport signatures merely require the ability to hash and concatenate values on the stack. J. Rubin, "[bitcoin-dev] OP_CAT Makes Bitcoin Quantum Secure [was CheckSigFromStack for Arithmetic Values]", 2021, https://lists.linuxfoundation.org/pipermail/bitcoin-dev/2021-July/019233.html It is an open question if a tapscript commitment would preserve the quantum resistance of Lamport signatures. Beyond this question, the use of Lamport Signatures in taproot outputs is unlikely to be quantum resistant even if the script spend-path is made quantum resistant. This is because taproot outputs can also be spent with a key. An attacker with a sufficiently powerful quantum computer could bypass the taproot script spend-path by finding the discrete log of the taproot output and thus spending the output using the key spend-path. The use of "Nothing Up My Sleeve" (NUMS) points as described in [[bip-0341.mediawiki|BIP341]] to disable the key spend-path does not disable the key spend-path against a quantum attacker as NUMS relies on the hardness of finding discrete logs. We are not aware of any mechanism which could disable the key spend-path in a taproot output without a softfork change to taproot. * Non-equivocation contracts T. Ruffing, A. Kate, D. Schröder, "Liar, Liar, Coins on Fire: Penalizing Equivocation by Loss of Bitcoins", 2015, https://citeseerx.ist.psu.edu/viewdoc/download?doi=10.1.1.727.6262&rep=rep1&type=pdf in tapscript provide a mechanism to punish equivocation/double spending in Bitcoin payment channels. OP_CAT enables this by enforcing rules on the spending transaction's nonce. The capability is a useful building block for payment channels and other Bitcoin protocols. * Vaults M. Moser, I. Eyal, and E. G. Sirer, Bitcoin Covenants, http://fc16.ifca.ai/bitcoin/papers/MES16.pdf which are a specialized covenant that allows a user to block a malicious party who has compromised the user's secret key from stealing the funds in that output. As shown in A. Poelstra, "CAT and Schnorr Tricks II", 2021, https://www.wpsoftware.net/andrew/blog/cat-and-schnorr-tricks-ii.html OP_CAT is sufficient to build vaults in Bitcoin. From 50e750a882f525cc9a297b75ca35682f3deb1f95 Mon Sep 17 00:00:00 2001 From: Pieter Wuille Date: Mon, 8 Jan 2024 13:08:46 -0500 Subject: [PATCH 201/454] Clarify exactly which scripts are witness outputs --- bip-0141.mediawiki | 10 +++++++--- 1 file changed, 7 insertions(+), 3 deletions(-) diff --git a/bip-0141.mediawiki b/bip-0141.mediawiki index eb2fc74abd..117ca59df6 100644 --- a/bip-0141.mediawiki +++ b/bip-0141.mediawiki @@ -83,19 +83,23 @@ If all transactions in a block do not have witness data, the commitment is optio === Witness program === -A scriptPubKey (or redeemScript as defined in BIP16/P2SH) that consists of a select subset of opcodes (OP_0,OP_1,OP_2,...,OP_16) followed by a data push between 2 and 40 bytes gets a new special meaning. The value of the first push is called the "version byte". The following byte vector pushed is called the "witness program". +A scriptPubKey (or redeemScript as defined in BIP16/P2SH) that consists of a 1-byte push opcode (one of OP_0,OP_1,OP_2,...,OP_16) followed by a direct data push between 2 and 40 bytes gets a new special meaning. The value of the first push is called the "version byte". The following byte vector pushed is called the "witness program". +In more detail, this means a scriptPubKey or redeemScript which consists of (in order): +* First, byte 0x00 (OP_0) or any byte between 0x51 (OP_1) and 0x60 (OP_16) inclusive (the version byte). +* Then, a byte ''L'' between 0x02 (push of 2 bytes) and 0x28 (push of 40 bytes) inclusive. +* Finally, ''L'' arbitrary bytes (the witness program). There are two cases in which witness validation logic are triggered. Each case determines the location of the witness version byte and program, as well as the form of the scriptSig: # Triggered by a scriptPubKey that is exactly a push of a version byte, plus a push of a witness program. The scriptSig must be exactly empty or validation fails. (''"native witness program"'') # Triggered when a scriptPubKey is a P2SH script, and the BIP16 redeemScript pushed in the scriptSig is exactly a push of a version byte plus a push of a witness program. The scriptSig must be exactly a push of the BIP16 redeemScript or validation fails. (''"P2SH witness program"'') -If the version byte is 0, and the witness program is 20 bytes: +If the version byte is 0, and the witness program is 20 bytes (''L = 20''): * It is interpreted as a pay-to-witness-public-key-hash (P2WPKH) program. * The witness must consist of exactly 2 items (≤ 520 bytes each). The first one a signature, and the second one a public key. * The HASH160 of the public key must match the 20-byte witness program. * After normal script evaluation, the signature is verified against the public key with CHECKSIG operation. The verification must result in a single TRUE on the stack. -If the version byte is 0, and the witness program is 32 bytes: +If the version byte is 0, and the witness program is 32 bytes (''L = 32''): * It is interpreted as a pay-to-witness-script-hash (P2WSH) program. * The witness must consist of an input stack to feed to the script, followed by a serialized script (witnessScript). * The witnessScript (≤ 10,000 bytes) is popped off the initial witness stack. SHA256 of the witnessScript must match the 32-byte witness program. From c10870a390a7141eb223ed8141cab48668239536 Mon Sep 17 00:00:00 2001 From: Ethan Heilman Date: Fri, 26 Apr 2024 13:59:28 -0400 Subject: [PATCH 202/454] Adds comma Co-authored-by: Mark "Murch" Erhardt --- bip-0347.mediawiki | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/bip-0347.mediawiki b/bip-0347.mediawiki index e43bd72f0f..24df645625 100644 --- a/bip-0347.mediawiki +++ b/bip-0347.mediawiki @@ -20,7 +20,7 @@ This document is licensed under the 3-clause BSD license. ==Specification== -When evaluated the OP_CAT instruction: +When evaluated, the OP_CAT instruction: # Pops the top two values off the stack, # concatenates the popped values together in stack order, # and then pushes the concatenated value on the top of the stack. From 5413e18fd93c078d4c12d4845a08b7c9a9b24ada Mon Sep 17 00:00:00 2001 From: Ethan Heilman Date: Fri, 26 Apr 2024 14:01:59 -0400 Subject: [PATCH 203/454] Consistent formatting for Section Headings Co-authored-by: Mark "Murch" Erhardt --- bip-0347.mediawiki | 1 + 1 file changed, 1 insertion(+) diff --git a/bip-0347.mediawiki b/bip-0347.mediawiki index 24df645625..dca210006d 100644 --- a/bip-0347.mediawiki +++ b/bip-0347.mediawiki @@ -30,6 +30,7 @@ Given the stack ''[x1, x2]'', where ''x2'' is at the top of the This opcode would be activated via a soft fork by redefining the tapscript opcode OP_SUCCESS126 (126 in decimal and 0x7e in hexadecimal) to OP_CAT. ==Motivation== + Bitcoin tapscript lacks a general purpose way of combining objects on the stack restricting the expressiveness and power of tapscript. This prevents among many other things the ability to construct and evaluate merkle trees and other hashed data structures in tapscript. OP_CAT by adding a general purpose way to concatenate stack values would overcome this limitation and greatly increase the functionality of tapscript. OP_CAT aims to expand the toolbox of the tapscript developer with a simple, modular, and useful opcode in the spirit of Unix R. Pike and B. Kernighan, "Program design in the UNIX environment", 1983, https://harmful.cat-v.org/cat-v/unix_prog_design.pdf. To demonstrate the usefulness of OP_CAT below we provide a non-exhaustive list of some usecases that OP_CAT would enable: From dbc612edfa137ce1f1cbcb9d40f58773758315ae Mon Sep 17 00:00:00 2001 From: Ethan Heilman Date: Fri, 26 Apr 2024 14:02:13 -0400 Subject: [PATCH 204/454] Consistent formatting for Section Headings Co-authored-by: Mark "Murch" Erhardt --- bip-0347.mediawiki | 1 + 1 file changed, 1 insertion(+) diff --git a/bip-0347.mediawiki b/bip-0347.mediawiki index dca210006d..e825284c22 100644 --- a/bip-0347.mediawiki +++ b/bip-0347.mediawiki @@ -16,6 +16,7 @@ This BIP introduces OP_CAT as a tapscript opcode which allows the concatenation of two values on the stack. OP_CAT would be activated via a soft fork by redefining the opcode OP_SUCCESS126 (126 in decimal and 0x7e in hexadecimal). This is the same opcode value used by the original OP_CAT. == Copyright == + This document is licensed under the 3-clause BSD license. ==Specification== From a05543cc588ebcb266aa3251472324671e384afe Mon Sep 17 00:00:00 2001 From: Ethan Heilman Date: Mon, 29 Apr 2024 18:44:24 -0400 Subject: [PATCH 205/454] Changes title of BIP to "Enable OP_CAT in Tapscript" --- bip-0347.mediawiki | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/bip-0347.mediawiki b/bip-0347.mediawiki index e825284c22..1a0feb8896 100644 --- a/bip-0347.mediawiki +++ b/bip-0347.mediawiki @@ -1,7 +1,7 @@
   BIP: 347
   Layer: Consensus (soft fork)
-  Title: OP_CAT
+  Title: Enable OP_CAT in Tapscript
   Author: Ethan Heilman 
           Armin Sabouri 
   Comments-URI: https://github.com/bitcoin/bips/wiki/Comments:BIP-0347

From 1d5530443dd660dc090145061bc146d4c64ffab3 Mon Sep 17 00:00:00 2001
From: Ethan Heilman 
Date: Mon, 29 Apr 2024 19:36:26 -0400
Subject: [PATCH 206/454] OP_CAT in Tapscript
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit

Co-authored-by: Vojtěch Strnad <43024885+vostrnad@users.noreply.github.com>
---
 bip-0347.mediawiki | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/bip-0347.mediawiki b/bip-0347.mediawiki
index 1a0feb8896..3070d14e48 100644
--- a/bip-0347.mediawiki
+++ b/bip-0347.mediawiki
@@ -1,7 +1,7 @@
 
   BIP: 347
   Layer: Consensus (soft fork)
-  Title: Enable OP_CAT in Tapscript
+  Title: OP_CAT in Tapscript
   Author: Ethan Heilman 
           Armin Sabouri 
   Comments-URI: https://github.com/bitcoin/bips/wiki/Comments:BIP-0347

From 3d78cc08863864d7caea85a229fb223dea25540f Mon Sep 17 00:00:00 2001
From: Ethan Heilman 
Date: Mon, 29 Apr 2024 21:04:15 -0400
Subject: [PATCH 207/454] Fixes typos

Co-authored-by: Mark "Murch" Erhardt 
---
 bip-0347.mediawiki | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/bip-0347.mediawiki b/bip-0347.mediawiki
index 3070d14e48..622d7b46ec 100644
--- a/bip-0347.mediawiki
+++ b/bip-0347.mediawiki
@@ -56,7 +56,7 @@ While the OP_SUCCESSx opcode upgrade path could enable us to increase the stack
 
 ==Backwards Compatibility==
 
-OP_CAT usage in an non-tapscript script will continue to trigger the SCRIPT_ERR_DISABLED_OPCODE. The only change would be to OP_CAT usage in tapscript. This change to tapscript would be activated a soft fork that redefines an OP_SUCCESSx opcode (OP_SUCCESS126) to OP_CAT.
+OP_CAT usage in a non-tapscript script will continue to trigger the SCRIPT_ERR_DISABLED_OPCODE. The only change would be to OP_CAT usage in tapscript. This change to tapscript would be activated as a soft fork that redefines an OP_SUCCESSx opcode (OP_SUCCESS126) to OP_CAT.
 
 ==Reference implementation==
 

From f75184b8d8c8b723d8efb0a02916f9d874226efc Mon Sep 17 00:00:00 2001
From: Yannick Seurin 
Date: Tue, 30 Apr 2024 11:34:30 +0200
Subject: [PATCH 208/454] updating info on multi-, threshold, and blind
 signatures

---
 bip-0340.mediawiki | 10 +++++-----
 1 file changed, 5 insertions(+), 5 deletions(-)

diff --git a/bip-0340.mediawiki b/bip-0340.mediawiki
index c94191670b..7746018bb7 100644
--- a/bip-0340.mediawiki
+++ b/bip-0340.mediawiki
@@ -62,7 +62,7 @@ Since we would like to avoid the fragility that comes with short hashes, the ''e
 
 '''Key prefixing''' Using the verification rule above directly makes Schnorr signatures vulnerable to "related-key attacks" in which a third party can convert a signature ''(R, s)'' for public key ''P'' into a signature ''(R, s + a⋅hash(R || m))'' for public key ''P + a⋅G'' and the same message ''m'', for any given additive tweak ''a'' to the signing key. This would render signatures insecure when keys are generated using [[bip-0032.mediawiki#public-parent-key--public-child-key|BIP32's unhardened derivation]] and other methods that rely on additive tweaks to existing keys such as Taproot.
 
-To protect against these attacks, we choose ''key prefixed''A limitation of committing to the public key (rather than to a short hash of it, or not at all) is that it removes the ability for public key recovery or verifying signatures against a short public key hash. These constructions are generally incompatible with batch verification. Schnorr signatures which means that the public key is prefixed to the message in the challenge hash input. This changes the equation to ''s⋅G = R + hash(R || P || m)⋅P''. [https://eprint.iacr.org/2015/1135.pdf It can be shown] that key prefixing protects against related-key attacks with additive tweaks. In general, key prefixing increases robustness in multi-user settings, e.g., it seems to be a requirement for proving the MuSig multisignature scheme secure (see Applications below).
+To protect against these attacks, we choose ''key prefixed''A limitation of committing to the public key (rather than to a short hash of it, or not at all) is that it removes the ability for public key recovery or verifying signatures against a short public key hash. These constructions are generally incompatible with batch verification. Schnorr signatures which means that the public key is prefixed to the message in the challenge hash input. This changes the equation to ''s⋅G = R + hash(R || P || m)⋅P''. [https://eprint.iacr.org/2015/1135.pdf It can be shown] that key prefixing protects against related-key attacks with additive tweaks. In general, key prefixing increases robustness in multi-user settings, e.g., it seems to be a requirement for proving the MuSig2 multisignature scheme secure (see Applications below).
 
 We note that key prefixing is not strictly necessary for transaction signatures as used in Bitcoin currently, because signed transactions indirectly commit to the public keys already, i.e., ''m'' contains a commitment to ''pk''. However, this indirect commitment should not be relied upon because it may change with proposals such as SIGHASH_NOINPUT ([[bip-0118.mediawiki|BIP118]]), and would render the signature scheme unsuitable for other purposes than signing transactions, e.g., [https://bitcoin.org/en/developer-reference#signmessage signing ordinary messages].
 
@@ -165,7 +165,7 @@ It should be noted that various alternative signing algorithms can be used to pr
 
 '''Nonce exfiltration protection''' It is possible to strengthen the nonce generation algorithm using a second device. In this case, the second device contributes randomness which the actual signer provably incorporates into its nonce. This prevents certain attacks where the signer device is compromised and intentionally tries to leak the secret key through its nonce selection.
 
-'''Multisignatures''' This signature scheme is compatible with various types of multisignature and threshold schemes such as [https://eprint.iacr.org/2018/068 MuSig], where a single public key requires holders of multiple secret keys to participate in signing (see Applications below).
+'''Multisignatures''' This signature scheme is compatible with various types of multisignature and threshold schemes such as [https://eprint.iacr.org/2020/1261.pdf MuSig2], where a single public key requires holders of multiple secret keys to participate in signing (see Applications below).
 '''It is important to note that multisignature signing schemes in general are insecure with the ''rand'' generation from the default signing algorithm above (or any other deterministic method).'''
 
 '''Precomputed public key data''' For many uses the compressed 33-byte encoding of the public key corresponding to the secret key may already be known, making it easy to evaluate ''has_even_y(P)'' and ''bytes(P)''. As such, having signers supply this directly may be more efficient than recalculating the public key from the secret key. However, if this optimization is used and additionally the signature verification at the end of the signing algorithm is dropped for increased efficiency, signers must ensure the public key is correctly calculated and not taken from untrusted sources.
@@ -264,9 +264,9 @@ While recent academic papers claim that they are also possible with ECDSA, conse
 
 === Multisignatures and Threshold Signatures ===
 
-By means of an interactive scheme such as [https://eprint.iacr.org/2018/068 MuSig], participants can aggregate their public keys into a single public key which they can jointly sign for. This allows ''n''-of-''n'' multisignatures which, from a verifier's perspective, are no different from ordinary signatures, giving improved privacy and efficiency versus ''CHECKMULTISIG'' or other means.
+By means of an interactive scheme such as [https://eprint.iacr.org/2020/1261.pdf MuSig2], participants can aggregate their public keys into a single public key which they can jointly sign for. This allows ''n''-of-''n'' multisignatures which, from a verifier's perspective, are no different from ordinary signatures, giving improved privacy and efficiency versus ''CHECKMULTISIG'' or other means.
 
-Moreover, Schnorr signatures are compatible with [https://web.archive.org/web/20031003232851/http://www.research.ibm.com/security/dkg.ps distributed key generation], which enables interactive threshold signatures schemes, e.g., the schemes described by [http://cacr.uwaterloo.ca/techreports/2001/corr2001-13.ps Stinson and Strobl (2001)] or [https://web.archive.org/web/20060911151529/http://theory.lcs.mit.edu/~stasio/Papers/gjkr03.pdf Gennaro, Jarecki and Krawczyk (2003)]. These protocols make it possible to realize ''k''-of-''n'' threshold signatures, which ensure that any subset of size ''k'' of the set of ''n'' signers can sign but no subset of size less than ''k'' can produce a valid Schnorr signature. However, the practicality of the existing schemes is limited: most schemes in the literature have been proven secure only for the case ''k-1 < n/2'', are not secure when used concurrently in multiple sessions, or require a reliable broadcast mechanism to be secure. Further research is necessary to improve this situation.
+Moreover, Schnorr signatures are compatible with [https://en.wikipedia.org/wiki/Distributed_key_generation distributed key generation], which enables interactive threshold signatures schemes, e.g., the schemes described by [http://cacr.uwaterloo.ca/techreports/2001/corr2001-13.ps Stinson and Strobl (2001)], [https://link.springer.com/content/pdf/10.1007/s00145-006-0347-3.pdf Gennaro, Jarecki, Krawczyk, and Rabin (2007)], [https://eprint.iacr.org/2020/852.pdf Komlo and Goldberg (2020)], or [https://eprint.iacr.org/2023/899.pdf Chu, Gerhart, Ruffing, and Schröder (2023)]. These protocols make it possible to realize ''k''-of-''n'' threshold signatures, which ensure that any subset of size ''k'' of the set of ''n'' signers can sign but no subset of size less than ''k'' can produce a valid Schnorr signature.
 
 === Adaptor Signatures ===
 
@@ -278,7 +278,7 @@ Adaptor signatures, beyond the efficiency and privacy benefits of encoding scrip
 
 === Blind Signatures ===
 
-A blind signature protocol is an interactive protocol that enables a signer to sign a message at the behest of another party without learning any information about the signed message or the signature. Schnorr signatures admit a very [http://publikationen.ub.uni-frankfurt.de/files/4292/schnorr.blind_sigs_attack.2001.pdf simple blind signature scheme] which is however insecure because it's vulnerable to [https://www.iacr.org/archive/crypto2002/24420288/24420288.pdf Wagner's attack]. A known mitigation is to let the signer abort a signing session with a certain probability, and the resulting scheme can be [https://eprint.iacr.org/2019/877 proven secure under non-standard cryptographic assumptions].
+A blind signature protocol is an interactive protocol that enables a signer to sign a message at the behest of another party without learning any information about the signed message or the signature. Schnorr signatures admit a very [http://publikationen.ub.uni-frankfurt.de/files/4292/schnorr.blind_sigs_attack.2001.pdf simple blind signature scheme] which is however insecure because it's vulnerable to [https://www.iacr.org/archive/crypto2002/24420288/24420288.pdf Wagner's attack]. Known mitigations are to let the signer abort a signing session with a certain probability, which can be [https://eprint.iacr.org/2019/877 proven secure under non-standard cryptographic assumptions], or [https://eprint.iacr.org/2022/1676.pdf to use zero-knowledge proofs].
 
 Blind Schnorr signatures could for example be used in [https://github.com/ElementsProject/scriptless-scripts/blob/master/md/partially-blind-swap.md Partially Blind Atomic Swaps], a construction to enable transferring of coins, mediated by an untrusted escrow agent, without connecting the transactors in the public blockchain transaction graph.
 

From 2c017b0c0b1259a6a7f5716439b9a58dbe26f0ee Mon Sep 17 00:00:00 2001
From: Yannick Seurin 
Date: Tue, 30 Apr 2024 11:42:38 +0200
Subject: [PATCH 209/454] link to BIP327

---
 bip-0340.mediawiki | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/bip-0340.mediawiki b/bip-0340.mediawiki
index 7746018bb7..1aeb1c2978 100644
--- a/bip-0340.mediawiki
+++ b/bip-0340.mediawiki
@@ -264,7 +264,7 @@ While recent academic papers claim that they are also possible with ECDSA, conse
 
 === Multisignatures and Threshold Signatures ===
 
-By means of an interactive scheme such as [https://eprint.iacr.org/2020/1261.pdf MuSig2], participants can aggregate their public keys into a single public key which they can jointly sign for. This allows ''n''-of-''n'' multisignatures which, from a verifier's perspective, are no different from ordinary signatures, giving improved privacy and efficiency versus ''CHECKMULTISIG'' or other means.
+By means of an interactive scheme such as [https://eprint.iacr.org/2020/1261.pdf MuSig2] ([[bip-0327.mediawiki|BIP327]]), participants can aggregate their public keys into a single public key which they can jointly sign for. This allows ''n''-of-''n'' multisignatures which, from a verifier's perspective, are no different from ordinary signatures, giving improved privacy and efficiency versus ''CHECKMULTISIG'' or other means.
 
 Moreover, Schnorr signatures are compatible with [https://en.wikipedia.org/wiki/Distributed_key_generation distributed key generation], which enables interactive threshold signatures schemes, e.g., the schemes described by [http://cacr.uwaterloo.ca/techreports/2001/corr2001-13.ps Stinson and Strobl (2001)], [https://link.springer.com/content/pdf/10.1007/s00145-006-0347-3.pdf Gennaro, Jarecki, Krawczyk, and Rabin (2007)], [https://eprint.iacr.org/2020/852.pdf Komlo and Goldberg (2020)], or [https://eprint.iacr.org/2023/899.pdf Chu, Gerhart, Ruffing, and Schröder (2023)]. These protocols make it possible to realize ''k''-of-''n'' threshold signatures, which ensure that any subset of size ''k'' of the set of ''n'' signers can sign but no subset of size less than ''k'' can produce a valid Schnorr signature.
 

From 2d9e431fbe654640b55bca3bf8c4b17462890109 Mon Sep 17 00:00:00 2001
From: Varunram Ganesh 
Date: Tue, 30 Apr 2024 14:51:39 -0400
Subject: [PATCH 210/454] [trivial]: Correct spellings across bips (#675)

Co-authored-by: Mark "Murch" Erhardt 
---
 bip-0035.mediawiki | 2 +-
 bip-0080.mediawiki | 2 +-
 bip-0081.mediawiki | 2 +-
 bip-0174.mediawiki | 2 +-
 4 files changed, 4 insertions(+), 4 deletions(-)

diff --git a/bip-0035.mediawiki b/bip-0035.mediawiki
index 64edaf5d7a..eccd381559 100644
--- a/bip-0035.mediawiki
+++ b/bip-0035.mediawiki
@@ -16,7 +16,7 @@ Make a network node's transaction memory pool accessible via a new "mempool" mes
 
 ==Motivation==
 
-Several use cases make it desireable to expose a network node's transaction memory pool:
+Several use cases make it desirable to expose a network node's transaction memory pool:
 # SPV clients, wishing to obtain zero-confirmation transactions sent or received.
 # Miners, to avoid missing lucrative fees, downloading existing network transactions after a restart.
 # Remote network diagnostics.
diff --git a/bip-0080.mediawiki b/bip-0080.mediawiki
index 0cade1994b..f367c71a70 100644
--- a/bip-0080.mediawiki
+++ b/bip-0080.mediawiki
@@ -35,7 +35,7 @@ Each level has a special meaning, described in the chapters below.
 
 ===Purpose===
 
-Purpose is a constant set following the BIP43 recommendation to: the ASCII value of "80" with the most signifigant bit set to indicate hardened derivation (0x80000050). It indicates that the subtree of this node is used according to this specification.
+Purpose is a constant set following the BIP43 recommendation to: the ASCII value of "80" with the most significant bit set to indicate hardened derivation (0x80000050). It indicates that the subtree of this node is used according to this specification.
 
 Hardened derivation is used at this level.
 
diff --git a/bip-0081.mediawiki b/bip-0081.mediawiki
index 96ac8d1bb0..923917c550 100644
--- a/bip-0081.mediawiki
+++ b/bip-0081.mediawiki
@@ -35,7 +35,7 @@ Each level has a special meaning, described in the chapters below.
 
 ===Purpose===
 
-Purpose is a constant set following the BIP43 recommendation to: the ASCII value of "81" with the most signifigant bit set to indicate hardened derivation (0x80000051). It indicates that the subtree of this node is used according to this specification.
+Purpose is a constant set following the BIP43 recommendation to: the ASCII value of "81" with the most significant bit set to indicate hardened derivation (0x80000051). It indicates that the subtree of this node is used according to this specification.
 
 Hardened derivation is used at this level.
 
diff --git a/bip-0174.mediawiki b/bip-0174.mediawiki
index 5e70a110f7..c192f19e48 100644
--- a/bip-0174.mediawiki
+++ b/bip-0174.mediawiki
@@ -800,7 +800,7 @@ A MIME type name will be added to this document once one has been registered.
 ==Extensibility==
 
 The Partially Signed Transaction format can be extended in the future by adding
-new types for key-value pairs. Backwards compatibilty will still be maintained as those new
+new types for key-value pairs. Backwards compatibility will still be maintained as those new
 types will be ignored and passed-through by signers which do not know about them.
 
 ===Version Numbers===

From f61885edcf5e63ac205b1ca5f08173f1336bff74 Mon Sep 17 00:00:00 2001
From: John Bampton 
Date: Wed, 1 May 2024 06:54:05 +1000
Subject: [PATCH 211/454] docs: fix spelling (#1117)

Co-authored-by: Mark "Murch" Erhardt 
---
 bip-0014.mediawiki         |  2 +-
 bip-0015.mediawiki         |  4 ++--
 bip-0061.mediawiki         |  2 +-
 bip-0067.mediawiki         |  6 +++---
 bip-0078.mediawiki         | 14 +++++++-------
 bip-0083.mediawiki         |  2 +-
 bip-0099.mediawiki         |  2 +-
 bip-0109.mediawiki         |  2 +-
 bip-0126.mediawiki         | 16 ++++++++--------
 bip-0127.mediawiki         |  2 +-
 bip-0132.mediawiki         |  2 +-
 bip-0137.mediawiki         |  2 +-
 bip-0143.mediawiki         |  4 ++--
 bip-0151.mediawiki         |  2 +-
 bip-0158/gentestvectors.go |  2 +-
 bip-0174.mediawiki         |  2 +-
 bip-0310.mediawiki         |  2 +-
 bip-0330/minisketch.py     |  2 +-
 bip-0370.mediawiki         |  2 +-
 19 files changed, 36 insertions(+), 36 deletions(-)

diff --git a/bip-0014.mediawiki b/bip-0014.mediawiki
index abd575ce9b..fded42036a 100644
--- a/bip-0014.mediawiki
+++ b/bip-0014.mediawiki
@@ -28,7 +28,7 @@ Version bumping can also introduce incompatibilities and fracture the network. I
 
 By using a protocol version, we set all implementations on the network to a common standard. Everybody is able to agree within their confines what is protocol and what is implementation-dependent. A user agent string is offered as a 'vanity-plate' for clients to distinguish themselves in the network.
 
-Separation of the network protocol from the implemention, and forming development of said protocol by means of a mutual consensus among participants, has the democratic disadvantage when agreement is hard to reach on contentious issues. To mitigate this issue, strong communication channels and fast release schedules are needed, and are outside the scope of this document (concerning a process-BIP type).
+Separation of the network protocol from the implementation, and forming development of said protocol by means of a mutual consensus among participants, has the democratic disadvantage when agreement is hard to reach on contentious issues. To mitigate this issue, strong communication channels and fast release schedules are needed, and are outside the scope of this document (concerning a process-BIP type).
 
 User agents provide extra tracking information that is useful for keeping tabs on network data such as client implementations used or common architectures/operating-systems. In the rare case they may even provide an emergency method of shunning faulty clients that threaten network health- although this is strongly unrecommended and extremely bad form. The user agent does not provide a method for clients to work around and behave differently to different implementations, as this will lead to protocol fracturing.
 
diff --git a/bip-0015.mediawiki b/bip-0015.mediawiki
index a6e4426a81..52a698f235 100644
--- a/bip-0015.mediawiki
+++ b/bip-0015.mediawiki
@@ -348,7 +348,7 @@ By using DNS lookups, the MITM problem with IP transactions could be mitigated b
 
 === Namecoin ID ===
 
-This proposal uses the Namecoin blockchain to associate an alias with a bitcoin address. Bitcoin queries a namecoin node. This retreives the structured data containing the bitcoin address(es) associated with this alias.
+This proposal uses the Namecoin blockchain to associate an alias with a bitcoin address. Bitcoin queries a namecoin node. This retrieves the structured data containing the bitcoin address(es) associated with this alias.
 
 Using a decentralised domain name system like Namecoin, means no external server or entity needs to be trusted unlike the other proposals listed here. This indicates a system with the advantage of having a high availability and ease of entry (no restrictions for users to create aliases).
 
@@ -401,4 +401,4 @@ Any text can be put into the brackets, allowing merchants to adapt it to all the
 New features can be added later to support uncovered cases.
 
 
-See the specification of [http://dot-bit.org/Namespace:Identity Namecoin ID] for more informations.
+See the specification of [http://dot-bit.org/Namespace:Identity Namecoin ID] for more information.
diff --git a/bip-0061.mediawiki b/bip-0061.mediawiki
index b08739ddc1..384c0ff7ae 100644
--- a/bip-0061.mediawiki
+++ b/bip-0061.mediawiki
@@ -57,7 +57,7 @@ Every reject message begins with the following fields. Some messages append extr
 |}
 
 The human-readable string is intended only for debugging purposes; in particular, different implementations may
-use different strings. The string should not be shown to users or used for anthing besides diagnosing
+use different strings. The string should not be shown to users or used for anything besides diagnosing
 interoperability problems.
 
 The following reject code categories are used; in the descriptions below, "server" is the peer generating
diff --git a/bip-0067.mediawiki b/bip-0067.mediawiki
index 793039d248..a31cc3d0ca 100644
--- a/bip-0067.mediawiki
+++ b/bip-0067.mediawiki
@@ -53,10 +53,10 @@ Hash the redeem script according to BIP-0016 to get the P2SH address.
     3Q4sF6tv9wsdqu2NtARzNCpQgwifm2rAba
     
 ==Compatibility==
-* Uncompressed keys are incompatible with this specificiation. A compatible implementation should not automatically compress keys.  Receiving an uncompressed key from a multisig participant should be interpreted as a sign that the user has an incompatible implementation.
-* P2SH addressses do not reveal information about the script that is receiving the funds. For this reason it is not technically possible to enforce this BIP as a rule on the network.  Also, it would cause a hard fork.
+* Uncompressed keys are incompatible with this specification. A compatible implementation should not automatically compress keys.  Receiving an uncompressed key from a multisig participant should be interpreted as a sign that the user has an incompatible implementation.
+* P2SH addresses do not reveal information about the script that is receiving the funds. For this reason it is not technically possible to enforce this BIP as a rule on the network.  Also, it would cause a hard fork.
 * Implementations that do not conform with this BIP will have compatibility issues with strictly-compliant wallets.
-* Implementations which do adopt this standard will be cross-compatible when choosing multisig addressses. 
+* Implementations which do adopt this standard will be cross-compatible when choosing multisig addresses.
 * If a group of users were not entirely compliant, there is the possibility that a participant will derive an address that the others will not recognize as part of the common multisig account.
 
 ==Test vectors==
diff --git a/bip-0078.mediawiki b/bip-0078.mediawiki
index 1893f0e7a2..352872562c 100644
--- a/bip-0078.mediawiki
+++ b/bip-0078.mediawiki
@@ -143,7 +143,7 @@ If the receiver does not support the version of the sender, they should send an
 }
 
-* additionalfeeoutputindex=, if the sender is willing to pay for increased fee, this indicate output can have its value substracted to pay for it. +* additionalfeeoutputindex=, if the sender is willing to pay for increased fee, this indicate output can have its value subtracted to pay for it. If the additionalfeeoutputindex is out of bounds or pointing to the payment output meant for the receiver, the receiver should ignore the parameter. See [[#fee-output|fee output]] for more information. @@ -198,7 +198,7 @@ It is advised to hard code the description of the well known error codes into th ===Fee output=== In some situation, the sender might want to pay some additional fee in the payjoin proposal. -If such is the case, the sender must use both [[#optional-params|optional parameters]] additionalfeeoutputindex= and maxadditionalfeecontribution= to indicate which output and how much the receiver can substract fee. +If such is the case, the sender must use both [[#optional-params|optional parameters]] additionalfeeoutputindex= and maxadditionalfeecontribution= to indicate which output and how much the receiver can subtract fee. There is several cases where a fee output is useful: @@ -273,7 +273,7 @@ The sender should check the payjoin proposal before signing it to prevent a mali * For each outputs in the proposal: ** Verify that no keypaths is in the PSBT output ** If the output is the [[#fee-output|fee output]]: -*** The amount that was substracted from the output's value is less than or equal to maxadditionalfeecontribution. Let's call this amount actual contribution. +*** The amount that was subtracted from the output's value is less than or equal to maxadditionalfeecontribution. Let's call this amount actual contribution. *** Make sure the actual contribution is only paying fee: The actual contribution is less than or equals to the difference of absolute fee between the payjoin proposal and the original PSBT. *** Make sure the actual contribution is only paying for fee incurred by additional inputs: actual contribution is less than or equals to originalPSBTFeeRate * vsize(sender_input_type) * (count(payjoin_proposal_inputs) - count(original_psbt_inputs)). (see [[#fee-output|Fee output]] section) ** If the output is the payment output and payment output substitution is allowed. @@ -344,7 +344,7 @@ On top of this the receiver can poison analysis by randomly faking a round amoun ===Payment output substitution=== -Unless disallowed by sender explicitely via `disableoutputsubstitution=true` or by the BIP21 url via query parameter the `pjos=0`, the receiver is free to decrease the amount, remove, or change the scriptPubKey output paying to himself. +Unless disallowed by sender explicitly via `disableoutputsubstitution=true` or by the BIP21 url via query parameter the `pjos=0`, the receiver is free to decrease the amount, remove, or change the scriptPubKey output paying to himself. Note that if payment output substitution is disallowed, the reveiver can still increase the amount of the output. (See [[#reference-impl|the reference implementation]]) For example, if the sender's scriptPubKey type is P2WPKH while the receiver's payment output in the original PSBT is P2SH, then the receiver can substitute the payment output to be P2WPKH to match the sender's scriptPubKey type. @@ -413,7 +413,7 @@ Here is pseudo code of a sender implementation. The signedPSBT represents a PSBT which has been fully signed, but not yet finalized. We then prepare originalPSBT from the signedPSBT via the CreateOriginalPSBT function and get back the proposal. -While we verify the proposal, we also import into it informations about our own inputs and outputs from the signedPSBT. +While we verify the proposal, we also import into it information about our own inputs and outputs from the signedPSBT. At the end of this RequestPayjoin, the proposal is verified and ready to be signed. We logged the different PSBT involved, and show the result in our [[#test-vectors|test vectors]]. @@ -557,7 +557,7 @@ public async Task RequestPayjoin( if (output.OriginalTxOut == feeOutput) { var actualContribution = feeOutput.Value - proposedPSBTOutput.Value; - // The amount that was substracted from the output's value is less than or equal to maxadditionalfeecontribution + // The amount that was subtracted from the output's value is less than or equal to maxadditionalfeecontribution if (actualContribution > optionalParameters.MaxAdditionalFeeContribution) throw new PayjoinSenderException("The actual contribution is more than maxadditionalfeecontribution"); // Make sure the actual contribution is only paying fee @@ -642,7 +642,7 @@ A successful exchange with: {| class="wikitable" !InputScriptType -!Orginal PSBT Fee rate +!Original PSBT Fee rate !maxadditionalfeecontribution !additionalfeeoutputindex |- diff --git a/bip-0083.mediawiki b/bip-0083.mediawiki index d7bbe8ea82..c6690015be 100644 --- a/bip-0083.mediawiki +++ b/bip-0083.mediawiki @@ -53,7 +53,7 @@ p //' n instead of p / 0' / n Rather than specifying upfront which path is to be used for a specific purpose (i.e. external invoicing vs. internal change), different applications can specify arbitrary parent nodes and derivation paths. This allows for nesting of sublevels to arbitrary depth with application-specified semantics. Rather than trying to specify use cases upfront, we leave the design completely open-ended. Different applications can exchange these mappings for interoperability. Eventually, if certain mappings become popular, application user interfaces can provide convenient shortcuts or use them as defaults. -Note that BIP32 suggests reserving child 0 for the derivation of signing keys rather than sublevels. It is not really necessary to reserve signing key parents, however, as each key's parent's path can be explicitly stated. But unless we reserve a child for sublevel derivation, we lose the ability to nest deeper levels into the hierarchy. While we could reserve any arbitrary index for nesting sublevels, reserving child 0 seems simplest to implement, leaving all indices > 0 for contiguously indexed signing keys. We could also use MAX_INDEX (231 - 1) for this purpose. However, we believe doing so introduces more ideosyncracies into the semantics and will present a problem if we ever decide to extend the scheme to use indices larger than 31 bits. +Note that BIP32 suggests reserving child 0 for the derivation of signing keys rather than sublevels. It is not really necessary to reserve signing key parents, however, as each key's parent's path can be explicitly stated. But unless we reserve a child for sublevel derivation, we lose the ability to nest deeper levels into the hierarchy. While we could reserve any arbitrary index for nesting sublevels, reserving child 0 seems simplest to implement, leaving all indices > 0 for contiguously indexed signing keys. We could also use MAX_INDEX (231 - 1) for this purpose. However, we believe doing so introduces more idiosyncrasies into the semantics and will present a problem if we ever decide to extend the scheme to use indices larger than 31 bits. ==Use Cases== diff --git a/bip-0099.mediawiki b/bip-0099.mediawiki index 8882e0036b..156eec02c5 100644 --- a/bip-0099.mediawiki +++ b/bip-0099.mediawiki @@ -56,7 +56,7 @@ development, diversity, etc) to fork the Bitcoin Core software and it's good that there's many alternative implementations of the protocol (forks of Bitcoin Core or written from scratch). -But sometimes a bug in the reimplementaion of the consensus +But sometimes a bug in the reimplementation of the consensus validation rules can prevent users of alternative implementation from following the longest (most work) valid chain. This can result in those users losing coins or being defrauded, making reimplementations diff --git a/bip-0109.mediawiki b/bip-0109.mediawiki index 69b265b1c9..4822d4a25d 100644 --- a/bip-0109.mediawiki +++ b/bip-0109.mediawiki @@ -37,7 +37,7 @@ In particular: * The coinbase scriptSig is not counted * Signature operations in un-executed branches of a Script are not counted -* OP_CHECKMULTISIG evaluations are counted accurately; if the signature for a 1-of-20 OP_CHECKMULTISIG is satisified by the public key nearest the top of the execution stack, it is counted as one signature operation. If it is satisfied by the public key nearest the bottom of the execution stack, it is counted as twenty signature operations. +* OP_CHECKMULTISIG evaluations are counted accurately; if the signature for a 1-of-20 OP_CHECKMULTISIG is satisfied by the public key nearest the top of the execution stack, it is counted as one signature operation. If it is satisfied by the public key nearest the bottom of the execution stack, it is counted as twenty signature operations. * Signature operations involving invalidly encoded signatures or public keys are not counted towards the limit === Add a new limit of 1,300,000,000 bytes hashed to compute transaction signatures per block === diff --git a/bip-0126.mediawiki b/bip-0126.mediawiki index 4cfa2929a7..2c04eb4551 100644 --- a/bip-0126.mediawiki +++ b/bip-0126.mediawiki @@ -14,7 +14,7 @@ When a Bitcoin transaction contains inputs that reference previous transaction outputs sent to different Bitcoin addresses, personally identifiable information of the user will leak into the blockchain in an uncontrolled manner. While undesirable, these transactions are frequently unavoidable due to the natural fragmentation of wallet balances over time. -This document proposes a set of best practice guidelines which minimize the uncontrolled disclosure of personally identifiable information by defining standard forms for transactions containing heterogenous input scripts. +This document proposes a set of best practice guidelines which minimize the uncontrolled disclosure of personally identifiable information by defining standard forms for transactions containing heterogeneous input scripts. ==Copyright== @@ -23,8 +23,8 @@ This BIP is in the public domain. ==Definitions== * '''Heterogenous input script transaction (HIT)''': A transaction containing multiple inputs where the scripts of the previous transaction outputs being consumed are not identical (e.g. a transaction spending outputs which were sent to more than one Bitcoin address) -* '''Unavoidable heterogenous input script transaction''': A HIT created as a result of a user’s desire to create a new output with a value larger than the value of his wallet's largest existing unspent output -* '''Intentional heterogenous input script transaction''': A HIT created as part of a user protection protocol for reducing uncontrolled disclosure of personally-identifying information (PII) +* '''Unavoidable heterogeneous input script transaction''': A HIT created as a result of a user’s desire to create a new output with a value larger than the value of his wallet's largest existing unspent output +* '''Intentional heterogeneous input script transaction''': A HIT created as part of a user protection protocol for reducing uncontrolled disclosure of personally-identifying information (PII) Throughout this procedure, when input scripts are evaluated for uniqueness, "input script" should be interpreted to mean, "the script of the previous output referenced by an input to a transaction". @@ -33,10 +33,10 @@ Throughout this procedure, when input scripts are evaluated for uniqueness, "inp The recommendations in this document are designed to accomplish three goals: # Maximise the effectiveness of user-protecting protocols: Users may find that protection protocols are counterproductive if such transactions have a distinctive fingerprint which renders them ineffective. -# Minimise the adverse consequences of unavoidable heterogenous input transactions: If unavoidable HITs are indistinguishable from intentional HITs, a user creating an unavoidable HIT benefits from ambiguity with respect to graph analysis. +# Minimise the adverse consequences of unavoidable heterogeneous input transactions: If unavoidable HITs are indistinguishable from intentional HITs, a user creating an unavoidable HIT benefits from ambiguity with respect to graph analysis. # Limiting the effect on UTXO set growth: To date, non-standardized intentional HITs tend to increase the network's UTXO set with each transaction; this standard attempts to minimize this effect by standardizing unavoidable and intentional HITs to limit UTXO set growth. -In order to achieve these goals, this specification proposes a set of best practices for heterogenous input script transaction creation. These practices accommodate all applicable requirements of both intentional and unavoidable HITs while maximising the effectiveness of both in terms of preventing uncontrolled disclosure of PII. +In order to achieve these goals, this specification proposes a set of best practices for heterogeneous input script transaction creation. These practices accommodate all applicable requirements of both intentional and unavoidable HITs while maximising the effectiveness of both in terms of preventing uncontrolled disclosure of PII. In order to achieve this, two forms of HIT are proposed: Standard form and alternate form. @@ -44,7 +44,7 @@ In order to achieve this, two forms of HIT are proposed: Standard form and alter Applications which wish to comply both with this procedure and BIP69 should apply this procedure prior to applying BIP69. -==Standard form heterogenous input script transaction== +==Standard form heterogeneous input script transaction== ===Rules=== @@ -63,7 +63,7 @@ The requirement that all output scripts are unique prevents address reuse. Restr The requirement for at least one pair of outputs in an intentional HIT to be of equal value results in optimal behavior, and causes intentional HITs to resemble unavoidable HITs. -==Alternate form heterogenous input script transactions== +==Alternate form heterogeneous input script transactions== The formation of a standard form HIT is not possible in the following cases: @@ -100,7 +100,7 @@ An HIT formed via the preceding procedure will adhere to the following condition ## The sum of the inputs in the set minus the value of the change output is equal to the standard value with a tolerance equal to the transaction fee. ## Change outputs with a value of zero (virtual change outputs) are permitted. The are defined for the purpose of testing whether or not a HIT adheres to this specification but are not present in the version of the transaction which is broadcast to the network. -==Non-compliant heterogenous input script transactions== +==Non-compliant heterogeneous input script transactions== If a user wishes to create an output that is larger than half the total size of their spendable outputs, or if their inputs are not distributed in a manner in which the alternate form procedure can be completed, then the user can not create a transaction which is compliant with this procedure. diff --git a/bip-0127.mediawiki b/bip-0127.mediawiki index 44a90d7991..87071d8eaf 100644 --- a/bip-0127.mediawiki +++ b/bip-0127.mediawiki @@ -124,7 +124,7 @@ message FinalProof { // Bitcoin transaction. bytes proof_tx = 1; - // The metadata of the ouputs used in the proof transaction. + // The metadata of the outputs used in the proof transaction. repeated OutputMeta output_metadata = 2; } diff --git a/bip-0132.mediawiki b/bip-0132.mediawiki index e7aed29248..173c919818 100644 --- a/bip-0132.mediawiki +++ b/bip-0132.mediawiki @@ -48,7 +48,7 @@ The author doesn't believe this is a problem because a BIP cannot be forced on c == Process == -* '''Submit for Comments.''' The first BIP champion named in the proposal can call a "submit for comments" at any time by posting to the [https://lists.linuxfoundation.org/mailman/listinfo/bitcoin-dev Dev Mailing List] mailling with the BIP number and a statement that the champion intends to immediately submit the BIP for comments. +* '''Submit for Comments.''' The first BIP champion named in the proposal can call a "submit for comments" at any time by posting to the [https://lists.linuxfoundation.org/mailman/listinfo/bitcoin-dev Dev Mailing List] mailing with the BIP number and a statement that the champion intends to immediately submit the BIP for comments. ** The BIP must have been assigned BIP-number (i.e. been approved by the BIP editor) to be submitted for comments. * '''Comments.''' ** After a BIP has been submitted for comments, a two-week waiting period begins in which the community should transition from making suggestions about a proposal to publishing their opinions or concerns on the proposal. diff --git a/bip-0137.mediawiki b/bip-0137.mediawiki index 43addbab4c..575440b181 100644 --- a/bip-0137.mediawiki +++ b/bip-0137.mediawiki @@ -116,7 +116,7 @@ Since this format includes P2PKH keys, it is backwards compatible, but keep in m ==Implications== -Message signing is an important use case and potentially underused due to the fact that, up until now, there has not been a formal specification for how wallets can sign messages using Bitcoin private keys. Bitcoin wallets should be interoperable and use the same conventions for determing a signature's validity. This BIP can also be updated as new signature formats emerge. +Message signing is an important use case and potentially underused due to the fact that, up until now, there has not been a formal specification for how wallets can sign messages using Bitcoin private keys. Bitcoin wallets should be interoperable and use the same conventions for determining a signature's validity. This BIP can also be updated as new signature formats emerge. ==Acknowledgements== diff --git a/bip-0143.mediawiki b/bip-0143.mediawiki index ebf0d7c612..9935eaa2b7 100644 --- a/bip-0143.mediawiki +++ b/bip-0143.mediawiki @@ -39,12 +39,12 @@ A new transaction digest algorithm is defined, but only applicable to sigops in 9. nLocktime of the transaction (4-byte little endian) 10. sighash type of the signature (4-byte little endian) -Semantics of the original sighash types remain unchanged, except the followings: +Semantics of the original sighash types remain unchanged, except the following: # The way of serialization is changed; # All sighash types commit to the amount being spent by the signed input; # FindAndDelete of the signature is not applied to the scriptCode; # OP_CODESEPARATOR(s) after the last executed OP_CODESEPARATOR are not removed from the scriptCode (the last executed OP_CODESEPARATOR and any script before it are always removed); -# SINGLE does not commit to the input index. When ANYONECANPAY is not set, the semantics are unchanged since hashPrevouts and outpoint together implictly commit to the input index. When SINGLE is used with ANYONECANPAY, omission of the index commitment allows permutation of the input-output pairs, as long as each pair is located at an equivalent index. +# SINGLE does not commit to the input index. When ANYONECANPAY is not set, the semantics are unchanged since hashPrevouts and outpoint together implicitly commit to the input index. When SINGLE is used with ANYONECANPAY, omission of the index commitment allows permutation of the input-output pairs, as long as each pair is located at an equivalent index. The items 1, 4, 7, 9, 10 have the same meaning as the original algorithm. diff --git a/bip-0151.mediawiki b/bip-0151.mediawiki index 793c24411c..8bc119785b 100644 --- a/bip-0151.mediawiki +++ b/bip-0151.mediawiki @@ -85,7 +85,7 @@ a 64 bit nonce and a 64 bit counter into 64 bytes of output. This output is used Poly1305, also by Daniel Bernstein [4], is a one-time Carter-Wegman MAC that computes a 128 bit integrity tag given a message and a single-use 256 bit secret key. -The chacha20-poly1305@openssh.com specified and defined by openssh [5] combines these two primitives into an authenticated encryption mode. The construction used is based on that proposed for TLS by Adam Langley [6], but differs in the layout of data passed to the MAC and in the addition of encyption of the packet lengths. +The chacha20-poly1305@openssh.com specified and defined by openssh [5] combines these two primitives into an authenticated encryption mode. The construction used is based on that proposed for TLS by Adam Langley [6], but differs in the layout of data passed to the MAC and in the addition of encryption of the packet lengths. K_1 must be used to only encrypt the payload size of the encrypted message to avoid leaking information by revealing the message size. diff --git a/bip-0158/gentestvectors.go b/bip-0158/gentestvectors.go index 3435eb3cf7..e51b9842c6 100644 --- a/bip-0158/gentestvectors.go +++ b/bip-0158/gentestvectors.go @@ -207,7 +207,7 @@ func main() { prevOutputScripts, err := fetchPrevOutputScripts(client, block) if err != nil { - fmt.Println("Couldn't fetch prev output scipts: ", err) + fmt.Println("Couldn't fetch prev output scripts: ", err) return } diff --git a/bip-0174.mediawiki b/bip-0174.mediawiki index c192f19e48..95a5573b45 100644 --- a/bip-0174.mediawiki +++ b/bip-0174.mediawiki @@ -633,7 +633,7 @@ values are valid, then it does not matter which is chosen as either way the tran ===Proprietary Use Type=== For all global, per-input, and per-output maps, the type 0xFC is reserved for proprietary use. -The proprietary use type requires keys that follow the type with a compact size unsigned integer representing the length of the string identifer, followed by the string identifier, then a subtype, and finally any key data. +The proprietary use type requires keys that follow the type with a compact size unsigned integer representing the length of the string identifier, followed by the string identifier, then a subtype, and finally any key data. The identifier can be any variable length string that software can use to identify whether the particular data in the proprietary type can be used by it. It can also be the empty string although this is not recommended. diff --git a/bip-0310.mediawiki b/bip-0310.mediawiki index 257e92ad1c..6104015f1c 100644 --- a/bip-0310.mediawiki +++ b/bip-0310.mediawiki @@ -276,7 +276,7 @@ Miner provides additional text-based information. Currently, there is a similar protocol feature '''mining.capabilities''' that was intended for various protocol extensions. However, '''mining.configure''' is incompatible with this feature as it requires a server response confirming -all accepted/negotatied extensions. The reason why we made it incompatible is +all accepted/negotiated extensions. The reason why we made it incompatible is that '''mining.capabilities''' request has no associated response. diff --git a/bip-0330/minisketch.py b/bip-0330/minisketch.py index f64286fd8b..5e3977935d 100755 --- a/bip-0330/minisketch.py +++ b/bip-0330/minisketch.py @@ -120,7 +120,7 @@ def find_roots_inner(p, a): return [] elif len(p) == 2: return [p[0]] - # Otherwise, split p in left*right using paramater a_vals[0]. + # Otherwise, split p in left*right using parameter a_vals[0]. t = poly_monic(poly_trace(p, a)) left = poly_gcd(list(p), t) right = poly_divmod(list(left), p) diff --git a/bip-0370.mediawiki b/bip-0370.mediawiki index cd448cc0b0..98f1800256 100644 --- a/bip-0370.mediawiki +++ b/bip-0370.mediawiki @@ -248,7 +248,7 @@ Before any input or output may be added, the constructor must check the PSBT_GLO Inputs may only be added if the Inputs Modifiable flag is True. Outputs may only be added if the Outputs Modifiable flag is True. -When an input or output is added, the corresponding PSBT_GLOBAL_INPUT_COUNT or PSBT_GLOBAL_OUTPUT_COUNT must be incremeted to reflect the number of inputs and outputs in the PSBT. +When an input or output is added, the corresponding PSBT_GLOBAL_INPUT_COUNT or PSBT_GLOBAL_OUTPUT_COUNT must be incremented to reflect the number of inputs and outputs in the PSBT. When an input is added, it must have PSBT_IN_PREVIOUS_TXID and PSBT_IN_OUTPUT_INDEX set. When an output is added, it must have PSBT_OUT_VALUE and PSBT_OUT_OUTPUT_SCRIPT set. If the input has a required timelock, Constructors must set the requisite timelock field. From 696cc1713b931589d01c544d3016f3cf57be0058 Mon Sep 17 00:00:00 2001 From: Ethan Heilman Date: Tue, 30 Apr 2024 21:13:43 -0400 Subject: [PATCH 212/454] Adds post history, fixes created date --- bip-0347.mediawiki | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/bip-0347.mediawiki b/bip-0347.mediawiki index 622d7b46ec..88dad57ae9 100644 --- a/bip-0347.mediawiki +++ b/bip-0347.mediawiki @@ -7,8 +7,9 @@ Comments-URI: https://github.com/bitcoin/bips/wiki/Comments:BIP-0347 Status: Draft Type: Standards Track - Created: 2023-10-21 + Created: 2023-12-11 License: BSD-3-Clause + Post-History: 2023-10-21: https://lists.linuxfoundation.org/pipermail/bitcoin-dev/2023-October/022049.html [bitcoin-dev] Proposed BIP for OP_CAT
==Abstract== From 6fc75b1b2153df40f1ff8312d7086b69bfb091de Mon Sep 17 00:00:00 2001 From: Ali Sherief Date: Wed, 1 May 2024 13:44:03 +0000 Subject: [PATCH 213/454] [BIP322] remove empty message requirement for full (proof-of-funds) proofs (#1352) * add bip-notatether-signedmessage * minor heading correction * minor formatting correction * minor formatting correction * minor formatting correction * minor formatting correction * minor formatting correction * minor formatting correction * fix some consistency errors * Remove empty message for UTXO proofs * Delete bip-notatether-signedmessage.mediawiki --- bip-0322.mediawiki | 2 -- 1 file changed, 2 deletions(-) diff --git a/bip-0322.mediawiki b/bip-0322.mediawiki index 55a751f13f..911d3c80f9 100644 --- a/bip-0322.mediawiki +++ b/bip-0322.mediawiki @@ -80,8 +80,6 @@ A full signature consists of the base64-encoding of the to_sign tra 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. -* message_challenge is unused and shall be set to OP_TRUE -* Similarly, message_signature is then empty. * All outputs that the signer wishes to demonstrate control of are included as additional inputs of to_sign, and 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. From d670035b0c0ef60c10e9e818f3fbf6f11779257f Mon Sep 17 00:00:00 2001 From: Ethan Heilman Date: Wed, 1 May 2024 16:30:38 -0400 Subject: [PATCH 214/454] Adds sentence suggested by murchandamus to quantum paragraph Co-authored-by: Mark "Murch" Erhardt --- bip-0347.mediawiki | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/bip-0347.mediawiki b/bip-0347.mediawiki index 88dad57ae9..29d9219e97 100644 --- a/bip-0347.mediawiki +++ b/bip-0347.mediawiki @@ -39,7 +39,7 @@ OP_CAT aims to expand the toolbox of the tapscript developer with a simple, modu * Bitstream, a protocol for the atomic swap (fair exchange) of bitcoins for decryption keys, that enables decentralized file hosting systems paid in Bitcoin. While such swaps are currently possible on Bitcoin without OP_CAT they require the use of complex and computationally expensive Verifiable Computation cryptographic techniques. OP_CAT would remove this requirement on Verifiable Computation, making such protocols far more practical to build in Bitcoin. R. Linus, "BitStream: Decentralized File Hosting Incentivised via Bitcoin Payments", 2023, https://robinlinus.com/bitstream.pdf * Tree signatures provide a multisignature script whose size can be logarithmic in the number of public keys and can encode spend conditions beyond n-of-m. For instance a transaction less than 1KB in size could support tree signatures with up to 4,294,967,296 public keys. This also enables generalized logical spend conditions. P. Wuille, "Multisig on steroids using tree signatures", 2015, https://blog.blockstream.com/en-treesignatures/ -* Post-Quantum Lamport signatures in Bitcoin transactions. Lamport signatures merely require the ability to hash and concatenate values on the stack. J. Rubin, "[bitcoin-dev] OP_CAT Makes Bitcoin Quantum Secure [was CheckSigFromStack for Arithmetic Values]", 2021, https://lists.linuxfoundation.org/pipermail/bitcoin-dev/2021-July/019233.html It is an open question if a tapscript commitment would preserve the quantum resistance of Lamport signatures. Beyond this question, the use of Lamport Signatures in taproot outputs is unlikely to be quantum resistant even if the script spend-path is made quantum resistant. This is because taproot outputs can also be spent with a key. An attacker with a sufficiently powerful quantum computer could bypass the taproot script spend-path by finding the discrete log of the taproot output and thus spending the output using the key spend-path. The use of "Nothing Up My Sleeve" (NUMS) points as described in [[bip-0341.mediawiki|BIP341]] to disable the key spend-path does not disable the key spend-path against a quantum attacker as NUMS relies on the hardness of finding discrete logs. We are not aware of any mechanism which could disable the key spend-path in a taproot output without a softfork change to taproot. +* Post-Quantum Lamport signatures in Bitcoin transactions. Lamport signatures merely require the ability to hash and concatenate values on the stack. J. Rubin, "[bitcoin-dev] OP_CAT Makes Bitcoin Quantum Secure [was CheckSigFromStack for Arithmetic Values]", 2021, https://lists.linuxfoundation.org/pipermail/bitcoin-dev/2021-July/019233.html It has been proposed that if ECDSA is broken or a powerful computer was on the horizon, there might be an effort to protect ownership of bitcoins by allowing people to mark their taproot outputs as "script-path only" and then move their coins into such outputs with a leaf in the script tree requiring a Lamport signature. It is an open question if a tapscript commitment would preserve the quantum resistance of Lamport signatures. Beyond this question, the use of Lamport Signatures in taproot outputs is unlikely to be quantum resistant even if the script spend-path is made quantum resistant. This is because taproot outputs can also be spent with a key. An attacker with a sufficiently powerful quantum computer could bypass the taproot script spend-path by finding the discrete log of the taproot output and thus spending the output using the key spend-path. The use of "Nothing Up My Sleeve" (NUMS) points as described in [[bip-0341.mediawiki|BIP341]] to disable the key spend-path does not disable the key spend-path against a quantum attacker as NUMS relies on the hardness of finding discrete logs. We are not aware of any mechanism which could disable the key spend-path in a taproot output without a softfork change to taproot. * Non-equivocation contracts T. Ruffing, A. Kate, D. Schröder, "Liar, Liar, Coins on Fire: Penalizing Equivocation by Loss of Bitcoins", 2015, https://citeseerx.ist.psu.edu/viewdoc/download?doi=10.1.1.727.6262&rep=rep1&type=pdf in tapscript provide a mechanism to punish equivocation/double spending in Bitcoin payment channels. OP_CAT enables this by enforcing rules on the spending transaction's nonce. The capability is a useful building block for payment channels and other Bitcoin protocols. * Vaults M. Moser, I. Eyal, and E. G. Sirer, Bitcoin Covenants, http://fc16.ifca.ai/bitcoin/papers/MES16.pdf which are a specialized covenant that allows a user to block a malicious party who has compromised the user's secret key from stealing the funds in that output. As shown in A. Poelstra, "CAT and Schnorr Tricks II", 2021, https://www.wpsoftware.net/andrew/blog/cat-and-schnorr-tricks-ii.html OP_CAT is sufficient to build vaults in Bitcoin. * Replicating CheckSigFromStack A. Poelstra, "CAT and Schnorr Tricks I", 2021, https://medium.com/blockstream/cat-and-schnorr-tricks-i-faf1b59bd298 which would allow the creation of simple covenants and other advanced contracts without having to presign spending transactions, possibly reducing complexity and the amount of data that needs to be stored. Originally shown to work with Schnorr signatures, this result has been extended to ECDSA signatures R. Linus, "Covenants with CAT and ECDSA", 2023, https://gist.github.com/RobinLinus/9a69f5552be94d13170ec79bf34d5e85#file-covenants_cat_ecdsa-md. From e9e7636f7e7d5454c2993394518b48f6b4f0833a Mon Sep 17 00:00:00 2001 From: Ethan Heilman Date: Wed, 1 May 2024 16:31:49 -0400 Subject: [PATCH 215/454] Increases commas and capital letters This improves readability, thanks! Co-authored-by: Mark "Murch" Erhardt --- bip-0347.mediawiki | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/bip-0347.mediawiki b/bip-0347.mediawiki index 29d9219e97..2d4ab05ebc 100644 --- a/bip-0347.mediawiki +++ b/bip-0347.mediawiki @@ -33,7 +33,7 @@ This opcode would be activated via a soft fork by redefining the tapscript opcod ==Motivation== -Bitcoin tapscript lacks a general purpose way of combining objects on the stack restricting the expressiveness and power of tapscript. This prevents among many other things the ability to construct and evaluate merkle trees and other hashed data structures in tapscript. OP_CAT by adding a general purpose way to concatenate stack values would overcome this limitation and greatly increase the functionality of tapscript. +Bitcoin Tapscript lacks a general purpose way of combining objects on the stack, restricting the expressiveness and power of Tapscript. This prevents, among many other things, the ability to construct and evaluate merkle trees and other hashed data structures in Tapscript. OP_CAT, by adding a general purpose way to concatenate stack values, would overcome this limitation and greatly increase the functionality of Tapscript. OP_CAT aims to expand the toolbox of the tapscript developer with a simple, modular, and useful opcode in the spirit of Unix R. Pike and B. Kernighan, "Program design in the UNIX environment", 1983, https://harmful.cat-v.org/cat-v/unix_prog_design.pdf. To demonstrate the usefulness of OP_CAT below we provide a non-exhaustive list of some usecases that OP_CAT would enable: From 6815c39f93a7f26f509fb4e3dedf4c0d654ae857 Mon Sep 17 00:00:00 2001 From: Ethan Heilman Date: Wed, 1 May 2024 16:32:28 -0400 Subject: [PATCH 216/454] Adds commas Co-authored-by: Mark "Murch" Erhardt --- bip-0347.mediawiki | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/bip-0347.mediawiki b/bip-0347.mediawiki index 2d4ab05ebc..8d7bf32e2d 100644 --- a/bip-0347.mediawiki +++ b/bip-0347.mediawiki @@ -37,7 +37,7 @@ Bitcoin Tapscript lacks a general purpose way of combining objects on the stack, OP_CAT aims to expand the toolbox of the tapscript developer with a simple, modular, and useful opcode in the spirit of Unix R. Pike and B. Kernighan, "Program design in the UNIX environment", 1983, https://harmful.cat-v.org/cat-v/unix_prog_design.pdf. To demonstrate the usefulness of OP_CAT below we provide a non-exhaustive list of some usecases that OP_CAT would enable: -* Bitstream, a protocol for the atomic swap (fair exchange) of bitcoins for decryption keys, that enables decentralized file hosting systems paid in Bitcoin. While such swaps are currently possible on Bitcoin without OP_CAT they require the use of complex and computationally expensive Verifiable Computation cryptographic techniques. OP_CAT would remove this requirement on Verifiable Computation, making such protocols far more practical to build in Bitcoin. R. Linus, "BitStream: Decentralized File Hosting Incentivised via Bitcoin Payments", 2023, https://robinlinus.com/bitstream.pdf +* Bitstream, a protocol for the atomic swap (fair exchange) of bitcoins for decryption keys, that enables decentralized file hosting systems paid in Bitcoin. While such swaps are currently possible on Bitcoin without OP_CAT, they require the use of complex and computationally expensive Verifiable Computation cryptographic techniques. OP_CAT would remove this requirement on Verifiable Computation, making such protocols far more practical to build in Bitcoin. R. Linus, "BitStream: Decentralized File Hosting Incentivised via Bitcoin Payments", 2023, https://robinlinus.com/bitstream.pdf * Tree signatures provide a multisignature script whose size can be logarithmic in the number of public keys and can encode spend conditions beyond n-of-m. For instance a transaction less than 1KB in size could support tree signatures with up to 4,294,967,296 public keys. This also enables generalized logical spend conditions. P. Wuille, "Multisig on steroids using tree signatures", 2015, https://blog.blockstream.com/en-treesignatures/ * Post-Quantum Lamport signatures in Bitcoin transactions. Lamport signatures merely require the ability to hash and concatenate values on the stack. J. Rubin, "[bitcoin-dev] OP_CAT Makes Bitcoin Quantum Secure [was CheckSigFromStack for Arithmetic Values]", 2021, https://lists.linuxfoundation.org/pipermail/bitcoin-dev/2021-July/019233.html It has been proposed that if ECDSA is broken or a powerful computer was on the horizon, there might be an effort to protect ownership of bitcoins by allowing people to mark their taproot outputs as "script-path only" and then move their coins into such outputs with a leaf in the script tree requiring a Lamport signature. It is an open question if a tapscript commitment would preserve the quantum resistance of Lamport signatures. Beyond this question, the use of Lamport Signatures in taproot outputs is unlikely to be quantum resistant even if the script spend-path is made quantum resistant. This is because taproot outputs can also be spent with a key. An attacker with a sufficiently powerful quantum computer could bypass the taproot script spend-path by finding the discrete log of the taproot output and thus spending the output using the key spend-path. The use of "Nothing Up My Sleeve" (NUMS) points as described in [[bip-0341.mediawiki|BIP341]] to disable the key spend-path does not disable the key spend-path against a quantum attacker as NUMS relies on the hardness of finding discrete logs. We are not aware of any mechanism which could disable the key spend-path in a taproot output without a softfork change to taproot. * Non-equivocation contracts T. Ruffing, A. Kate, D. Schröder, "Liar, Liar, Coins on Fire: Penalizing Equivocation by Loss of Bitcoins", 2015, https://citeseerx.ist.psu.edu/viewdoc/download?doi=10.1.1.727.6262&rep=rep1&type=pdf in tapscript provide a mechanism to punish equivocation/double spending in Bitcoin payment channels. OP_CAT enables this by enforcing rules on the spending transaction's nonce. The capability is a useful building block for payment channels and other Bitcoin protocols. From 98f000a6fb330ec8afa87bcb6ba0cad20c7552f2 Mon Sep 17 00:00:00 2001 From: Ava Chow Date: Wed, 24 Apr 2024 19:11:06 -0400 Subject: [PATCH 217/454] diffchecks.sh: Make success clear and exit with failure on error --- scripts/diffcheck.sh | 2 ++ 1 file changed, 2 insertions(+) diff --git a/scripts/diffcheck.sh b/scripts/diffcheck.sh index 3d8a9e557d..aa9f557cf2 100755 --- a/scripts/diffcheck.sh +++ b/scripts/diffcheck.sh @@ -9,6 +9,8 @@ if git checkout HEAD^ && scripts/buildtable.pl >/tmp/table.mediawiki 2>/dev/null echo "$newdiff" exit 1 fi + echo "README table matches expected table from BIP files" else echo 'Cannot build previous commit table for comparison' + exit 1 fi From 94ca14f34eaa776411365eb87c1f5e32b453b8c2 Mon Sep 17 00:00:00 2001 From: Ava Chow Date: Wed, 24 Apr 2024 19:14:34 -0400 Subject: [PATCH 218/454] ci: Use actions/checkout@v4 v3 is deprecated --- .github/workflows/github-action-checks.yml | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/.github/workflows/github-action-checks.yml b/.github/workflows/github-action-checks.yml index 0b723e1b93..b18267e325 100644 --- a/.github/workflows/github-action-checks.yml +++ b/.github/workflows/github-action-checks.yml @@ -5,17 +5,17 @@ jobs: Link-Format-Checks: runs-on: ubuntu-latest steps: - - uses: actions/checkout@v3 + - uses: actions/checkout@v4 - run: scripts/link-format-chk.sh Build-Table-Checks: runs-on: ubuntu-latest steps: - - uses: actions/checkout@v3 + - uses: actions/checkout@v4 - run: scripts/buildtable.pl >/tmp/table.mediawiki || exit 1 Diff-Checks: runs-on: ubuntu-latest steps: - - uses: actions/checkout@v3 + - uses: actions/checkout@v4 with: fetch-depth: 2 - run: scripts/diffcheck.sh From 09439bb6626305c0bf146069cf8ea467d05b87c5 Mon Sep 17 00:00:00 2001 From: Ava Chow Date: Wed, 24 Apr 2024 19:16:30 -0400 Subject: [PATCH 219/454] ci: Clarify that diffchecks fails until a number is assigned --- .github/workflows/github-action-checks.yml | 1 + 1 file changed, 1 insertion(+) diff --git a/.github/workflows/github-action-checks.yml b/.github/workflows/github-action-checks.yml index b18267e325..8a7d2ac84f 100644 --- a/.github/workflows/github-action-checks.yml +++ b/.github/workflows/github-action-checks.yml @@ -13,6 +13,7 @@ jobs: - uses: actions/checkout@v4 - run: scripts/buildtable.pl >/tmp/table.mediawiki || exit 1 Diff-Checks: + name: "Diff Checks (fails until number assignment)" runs-on: ubuntu-latest steps: - uses: actions/checkout@v4 From 602cd676cd4ec95d1143aa6f2c39d661e95a2897 Mon Sep 17 00:00:00 2001 From: Ava Chow Date: Wed, 1 May 2024 17:02:36 -0400 Subject: [PATCH 220/454] buildtable.pl: Also check .md files (#1577) --- scripts/buildtable.pl | 3 +++ 1 file changed, 3 insertions(+) diff --git a/scripts/buildtable.pl b/scripts/buildtable.pl index 292f1ee5b0..4923a9ed4f 100755 --- a/scripts/buildtable.pl +++ b/scripts/buildtable.pl @@ -96,6 +96,9 @@ my $bipnum = 0; while (++$bipnum <= $topbip) { my $fn = sprintf "bip-%04d.mediawiki", $bipnum; + if (!-e $fn) { + $fn = sprintf "bip-%04d.md", $bipnum; + } -e $fn || next; open my $F, "<$fn"; while (<$F> !~ m[^(?:\xef\xbb\xbf)?
$]) {

From e155b58f1370dd90f0b2020862dff7dd43d891f2 Mon Sep 17 00:00:00 2001
From: Ava Chow 
Date: Wed, 1 May 2024 17:59:53 -0400
Subject: [PATCH 221/454] 197: Fix incorrectly formatted links

---
 bip-0197.mediawiki | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/bip-0197.mediawiki b/bip-0197.mediawiki
index 427ff22000..2cac042c3d 100644
--- a/bip-0197.mediawiki
+++ b/bip-0197.mediawiki
@@ -79,7 +79,7 @@ The Seizable Collateral script takes the following form:
 
 ==Compatibility==
 
-BIP 197 is compatible with [ERC 1850](https://github.com/ethereum/EIPs/pull/1850) for [atomic loans](https://arxiv.org/pdf/1901.05117.pdf) with Ethereum. Can be extended in the future to be compatible with other HTLC and smart contract compatible chains.
+BIP 197 is compatible with [https://github.com/ethereum/EIPs/pull/1850 ERC 1850] for [https://arxiv.org/pdf/1901.05117.pdf atomic loans] with Ethereum. Can be extended in the future to be compatible with other HTLC and smart contract compatible chains.
 
 ==Motivation==
 

From 3bd457c595a9a24ce9fedb38f0df2df659eb9974 Mon Sep 17 00:00:00 2001
From: Ava Chow 
Date: Wed, 1 May 2024 18:00:38 -0400
Subject: [PATCH 222/454] 310: Fix incorrectly formatted link

---
 bip-0310.mediawiki | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/bip-0310.mediawiki b/bip-0310.mediawiki
index 6104015f1c..34522bea3f 100644
--- a/bip-0310.mediawiki
+++ b/bip-0310.mediawiki
@@ -190,7 +190,7 @@ send the mask, in this case a default full mask is used.
 
 * '''"version-rolling.mask"''' (REQUIRED, ''TMask'')
 ::- Bits set to 1 are allowed to be changed by the miner. If a miner changes bits with mask value 0, the server will reject the submit.
-::- The server SHOULD return the largest mask possible (as many bits set to 1 as possible). This can be useful in a mining proxy setup when a proxy needs to negotiate the best mask for its future clients. There is a [Draft BIP](https://github.com/bitcoin/bips/pull/661/files) describing available nVersion bits. The server SHOULD pick a mask that preferably covers all bits specified in the BIP.
+::- The server SHOULD return the largest mask possible (as many bits set to 1 as possible). This can be useful in a mining proxy setup when a proxy needs to negotiate the best mask for its future clients. There is a [https://github.com/bitcoin/bips/pull/661/files Draft BIP] describing available nVersion bits. The server SHOULD pick a mask that preferably covers all bits specified in the BIP.
 
 * '''"version-rolling.min-bit-count"''' (REQUIRED, ''TMask'')
 ::- The miner also provides a minimum number of bits that it needs for efficient version rolling in hardware. Note that this parameter provides important diagnostic information to the pool server. If the requested bit count exceeds the limit of the pool server, the miner always has the chance to operate in a degraded mode without using full hashing power. The pool server SHOULD NOT terminate miner connection if this rare mismatch case occurs.

From 3a2031380d55217eb19871f9e954131837ec205c Mon Sep 17 00:00:00 2001
From: Ava Chow 
Date: Wed, 1 May 2024 18:00:54 -0400
Subject: [PATCH 223/454] ci: Run link format check on all mediawiki documents

---
 scripts/link-format-chk.sh | 16 +++++++---------
 1 file changed, 7 insertions(+), 9 deletions(-)

diff --git a/scripts/link-format-chk.sh b/scripts/link-format-chk.sh
index e3f0f6d770..9493765d99 100755
--- a/scripts/link-format-chk.sh
+++ b/scripts/link-format-chk.sh
@@ -8,16 +8,14 @@
 
 ECODE=0
 FILES=""
-for fname in $(git diff --name-only HEAD $(git merge-base HEAD master)); do
-    if [[ $fname == *.mediawiki ]]; then
-        GRES=$(grep -n '](http' $fname)
-        if [ "$GRES" != "" ]; then
-            if [ $ECODE -eq 0 ]; then
-                >&2 echo "Github Mediawiki format writes link as [URL text], not as [text](url):"
-            fi
-            ECODE=1
-            echo "- $fname:$GRES"
+for fname in *.mediawiki; do
+    GRES=$(grep -n '](http' $fname)
+    if [ "$GRES" != "" ]; then
+        if [ $ECODE -eq 0 ]; then
+            >&2 echo "Github Mediawiki format writes link as [URL text], not as [text](url):"
         fi
+        ECODE=1
+        echo "- $fname:$GRES"
     fi
 done
 exit $ECODE

From e2547df1cd2317e7db86b9d519df8dc02a16d102 Mon Sep 17 00:00:00 2001
From: Janus 
Date: Sun, 11 Oct 2020 16:59:38 -0500
Subject: [PATCH 224/454] Final BIP-0133

---
 README.mediawiki   | 4 ++--
 bip-0133.mediawiki | 2 +-
 2 files changed, 3 insertions(+), 3 deletions(-)

diff --git a/README.mediawiki b/README.mediawiki
index 41a93476b7..94ecb8bcb3 100644
--- a/README.mediawiki
+++ b/README.mediawiki
@@ -714,13 +714,13 @@ Those proposing changes should consider that ultimately consent may rest with th
 | Andy Chase
 | Process
 | Withdrawn
-|-
+|- style="background-color: #cfffcf"
 | [[bip-0133.mediawiki|133]]
 | Peer Services
 | feefilter message
 | Alex Morcos
 | Standard
-| Draft
+| Final
 |- style="background-color: #ffcfcf"
 | [[bip-0134.mediawiki|134]]
 | Consensus (hard fork)
diff --git a/bip-0133.mediawiki b/bip-0133.mediawiki
index c109f12ff9..b37370d9b4 100644
--- a/bip-0133.mediawiki
+++ b/bip-0133.mediawiki
@@ -5,7 +5,7 @@
   Author: Alex Morcos 
   Comments-Summary: No comments yet.
   Comments-URI: https://github.com/bitcoin/bips/wiki/Comments:BIP-0133
-  Status: Draft
+  Status: Final
   Type: Standards Track
   Created: 2016-02-13
   License: PD

From 6ea9fda9aca437778d8162f6dbf80d7a5aca6b99 Mon Sep 17 00:00:00 2001
From: Ethan Heilman 
Date: Thu, 2 May 2024 18:39:58 -0400
Subject: [PATCH 225/454] Fixes link to liar liar

---
 bip-0347.mediawiki | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/bip-0347.mediawiki b/bip-0347.mediawiki
index 8d7bf32e2d..0e198958e1 100644
--- a/bip-0347.mediawiki
+++ b/bip-0347.mediawiki
@@ -40,7 +40,7 @@ OP_CAT aims to expand the toolbox of the tapscript developer with a simple, modu
 * Bitstream, a protocol for the atomic swap (fair exchange) of bitcoins for decryption keys, that enables decentralized file hosting systems paid in Bitcoin. While such swaps are currently possible on Bitcoin without OP_CAT, they require the use of complex and computationally expensive Verifiable Computation cryptographic techniques. OP_CAT would remove this requirement on Verifiable Computation, making such protocols far more practical to build in Bitcoin. R. Linus, "BitStream: Decentralized File Hosting Incentivised via Bitcoin Payments", 2023, https://robinlinus.com/bitstream.pdf
 * Tree signatures provide a multisignature script whose size can be logarithmic in the number of public keys and can encode spend conditions beyond n-of-m. For instance a transaction less than 1KB in size could support tree signatures with up to 4,294,967,296 public keys. This also enables generalized logical spend conditions.  P. Wuille, "Multisig on steroids using tree signatures", 2015, https://blog.blockstream.com/en-treesignatures/
 * Post-Quantum Lamport signatures in Bitcoin transactions. Lamport signatures merely require the ability to hash and concatenate values on the stack. J. Rubin, "[bitcoin-dev] OP_CAT Makes Bitcoin Quantum Secure [was CheckSigFromStack for Arithmetic Values]", 2021, https://lists.linuxfoundation.org/pipermail/bitcoin-dev/2021-July/019233.html It has been proposed that if ECDSA is broken or a powerful computer was on the horizon, there might be an effort to protect ownership of bitcoins by allowing people to mark their taproot outputs as "script-path only" and then move their coins into such outputs with a leaf in the script tree requiring a Lamport signature. It is an open question if a tapscript commitment would preserve the quantum resistance of Lamport signatures. Beyond this question, the use of Lamport Signatures in taproot outputs is unlikely to be quantum resistant even if the script spend-path is made quantum resistant. This is because taproot outputs can also be spent with a key. An attacker with a sufficiently powerful quantum computer could bypass the taproot script spend-path by finding the discrete log of the taproot output and thus spending the output using the key spend-path. The use of "Nothing Up My Sleeve" (NUMS) points as described in [[bip-0341.mediawiki|BIP341]] to disable the key spend-path does not disable the key spend-path against a quantum attacker as NUMS relies on the hardness of finding discrete logs. We are not aware of any mechanism which could disable the key spend-path in a taproot output without a softfork change to taproot.
-* Non-equivocation contracts T. Ruffing, A. Kate, D. Schröder, "Liar, Liar, Coins on Fire: Penalizing Equivocation by Loss of Bitcoins", 2015, https://citeseerx.ist.psu.edu/viewdoc/download?doi=10.1.1.727.6262&rep=rep1&type=pdf in tapscript provide a mechanism to punish equivocation/double spending in Bitcoin payment channels. OP_CAT enables this by enforcing rules on the spending transaction's nonce. The capability is a useful building block for payment channels and other Bitcoin protocols.
+* Non-equivocation contracts T. Ruffing, A. Kate, D. Schröder, "Liar, Liar, Coins on Fire: Penalizing Equivocation by Loss of Bitcoins", 2015, https://dl.acm.org/doi/10.1145/2810103.2813686 in tapscript provide a mechanism to punish equivocation/double spending in Bitcoin payment channels. OP_CAT enables this by enforcing rules on the spending transaction's nonce. The capability is a useful building block for payment channels and other Bitcoin protocols.
 * Vaults M. Moser, I. Eyal, and E. G. Sirer, Bitcoin Covenants, http://fc16.ifca.ai/bitcoin/papers/MES16.pdf which are a specialized covenant that allows a user to block a malicious party who has compromised the user's secret key from stealing the funds in that output. As shown in A. Poelstra, "CAT and Schnorr Tricks II", 2021, https://www.wpsoftware.net/andrew/blog/cat-and-schnorr-tricks-ii.html OP_CAT is sufficient to build vaults in Bitcoin.
 * Replicating CheckSigFromStack A. Poelstra, "CAT and Schnorr Tricks I", 2021, https://medium.com/blockstream/cat-and-schnorr-tricks-i-faf1b59bd298 which would allow the creation of simple covenants and other advanced contracts without having to presign spending transactions, possibly reducing complexity and the amount of data that needs to be stored. Originally shown to work with Schnorr signatures, this result has been extended to ECDSA signatures R. Linus, "Covenants with CAT and ECDSA", 2023, https://gist.github.com/RobinLinus/9a69f5552be94d13170ec79bf34d5e85#file-covenants_cat_ecdsa-md.
 

From 31f51927f12906678e9e710c2871eccc0fc2dd40 Mon Sep 17 00:00:00 2001
From: Murch 
Date: Thu, 2 May 2024 21:57:31 -0400
Subject: [PATCH 226/454] Add BIP-347 OP_CAT to table

---
 README.mediawiki | 7 +++++++
 1 file changed, 7 insertions(+)

diff --git a/README.mediawiki b/README.mediawiki
index 96b8df3372..ed7df0c9de 100644
--- a/README.mediawiki
+++ b/README.mediawiki
@@ -1072,6 +1072,13 @@ Those proposing changes should consider that ultimately consent may rest with th
 | Standard
 | Final
 |-
+| [[bip-0347.mediawiki|347]]
+| Consensus (soft fork)
+| OP_CAT in Tapscript
+| Ethan Heilman, Armin Sabouri
+| Standard
+| Draft
+|-
 | [[bip-0350.mediawiki|350]]
 | Applications
 | Bech32m format for v1+ witness addresses

From 1ed7d03393988facec21bfb1cabdf11685c78aea Mon Sep 17 00:00:00 2001
From: Yannick Seurin 
Date: Fri, 3 May 2024 10:31:27 +0200
Subject: [PATCH 227/454] more precise wording for key-prefixing justification

---
 bip-0340.mediawiki | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/bip-0340.mediawiki b/bip-0340.mediawiki
index 1aeb1c2978..3fd491fb6d 100644
--- a/bip-0340.mediawiki
+++ b/bip-0340.mediawiki
@@ -62,7 +62,7 @@ Since we would like to avoid the fragility that comes with short hashes, the ''e
 
 '''Key prefixing''' Using the verification rule above directly makes Schnorr signatures vulnerable to "related-key attacks" in which a third party can convert a signature ''(R, s)'' for public key ''P'' into a signature ''(R, s + a⋅hash(R || m))'' for public key ''P + a⋅G'' and the same message ''m'', for any given additive tweak ''a'' to the signing key. This would render signatures insecure when keys are generated using [[bip-0032.mediawiki#public-parent-key--public-child-key|BIP32's unhardened derivation]] and other methods that rely on additive tweaks to existing keys such as Taproot.
 
-To protect against these attacks, we choose ''key prefixed''A limitation of committing to the public key (rather than to a short hash of it, or not at all) is that it removes the ability for public key recovery or verifying signatures against a short public key hash. These constructions are generally incompatible with batch verification. Schnorr signatures which means that the public key is prefixed to the message in the challenge hash input. This changes the equation to ''s⋅G = R + hash(R || P || m)⋅P''. [https://eprint.iacr.org/2015/1135.pdf It can be shown] that key prefixing protects against related-key attacks with additive tweaks. In general, key prefixing increases robustness in multi-user settings, e.g., it seems to be a requirement for proving the MuSig2 multisignature scheme secure (see Applications below).
+To protect against these attacks, we choose ''key prefixed''A limitation of committing to the public key (rather than to a short hash of it, or not at all) is that it removes the ability for public key recovery or verifying signatures against a short public key hash. These constructions are generally incompatible with batch verification. Schnorr signatures which means that the public key is prefixed to the message in the challenge hash input. This changes the equation to ''s⋅G = R + hash(R || P || m)⋅P''. [https://eprint.iacr.org/2015/1135.pdf It can be shown] that key prefixing protects against related-key attacks with additive tweaks. In general, key prefixing increases robustness in multi-user settings, e.g., it seems to be a requirement for proving multiparty signature protocols (such as MuSig, MuSig2, and FROST) secure (see Applications below).
 
 We note that key prefixing is not strictly necessary for transaction signatures as used in Bitcoin currently, because signed transactions indirectly commit to the public keys already, i.e., ''m'' contains a commitment to ''pk''. However, this indirect commitment should not be relied upon because it may change with proposals such as SIGHASH_NOINPUT ([[bip-0118.mediawiki|BIP118]]), and would render the signature scheme unsuitable for other purposes than signing transactions, e.g., [https://bitcoin.org/en/developer-reference#signmessage signing ordinary messages].
 

From 4dcdadee675db63e241cda71cdfca9ebe96ce0bf Mon Sep 17 00:00:00 2001
From: Yannick Seurin 
Date: Fri, 3 May 2024 10:32:42 +0200
Subject: [PATCH 228/454] update changelog

---
 bip-0340.mediawiki | 1 +
 1 file changed, 1 insertion(+)

diff --git a/bip-0340.mediawiki b/bip-0340.mediawiki
index 3fd491fb6d..03ec45d75b 100644
--- a/bip-0340.mediawiki
+++ b/bip-0340.mediawiki
@@ -293,6 +293,7 @@ To help implementors understand updates to this BIP, we keep a list of substanti
 
 * 2022-08: Fix function signature of lift_x in reference code
 * 2023-04: Allow messages of arbitrary size
+* 2024-05: Update "Applications" section with more recent references
 
 == Footnotes ==
 

From cda34eef1c2543ece1205240f27e8d1cfffb336d Mon Sep 17 00:00:00 2001
From: Ethan Heilman 
Date: Sun, 5 May 2024 17:57:27 -0400
Subject: [PATCH 229/454] Improved accuracy of paragraph on OP_CAT's removal in
 2010

---
 bip-0347.mediawiki | 8 ++++++--
 1 file changed, 6 insertions(+), 2 deletions(-)

diff --git a/bip-0347.mediawiki b/bip-0347.mediawiki
index 0e198958e1..545ffbb6fa 100644
--- a/bip-0347.mediawiki
+++ b/bip-0347.mediawiki
@@ -44,8 +44,12 @@ OP_CAT aims to expand the toolbox of the tapscript developer with a simple, modu
 * Vaults M. Moser, I. Eyal, and E. G. Sirer, Bitcoin Covenants, http://fc16.ifca.ai/bitcoin/papers/MES16.pdf which are a specialized covenant that allows a user to block a malicious party who has compromised the user's secret key from stealing the funds in that output. As shown in A. Poelstra, "CAT and Schnorr Tricks II", 2021, https://www.wpsoftware.net/andrew/blog/cat-and-schnorr-tricks-ii.html OP_CAT is sufficient to build vaults in Bitcoin.
 * Replicating CheckSigFromStack A. Poelstra, "CAT and Schnorr Tricks I", 2021, https://medium.com/blockstream/cat-and-schnorr-tricks-i-faf1b59bd298 which would allow the creation of simple covenants and other advanced contracts without having to presign spending transactions, possibly reducing complexity and the amount of data that needs to be stored. Originally shown to work with Schnorr signatures, this result has been extended to ECDSA signatures R. Linus, "Covenants with CAT and ECDSA", 2023, https://gist.github.com/RobinLinus/9a69f5552be94d13170ec79bf34d5e85#file-covenants_cat_ecdsa-md.
 
-The opcode OP_CAT was available in early versions of Bitcoin. However, OP_CAT was removed because it enabled the construction of a script whose evaluation could have memory usage exponential in the size of the script.
-For example, a script that pushed a 1-byte value on the stack and then repeated the opcodes OP_DUP, OP_CAT 40 times would result in a stack value whose size was greater than 1 terabyte. This is no longer an issue because tapscript enforces a maximum stack element size of 520 bytes.
+OP_CAT was available in early versions of Bitcoin. 
+In 2010, a single commit disabled OP_CAT, along with another 15 opcodes.
+Folklore states that OP_CAT was removed in this commit because it enabled the construction of a script whose evaluation could have memory usage exponential in the size of the script.
+For example, a script that pushed a 1-byte value on the stack and then repeated the opcodes OP_DUP, OP_CAT 40 times would result in a stack element whose size was greater than 1 terabyte assuming no maximum stack element size. As Bitcoin at that time had a maximum stack element size of 5000 bytes, the effect of this expansion was limited to 5000 bytes.
+This is no longer an issue because tapscript enforces a maximum stack element size of 520 bytes.
+
 
 ==Rationale==
 

From 1f1f24f0efad7604c57b3570d7cd0ccee68b4984 Mon Sep 17 00:00:00 2001
From: Yannick Seurin 
Date: Mon, 6 May 2024 11:39:15 +0200
Subject: [PATCH 230/454] spelling out FROST

Co-authored-by: Tim Ruffing 
---
 bip-0340.mediawiki | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/bip-0340.mediawiki b/bip-0340.mediawiki
index 03ec45d75b..1d9aa29d6a 100644
--- a/bip-0340.mediawiki
+++ b/bip-0340.mediawiki
@@ -266,7 +266,7 @@ While recent academic papers claim that they are also possible with ECDSA, conse
 
 By means of an interactive scheme such as [https://eprint.iacr.org/2020/1261.pdf MuSig2] ([[bip-0327.mediawiki|BIP327]]), participants can aggregate their public keys into a single public key which they can jointly sign for. This allows ''n''-of-''n'' multisignatures which, from a verifier's perspective, are no different from ordinary signatures, giving improved privacy and efficiency versus ''CHECKMULTISIG'' or other means.
 
-Moreover, Schnorr signatures are compatible with [https://en.wikipedia.org/wiki/Distributed_key_generation distributed key generation], which enables interactive threshold signatures schemes, e.g., the schemes described by [http://cacr.uwaterloo.ca/techreports/2001/corr2001-13.ps Stinson and Strobl (2001)], [https://link.springer.com/content/pdf/10.1007/s00145-006-0347-3.pdf Gennaro, Jarecki, Krawczyk, and Rabin (2007)], [https://eprint.iacr.org/2020/852.pdf Komlo and Goldberg (2020)], or [https://eprint.iacr.org/2023/899.pdf Chu, Gerhart, Ruffing, and Schröder (2023)]. These protocols make it possible to realize ''k''-of-''n'' threshold signatures, which ensure that any subset of size ''k'' of the set of ''n'' signers can sign but no subset of size less than ''k'' can produce a valid Schnorr signature.
+Moreover, Schnorr signatures are compatible with [https://en.wikipedia.org/wiki/Distributed_key_generation distributed key generation], which enables interactive threshold signatures schemes, e.g., the schemes by [http://cacr.uwaterloo.ca/techreports/2001/corr2001-13.ps Stinson and Strobl (2001)], by [https://link.springer.com/content/pdf/10.1007/s00145-006-0347-3.pdf Gennaro, Jarecki, Krawczyk, and Rabin (2007)], or the [https://eprint.iacr.org/2020/852.pdf FROST] scheme including its variants such as [https://eprint.iacr.org/2023/899.pdf FROST3]. These protocols make it possible to realize ''k''-of-''n'' threshold signatures, which ensure that any subset of size ''k'' of the set of ''n'' signers can sign but no subset of size less than ''k'' can produce a valid Schnorr signature.
 
 === Adaptor Signatures ===
 

From 5d10163efc36331eba5426dd854d91f0f68170f4 Mon Sep 17 00:00:00 2001
From: Yannick Seurin 
Date: Mon, 6 May 2024 11:40:02 +0200
Subject: [PATCH 231/454] more precise wording

Co-authored-by: Tim Ruffing 
---
 bip-0340.mediawiki | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/bip-0340.mediawiki b/bip-0340.mediawiki
index 1d9aa29d6a..85b7bac4dc 100644
--- a/bip-0340.mediawiki
+++ b/bip-0340.mediawiki
@@ -62,7 +62,7 @@ Since we would like to avoid the fragility that comes with short hashes, the ''e
 
 '''Key prefixing''' Using the verification rule above directly makes Schnorr signatures vulnerable to "related-key attacks" in which a third party can convert a signature ''(R, s)'' for public key ''P'' into a signature ''(R, s + a⋅hash(R || m))'' for public key ''P + a⋅G'' and the same message ''m'', for any given additive tweak ''a'' to the signing key. This would render signatures insecure when keys are generated using [[bip-0032.mediawiki#public-parent-key--public-child-key|BIP32's unhardened derivation]] and other methods that rely on additive tweaks to existing keys such as Taproot.
 
-To protect against these attacks, we choose ''key prefixed''A limitation of committing to the public key (rather than to a short hash of it, or not at all) is that it removes the ability for public key recovery or verifying signatures against a short public key hash. These constructions are generally incompatible with batch verification. Schnorr signatures which means that the public key is prefixed to the message in the challenge hash input. This changes the equation to ''s⋅G = R + hash(R || P || m)⋅P''. [https://eprint.iacr.org/2015/1135.pdf It can be shown] that key prefixing protects against related-key attacks with additive tweaks. In general, key prefixing increases robustness in multi-user settings, e.g., it seems to be a requirement for proving multiparty signature protocols (such as MuSig, MuSig2, and FROST) secure (see Applications below).
+To protect against these attacks, we choose ''key prefixed''A limitation of committing to the public key (rather than to a short hash of it, or not at all) is that it removes the ability for public key recovery or verifying signatures against a short public key hash. These constructions are generally incompatible with batch verification. Schnorr signatures which means that the public key is prefixed to the message in the challenge hash input. This changes the equation to ''s⋅G = R + hash(R || P || m)⋅P''. [https://eprint.iacr.org/2015/1135.pdf It can be shown] that key prefixing protects against related-key attacks with additive tweaks. In general, key prefixing increases robustness in multi-user settings, e.g., it seems to be a requirement for proving multiparty signing protocols (such as MuSig, MuSig2, and FROST) secure (see Applications below).
 
 We note that key prefixing is not strictly necessary for transaction signatures as used in Bitcoin currently, because signed transactions indirectly commit to the public keys already, i.e., ''m'' contains a commitment to ''pk''. However, this indirect commitment should not be relied upon because it may change with proposals such as SIGHASH_NOINPUT ([[bip-0118.mediawiki|BIP118]]), and would render the signature scheme unsuitable for other purposes than signing transactions, e.g., [https://bitcoin.org/en/developer-reference#signmessage signing ordinary messages].
 

From 7ad0f821ddc60366e98344a1e3019114ae46c80f Mon Sep 17 00:00:00 2001
From: Ethan Heilman 
Date: Mon, 6 May 2024 13:12:47 -0400
Subject: [PATCH 232/454] Adds stable URL for Liar, Liar, Coins on Fire!

---
 bip-0347.mediawiki | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/bip-0347.mediawiki b/bip-0347.mediawiki
index 545ffbb6fa..981af8127b 100644
--- a/bip-0347.mediawiki
+++ b/bip-0347.mediawiki
@@ -40,7 +40,7 @@ OP_CAT aims to expand the toolbox of the tapscript developer with a simple, modu
 * Bitstream, a protocol for the atomic swap (fair exchange) of bitcoins for decryption keys, that enables decentralized file hosting systems paid in Bitcoin. While such swaps are currently possible on Bitcoin without OP_CAT, they require the use of complex and computationally expensive Verifiable Computation cryptographic techniques. OP_CAT would remove this requirement on Verifiable Computation, making such protocols far more practical to build in Bitcoin. R. Linus, "BitStream: Decentralized File Hosting Incentivised via Bitcoin Payments", 2023, https://robinlinus.com/bitstream.pdf
 * Tree signatures provide a multisignature script whose size can be logarithmic in the number of public keys and can encode spend conditions beyond n-of-m. For instance a transaction less than 1KB in size could support tree signatures with up to 4,294,967,296 public keys. This also enables generalized logical spend conditions.  P. Wuille, "Multisig on steroids using tree signatures", 2015, https://blog.blockstream.com/en-treesignatures/
 * Post-Quantum Lamport signatures in Bitcoin transactions. Lamport signatures merely require the ability to hash and concatenate values on the stack. J. Rubin, "[bitcoin-dev] OP_CAT Makes Bitcoin Quantum Secure [was CheckSigFromStack for Arithmetic Values]", 2021, https://lists.linuxfoundation.org/pipermail/bitcoin-dev/2021-July/019233.html It has been proposed that if ECDSA is broken or a powerful computer was on the horizon, there might be an effort to protect ownership of bitcoins by allowing people to mark their taproot outputs as "script-path only" and then move their coins into such outputs with a leaf in the script tree requiring a Lamport signature. It is an open question if a tapscript commitment would preserve the quantum resistance of Lamport signatures. Beyond this question, the use of Lamport Signatures in taproot outputs is unlikely to be quantum resistant even if the script spend-path is made quantum resistant. This is because taproot outputs can also be spent with a key. An attacker with a sufficiently powerful quantum computer could bypass the taproot script spend-path by finding the discrete log of the taproot output and thus spending the output using the key spend-path. The use of "Nothing Up My Sleeve" (NUMS) points as described in [[bip-0341.mediawiki|BIP341]] to disable the key spend-path does not disable the key spend-path against a quantum attacker as NUMS relies on the hardness of finding discrete logs. We are not aware of any mechanism which could disable the key spend-path in a taproot output without a softfork change to taproot.
-* Non-equivocation contracts T. Ruffing, A. Kate, D. Schröder, "Liar, Liar, Coins on Fire: Penalizing Equivocation by Loss of Bitcoins", 2015, https://dl.acm.org/doi/10.1145/2810103.2813686 in tapscript provide a mechanism to punish equivocation/double spending in Bitcoin payment channels. OP_CAT enables this by enforcing rules on the spending transaction's nonce. The capability is a useful building block for payment channels and other Bitcoin protocols.
+* Non-equivocation contracts T. Ruffing, A. Kate, D. Schröder, "Liar, Liar, Coins on Fire: Penalizing Equivocation by Loss of Bitcoins", 2015, https://web.archive.org/web/20221023121048/https://publications.cispa.saarland/565/1/penalizing.pdf in tapscript provide a mechanism to punish equivocation/double spending in Bitcoin payment channels. OP_CAT enables this by enforcing rules on the spending transaction's nonce. The capability is a useful building block for payment channels and other Bitcoin protocols.
 * Vaults M. Moser, I. Eyal, and E. G. Sirer, Bitcoin Covenants, http://fc16.ifca.ai/bitcoin/papers/MES16.pdf which are a specialized covenant that allows a user to block a malicious party who has compromised the user's secret key from stealing the funds in that output. As shown in A. Poelstra, "CAT and Schnorr Tricks II", 2021, https://www.wpsoftware.net/andrew/blog/cat-and-schnorr-tricks-ii.html OP_CAT is sufficient to build vaults in Bitcoin.
 * Replicating CheckSigFromStack A. Poelstra, "CAT and Schnorr Tricks I", 2021, https://medium.com/blockstream/cat-and-schnorr-tricks-i-faf1b59bd298 which would allow the creation of simple covenants and other advanced contracts without having to presign spending transactions, possibly reducing complexity and the amount of data that needs to be stored. Originally shown to work with Schnorr signatures, this result has been extended to ECDSA signatures R. Linus, "Covenants with CAT and ECDSA", 2023, https://gist.github.com/RobinLinus/9a69f5552be94d13170ec79bf34d5e85#file-covenants_cat_ecdsa-md.
 

From 945b281155f12d50be76ade722cbb1a04681caa0 Mon Sep 17 00:00:00 2001
From: Ava Chow 
Date: Wed, 17 Apr 2024 18:25:00 -0400
Subject: [PATCH 233/454] BIP 387: multi_a() descriptor

---
 README.mediawiki   |   7 ++++
 bip-0387.mediawiki | 101 +++++++++++++++++++++++++++++++++++++++++++++
 2 files changed, 108 insertions(+)
 create mode 100644 bip-0387.mediawiki

diff --git a/README.mediawiki b/README.mediawiki
index 43e60a4093..b613944281 100644
--- a/README.mediawiki
+++ b/README.mediawiki
@@ -1163,6 +1163,13 @@ Those proposing changes should consider that ultimately consent may rest with th
 | Informational
 | Draft
 |-
+| [[bip-0387.mediawiki|387]]
+| Applications
+| Tapscript Multisig Output Script Descriptors
+| Pieter Wuille, Ava Chow
+| Informational
+| Draft
+|-
 | [[bip-0389.mediawiki|389]]
 | Applications
 | Multipath Descriptor Key Expressions
diff --git a/bip-0387.mediawiki b/bip-0387.mediawiki
new file mode 100644
index 0000000000..5c039b8fe9
--- /dev/null
+++ b/bip-0387.mediawiki
@@ -0,0 +1,101 @@
+
+  BIP: 387
+  Layer: Applications
+  Title: Tapscript Multisig Output Script Descriptors
+  Author: Pieter Wuille 
+          Ava Chow 
+  Comments-Summary: No comments yet.
+  Comments-URI: https://github.com/bitcoin/bips/wiki/Comments:BIP-0387
+  Status: Draft
+  Type: Informational
+  Created: 2024-04-17
+  License: BSD-2-Clause
+
+ +==Abstract== + +This document specifies multi_a() and sortedmulti_a() output script descriptors. +Like BIP 383's multi() and sortedmulti(), both functions take a threshold and one +or more public keys and produce a multisig script. The primary distinction is that multi_a() +and sortedmulti_a() only produce tapscripts and are only allowed in a tapscript context. + +==Copyright== + +This BIP is licensed under the BSD 2-clause license. + +==Motivation== + +The most common complex script used in Bitcoin is a threshold multisig. +These expressions allow specifying multisig scripts as a descriptor. + +==Specification== + +Two new script expressions are defined: multi_a() and sortedmulti_a(). +Both expressions produce the scripts of the same template and take the same arguments. +They are written as multi_a(k,KEY_1,KEY_2,...,KEY_n). +k is the threshold - the number of keys that must sign the input for the script to be valid. +KEY_1,KEY_2,...,KEY_n are the key expressions for the multisig. k must be less than or equal to n. + +multi_a() and sortedmulti_a() expressions can only be used inside of a tr() descriptor. +The maximum number of keys is 999. + +The output script produced also depends on the value of k. If k is less than or equal to 16: +
+KEY_1 OP_CHECKSIG KEY_2 OP_CHECKSIGADD ... KEY_n OP_CHECKSIGADD OP_k OP_NUMEQUAL
+
+ +if k is greater than 16: +
+KEY_1 OP_CHECKSIG KEY_2 OP_CHECKSIGADD ... KEY_n OP_CHECKSIGADD k OP_NUMEQUAL
+
+ +===sortedmulti_a()=== + +The only change for sortedmulti_a() is that the x-only public keys are sorted lexicographically prior to the creation of the output script. +This sorting is on the keys that are to be put into the output script, i.e. after all extended keys are derived. + +===Multiple Extended Keys=== + +When one or more of the key expressions in a multi_a() or sortedmulti_a() expression are extended keys, the derived keys use the same child index. +This changes the keys in lockstep and allows for output scripts to be indexed in the same way that the derived keys are indexed. + +==Test Vectors== + +Valid descriptors followed by the scripts they produce. Descriptors involving derived child keys will have the 0th, 1st, and 2nd scripts listed. + +* tr(L4rK1yDtCWekvXuE6oXD9jCYfFNV2cWRpVuPLBcCU2z8TrisoyY1,multi_a(1,KzoAz5CanayRKex3fSLQ2BwJpN7U52gZvxMyk78nDMHuqrUxuSJy)) +** 5120eb5bd3894327d75093891cc3a62506df7d58ec137fcd104cdd285d67816074f3 +* tr(a34b99f22c790c4e36b2b3c2c35a36db06226e41c692fc82b8b56ac1c540c5bd,multi_a(1,669b8afcec803a0d323e9a17f3ea8e68e8abe5a278020a929adbec52421adbd0)) +** 5120eb5bd3894327d75093891cc3a62506df7d58ec137fcd104cdd285d67816074f3 +* tr(50929b74c1a04954b78b4b6035e97a5e078a5a0f28ec96d547bfee9ace803ac0,multi_a(2,[00000000/111'/222]xprvA1RpRA33e1JQ7ifknakTFpgNXPmW2YvmhqLQYMmrj4xJXXWYpDPS3xz7iAxn8L39njGVyuoseXzU6rcxFLJ8HFsTjSyQbLYnMpCqE2VbFWc,xprv9uPDJpEQgRQfDcW7BkF7eTya6RPxXeJCqCJGHuCJ4GiRVLzkTXBAJMu2qaMWPrS7AANYqdq6vcBcBUdJCVVFceUvJFjaPdGZ2y9WACViL4L/0)) +** 51202eea93581594a43c0c8423b70dc112e5651df63984d108d4fc8ccd3b63b4eafa +* tr(50929b74c1a04954b78b4b6035e97a5e078a5a0f28ec96d547bfee9ace803ac0,sortedmulti_a(2,[00000000/111'/222]xprvA1RpRA33e1JQ7ifknakTFpgNXPmW2YvmhqLQYMmrj4xJXXWYpDPS3xz7iAxn8L39njGVyuoseXzU6rcxFLJ8HFsTjSyQbLYnMpCqE2VbFWc,xprv9uPDJpEQgRQfDcW7BkF7eTya6RPxXeJCqCJGHuCJ4GiRVLzkTXBAJMu2qaMWPrS7AANYqdq6vcBcBUdJCVVFceUvJFjaPdGZ2y9WACViL4L/0)) +** 512016fa6a6ba7e98c54b5bf43b3144912b78a61b60b02f6a74172b8dcb35b12bc30 +* tr(50929b74c1a04954b78b4b6035e97a5e078a5a0f28ec96d547bfee9ace803ac0,sortedmulti_a(2,xpub6ERApfZwUNrhLCkDtcHTcxd75RbzS1ed54G1LkBUHQVHQKqhMkhgbmJbZRkrgZw4koxb5JaHWkY4ALHY2grBGRjaDMzQLcgJvLJuZZvRcEL/*,xpub68NZiKmJWnxxS6aaHmn81bvJeTESw724CRDs6HbuccFQN9Ku14VQrADWgqbhhTHBaohPX4CjNLf9fq9MYo6oDaPPLPxSb7gwQN3ih19Zm4Y/0/0/*)) +** 5120abd47468515223f58a1a18edfde709a7a2aab2b696d59ecf8c34f0ba274ef772 +** 5120fe62e7ed20705bd1d3678e072bc999acb014f07795fa02cb8f25a7aa787e8cbd +** 51201311093750f459039adaa2a5ed23b0f7a8ae2c2ffb07c5390ea37e2fb1050b41 +* tr(50929b74c1a04954b78b4b6035e97a5e078a5a0f28ec96d547bfee9ace803ac0,multi_a(2,xprv9s21ZrQH143K31xYSDQpPDxsXRTUcvj2iNHm5NUtrGiGG5e2DtALGdso3pGz6ssrdK4PFmM8NSpSBHNqPqm55Qn3LqFtT2emdEXVYsCzC2U/2147483647'/0,xprv9vHkqa6EV4sPZHYqZznhT2NPtPCjKuDKGY38FBWLvgaDx45zo9WQRUT3dKYnjwih2yJD9mkrocEZXo1ex8G81dwSM1fwqWpWkeS3v86pgKt/1/2/*,xprv9s21ZrQH143K3QTDL4LXw2F7HEK3wJUD2nW2nRk4stbPy6cq3jPPqjiChkVvvNKmPGJxWUtg6LnF5kejMRNNU3TGtRBeJgk33yuGBxrMPHi/10/20/30/40/*')) +** 5120e4c8f2b0a7d3a688ac131cb03248c0d4b0a59bbd4f37211c848cfbd22a981192 +** 5120827faedaa21e52fca2ac83b53afd1ab7d4d1e6ce67ff42b19f2723d48b5a19ab +** 5120647495ed09de61a3a324704f9203c130d655bf3141f9b748df8f7be7e9af55a4 + +Invalid descriptors + +* Unsupported top level: multi_a(1,03669b8afcec803a0d323e9a17f3ea8e68e8abe5a278020a929adbec52421adbd0) +* Unsupported sh() context: sh(multi_a(1,03669b8afcec803a0d323e9a17f3ea8e68e8abe5a278020a929adbec52421adbd0)) +* Unsupported wsh() context: wsh(multi_a(1,03669b8afcec803a0d323e9a17f3ea8e68e8abe5a278020a929adbec52421adbd0)) +* Invalid threshold: tr(50929b74c1a04954b78b4b6035e97a5e078a5a0f28ec96d547bfee9ace803ac0,multi_a(a,03a34b99f22c790c4e36b2b3c2c35a36db06226e41c692fc82b8b56ac1c540c5bd)) +* Threshold of 0: tr(50929b74c1a04954b78b4b6035e97a5e078a5a0f28ec96d547bfee9ace803ac0,multi_a(0,03a34b99f22c790c4e36b2b3c2c35a36db06226e41c692fc82b8b56ac1c540c5bd)) +* Uncompressed pubkey: tr(50929b74c1a04954b78b4b6035e97a5e078a5a0f28ec96d547bfee9ace803ac0,multi_a(1,04a34b99f22c790c4e36b2b3c2c35a36db06226e41c692fc82b8b56ac1c540c5bd5b8dec5235a0fa8722476c7709c02559e3aa73aa03918ba2d492eea75abea235)) +* Threshold larger than keys: tr(50929b74c1a04954b78b4b6035e97a5e078a5a0f28ec96d547bfee9ace803ac0,multi_a(3,L4rK1yDtCWekvXuE6oXD9jCYfFNV2cWRpVuPLBcCU2z8TrisoyY1,5KYZdUEo39z3FPrtuX2QbbwGnNP5zTd7yyr2SC1j299sBCnWjss)) + +==Backwards Compatibility== + +multi_a() and sortedmulti_a() descriptors use the format and general operation specified in [[bip-0380.mediawiki|380]]. +As these are wholly new descriptors, they are not compatible with any implementation. +However, the scripts produced are standard scripts, so existing software are likely to be familiar with them. + +==Reference Implementation== + +multi_a() and sortedmulti_a() descriptors were implemented in Bitcoin Core in https://github.com/bitcoin/bitcoin/pull/24043 and have been available since version 24.0. From 44798a2a9e19643040af61818a7acb4cded47e00 Mon Sep 17 00:00:00 2001 From: Salvatore Ingala <6681844+bigspider@users.noreply.github.com> Date: Thu, 1 Sep 2022 15:30:54 +0200 Subject: [PATCH 234/454] New BIP: Wallet Policies --- bip-wallet-policies.mediawiki | 343 +++++++++++++++++++++++++ bip-wallet-policies/wallet_policies.py | 200 ++++++++++++++ 2 files changed, 543 insertions(+) create mode 100644 bip-wallet-policies.mediawiki create mode 100644 bip-wallet-policies/wallet_policies.py diff --git a/bip-wallet-policies.mediawiki b/bip-wallet-policies.mediawiki new file mode 100644 index 0000000000..e46df1c646 --- /dev/null +++ b/bip-wallet-policies.mediawiki @@ -0,0 +1,343 @@ +
+  BIP: wallet-policies
+  Layer: Applications
+  Title: Wallet Policies for Descriptor Wallets
+  Author: Salvatore Ingala 
+  Comments-Summary: No comments yet.
+  Comments-URI: https://github.com/bitcoin/bips/wiki/Comments:BIP-wallet-policies
+  Status: Draft
+  Type: Informational
+  Created: 2022-11-16
+  License: BSD-2-Clause
+
+ +== Abstract == + +Wallet policies build on top of output descriptors to represent in a compact, easier to inspect way the types of descriptors that are typically used to represent "accounts" in a software wallet, or a hardware signing device. A wallet policy always represents exactly two descriptors, which produce the receive and change addresses that are logically part of the same account. + +Reducing the generality of descriptors to just the essential features, and separating the extended pubkeys and other key information from the descriptor, allows to simplify the language in a way that suits devices with limited memory, where even keeping the entire descriptor in memory could be a major hurdle. + +Moreover, together with the gain in compactness, this simplifies user's inspection of the policy. + +Finally, by keeping the language extremely close to that of output script descriptors, the compilation of wallet policies to the corresponding descriptor is extremely easy, and even the reverse process is not too difficult for supported descriptors. + +== Copyright == + +This BIP is licensed under the BSD 2-clause license. + +== Motivation == + +''[[bip-0380.mediawiki|Output Script Descriptors]]'' were introduced in bitcoin-core as a way to represent collections of output scripts. It is a very general and flexible language, designed to catch all the possible use-cases of bitcoin wallets (that is, if you know the script and you have the necessary keys, it will be possible to sign transactions with any descriptor-based software wallet). + +Unfortunately, descriptors are not a perfect match for the typical usage of hardware signing devices (often also called ''hardware wallets''). Most of them have some of the following limitations when compared to a general-purpose machine running bitcoin-core: + +* they are embedded devices with limited RAM, and computational power; +* they cannot import additional private keys (that is, they can only sign with keys derived from a single seed via [[bip-0032.mediawiki|BIP-32]]); +* they have limited storage, or they might not have persistent storage at all (''stateless design''). + +Moreover, other limitations like the limited size of the screen might affect what design choices are available in practice. Therefore, minimizing the size of the information shown on-screen is important for a good user experience; that is crucial since the ability for the user to completely validate on-screen the kind of script used (and each of the involved keys) is a prerequisite for secure usage, as the machine that is interacting with the hardware signer (and running the software wallet) is considered untrusted. + +A more native, compact representation of the wallet receive/change might also benefit the UX of software wallets using descriptors to represent software wallets using descriptors (possibly with miniscript) for complex locking conditions. + +We remark that wallet policies are not related to the ''policy'' language, a higher level language that can be compiled to miniscript. + +=== Security and UX concerns for hardware signing devices === + +For a hardware signing device, allowing the usage of complex scripts presents challenges in terms of both security and user experience. + +==== Security issues ==== + +One of the security properties that hardware signing devices strive to guarantee is the following: as long as the user correctly verifies the information that is shown on the device's screen before approving, no action can be performed without the user's consent. + +This must hold even in scenarios where the attacker has full control of the machine that is connected to the signing device, and can execute arbitrary requests, or tamper with the legitimate user's requests. + +Therefore, it is not at all trivial to allow complex scripts, especially if they contain keys that belong to third parties. +The hardware signing device must guarantee that the user knows precisely what "policy" is being used to spend the funds, and that any "unspent" funds (if any) that is sent to a change address will be protected by the same policy. + +This makes it impossible for an attacker to surreptitiously modify the policy, therefore stealing or burning the user's funds. + +==== UX issues ==== + +With miniscript (and taproot trees) allowing substantially more complex spending policies to be used, it becomes more challenging to make sure that the user is practically able to verify the information on the screen. + +Therefore, there are two fundamental design goals to strive for: +* Minimize the amount of information that is shown on screen - so that the user can actually validate it. +* Minimize the number of times the user has to validate such information. + +Designing a secure protocol for the coordination of a descriptor wallet among distant parties is also a challenging problem that is out of scope in this document. See [[bip-00129.mediawiki|BIP-129 (Bitcoin Secure Multisig Setup)]] for an approach designed for multisignature wallets. Regardless the approach, the ability for the user to carefully verify all the details of the spending policies using the hardware signer's screen is a prerequisite for security in adversarial environments. + +=== Policy registration as a solution === + +A solution to address the security concerns, and part of the UX concerns, is to have a registration flow for the wallet policy in the hardware signing device. The ''wallet policy'' must contain enough information to generate all the relevant addresses/scripts, and for the hardware signing device to identify the keys that it controls and that are needed to spend the funds sent to those addresses. + +Before a new policy is used for the first time, the user will register a wallet policy into the hardware device. While the details of the process are out of scope in this document, the flow should be something similar to the following: + +# The software wallet initiates a ''wallet policy registration'' on the hardware signing device; the information should include the wallet policy, but also a unique ''name'' that identifies the policy. +# The device shows the wallet policy to the user using the secure screen. +# After inspecting the policy and comparing it with a trusted source (for example a printed backup), the user approves the policy. +# If stateful, the hardware signing device persists the policy in its permanent memory; if stateless, it returns a "proof of registration". + +The proof of registration will allow the hardware signer to verify that a certain policy was indeed previously approved by the user, and is therefore safe to use without repeating the expensive user verification procedure. The details of how to create a proof of registration are out of scope for this document; using a Message Authentication Code on a hash committing to the wallet policy, its name and any additional metadata is an effective solution if correctly executed. + +Once a policy is registered, the hardware signing device can perform the typical operations securely: +* generating receive and change addresses; +* showing addresses on the secure screen; +* sign transactions spending from a wallet, while correctly identifying change addresses and computing the transaction fees. + +Before any of the actions mentioned above, the hardware signing device will retrieve the policy from its permanent storage if stateful; if stateless it will validate the _proof of registration_ before using the wallet policy provided by the client. + +Once the previously registered policy is correctly identified and approved by the user (for example by showing its name), and as long as the policy registration was executed securely, hardware signing devices can provide a user experience similar to the usual one for single-signature transactions. + +=== Avoiding blowup in descriptor size === + +While reusing a pubkey in different branches of a miniscript is explicitly forbidden by miniscript (as it has certain negative security implications), it is still reasonable to reuse the same xpub in multiple places, albeit with different final steps of derivation (so that the actual pubkeys that are used in the script are indeed different). + +For example, using Taproot, a 3-of-5 multisignature wallet could use: +* a key path with a 5-of-5 MuSig2 aggregated key +* a script tree with 11 leaves: +** 10 different script using a 3-of-3 MuSig2 aggregated key, plus +** a final leaf with a fallback 3-of-5 multisignature using OP_CHECKSIGADD (in case interactive signing is not available). + +This could look similar to: + +
+tr(musig(xpubA,xpubB,xpubC,xpubD,xpubE)/<0;1>/*), {
+  {
+    {
+      pk(musig(xpubA,xpubB,xpubC)/<2;3>/*),
+      {
+        pk(musig(xpubA,xpubB,xpubD)/<4;5>/*)
+        pk(musig(xpubA,xpubB,xpubE)/<6;7>/*),
+      }
+    },
+    {
+      pk(musig(xpubA,xpubC,xpubD)/<8;9>/*),
+      {
+        pk(musig(xpubA,xpubC,xpubE)/<10;11>/*),
+        pk(musig(xpubA,xpubD,xpubE)/<12;13>/*)
+      }
+    }
+  },
+  {
+    {
+      pk(musig(xpubB,xpubC,xpubD)/<14;15>/*),
+      pk(musig(xpubB,xpubC,xpubE)/<16;17>/*)
+    },
+    {
+      pk(musig(xpubB,xpubD,xpubE)/<18;19>/*),
+      {
+        pk(musig(xpubC,xpubD,xpubE)/<20;21>/*),
+        sortedmulti_a(3,
+          xpubA/<22;23>/*,
+          xpubB/<22;23>/*,
+          xpubC/<22;23>/*,
+          xpubD/<22;23>/*,
+          xpubE/<22;23>/*)
+      }
+    }
+  }
+})
+
+ +Notice how each root xpub appears 8 times. With xpubs being up to 118 bytes long, the length of the full descriptor can get extremely long (the problem rapidly gets worse with larger multisignature schemes). + +Replacing the common part of the key with a short key placeholder and moving the key expression separately helps to keep the size of the wallet policy small, which is crucial to allow human inspection during the registration flow. + +== Specification == + +This section formally defines wallet policies, and how they relate to output script descriptors. + +=== Formal definition === + +A ''wallet policy'' is composed by a ''wallet descriptor template'', together with a vector of ''key information items''. + +==== Wallet descriptor template ==== + +A ''wallet descriptor template'' is a SCRIPT expression. + +SCRIPT expressions: +* sh(SCRIPT) (top level only): P2SH embed the argument. +* wsh(SCRIPT) (top level or inside sh only): P2WSH embed the argument. +* pkh(KP) (not inside tr): P2PKH output for the given public key. +* wpkh(KP) (top level or inside sh only): P2WPKH output for the given compressed pubkey. +* multi(k,KP_1,KP_2,...,KP_n) (inside sh or wsh only): ''k''-of-''n'' multisig script. +* sortedmulti(k,KP_1,KP_2,...,KP_n) (inside sh or wsh only): ''k''-of-''n'' multisig script with keys sorted lexicographically in the resulting script. +* tr(KP) or tr(KP,TREE) (top level only): P2TR output with the specified key as internal key, and optionally a tree of script paths. +* any valid miniscript template (inside wsh or tr only). + +TREE expressions: +* any SCRIPT expression +* An open brace {, a TREE expression, a comma ,, a TREE expression, and a closing brace } + + +KP expressions (key placeholders) consist of +* a single character @ +* followed by a non-negative decimal number, with no leading zeros (except for @0) +* ''always'' followed by either: +** the string /**, or +** a string of the form //*, for two distinct decimal numbers NUM representing unhardened derivations, or +** any of the additional, implementation-specific valid derivation path patterns (see [[#Optional_derivation_paths|Optional derivation paths]] below). + +The /** in the placeholder template represents commonly used paths for receive/change addresses, and is equivalent to <0;1>/*. + +Note that while [[bip-0389.mediawiki|BIP-389]] allows multipath `/` expressions with an arbitrary number of options, this specification restricts it to exactly 2 choices (with the typical meaning of receive/change addresses). + +The placeholder @i for some number ''i'' represents the ''i''-th key in the vector of key information items (which must be of size at least ''i + 1'', or the wallet policy is invalid). + +Note: while descriptor templates for miniscript are not formally defined in this version of the document (pending standardization) it is straightforward to adapt this approach by adding additional SCRIPT expressions. + +==== Keys information vector ==== + +Each element of the key origin information vector is a KEY expression. + +* Optionally, key origin information, consisting of: +** An open bracket [ +** Exactly 8 hex characters for the fingerprint of the master key from which this key is derived from (see [[bip-0032.mediawiki|BIP-32]] for details) +** Followed by zero or more /NUM' or /NUM path elements to indicate hardened or unhardened derivation steps between the fingerprint and the xpub that follows +** A closing bracket ] +* Followed by the actual key, which is a serialized extended public key (as defined in [[bip-0032.mediawiki|BIP-32]]). + +==== Additional rules ==== + +A wallet policy must have at least one key placeholder and the corresponding key. + +The public keys obtained by deserializing elements of the keys information vector must be pairwise distinct'''Why must public keys be distinct?''' Reusing pubkeys could be insecure in the conext of wallet policies containing [https://bitcoin.sipa.be/miniscript/ miniscript]. Avoiding repeated public keys altogether avoids the problem at the source.. + +If two key placeholders are @i//* and @i//* for the same index i, then the sets {M, N} and {P, Q} must be disjoint. + +The key information vector should be ordered so that placeholder @i never appear for the first time before an occurrence of @j for some j < i; for example, the first placeholder is always @0, the next one is @1, etc. + +=== Descriptor derivation === + +From a wallet descriptor template (and the associated vector of key information items), one can therefore obtain the corresponding multipath descriptor by: + +* replacing each key placeholder with the corresponding key origin +information; +* replacing every /** with /<0;1>/*. + +For example, the wallet descriptor pkh(@0/**) with key information +["[d34db33f/44'/0'/0']xpub6ERApfZwUNrhLCkDtcHTcxd75RbzS1ed54G1LkBUHQVHQKqhMkhgbmJbZRkrgZw4koxb5JaHWkY4ALHY2grBGRjaDMzQLcgJvLJuZZvRcEL"] +produces the following multipath descriptor: + +pkh([d34db33f/44'/0'/0']xpub6ERApfZwUNrhLCkDtcHTcxd75RbzS1ed54G1LkBUHQVHQKqhMkhgbmJbZRkrgZw4koxb5JaHWkY4ALHY2grBGRjaDMzQLcgJvLJuZZvRcEL/<0;1>/*) + +=== Implementation guidelines === + +Implementations must not necessarily implement all the possible wallet policies defined by this standard, but it is recommended to clearly document any limitation. + +Implementations can add additional metadata that is stored together with the wallet policy for the purpose of wallet policy registration and later usage. Metadata can be vendor-specific and is out of the scope of this document. + +Any implementation in a software wallet that allows wallet policies not matching any of the specifications in [[bip-0044.mediawiki|BIP-44]], [[bip-0049.mediawiki|BIP-49]], [[bip-0084.mediawiki|BIP-84]], [[bip-0086.mediawiki|BIP-86]] (especially if involving external cosigners) should put great care into a process for backing up the wallet policy that represents the account. In fact, unlike standard single-signature scenarios, the seed alone is no longer enough to discover wallet policies with existing funds, and the loss of the backup is likely to lead to permanent loss of funds. Unlike the seed, leaking such backups only affects the privacy of the user, but it does not allow the attacker to steal funds. + +Avoiding key reuse among different wallet accounts is also extremely important, but out of scope for this document. + +=== Optional derivation paths === + +In order to allow supporting legacy derivation schemes (for example, using simply /* instead of the more common //* scheme most software wallets use today), or other schemes that are not covered in this document, implementations might choose to permit additional derivation patterns for the key placeholder (KP) expressions. + +However, care needs to be taken in view of the following considerations: + +* Allowing derivation schemes with a different length or cardinality in the same wallet policy would make it difficult to guarantee that there are no repeated pubkeys for every possible address generated by the policy. For example, `@0/<0;1>/*` and `@1/*` would generate the same pubkeys if the second public key in the keys information vector is one of the first two unhardened children of the first public key. This could cause malleability with potential security implications (for example, in policies containing miniscript). +* Allowing naked pubkeys with no /* suffix (for example a descriptor template like wsh(multi(2,@0,@1/<0;1>/*))) would cause a pubkey to be repeated in every output generated from the policy, which would result in a total loss of privacy. + +== Examples == + +In the examples in this section, the vector of key information items is omitted. See the test vectors below for complete examples. + +Common single-signature account patterns: +* pkh(@0/**) (legacy). +* wpkh(@0/**) (native segwit). +* sh(wpkh(@0/**)) (nested segwit). +* tr(@0/**) (taproot single-signature account). + +Common multisignature schemes: +* wsh(multi(2,@0/**,@1/**)) - SegWit 2-of-2 multisignature, keys in order. +* sh(sortedmulti(2,@0/**,@1/**,@2/**)) - Legacy 2-of-3 multisignature, sorted keys. + +Some miniscript policies in wsh: +* wsh(and_v(v:pk(@0/**),or_d(pk(@1/**),older(12960)))) - Trust-minimized second factor, degrading to a single signature after about 90 days. +* wsh(thresh(3,pk(@0/**),s:pk(@1/**),s:pk(@2/**),sln:older(12960))) - A 3-of-3 wallet that becomes a 2-of-3 if coins are not spent for about 90 days. +* wsh(or_d(pk(@0/**),and_v(v:multi(2,@1/**,@2/**,@3/**),older(65535)))) - A singlesig wallet with automatic inheritance to a timelocked 2-of-3 multisig of family members. + +== Test Vectors == + +=== Valid policies === + +[[bip-0044.mediawiki|BIP-44]], first account + Descriptor template: pkh(@0/**) + Keys info: ["[6738736c/44'/0'/0']xpub6Br37sWxruYfT8ASpCjVHKGwgdnYFEn98DwiN76i2oyY6fgH1LAPmmDcF46xjxJr22gw4jmVjTE2E3URMnRPEPYyo1zoPSUba563ESMXCeb"] + Descriptor:pkh([6738736c/44'/0'/0']xpub6Br37sWxruYfT8ASpCjVHKGwgdnYFEn98DwiN76i2oyY6fgH1LAPmmDcF46xjxJr22gw4jmVjTE2E3URMnRPEPYyo1zoPSUba563ESMXCeb) +
+[[bip-0049.mediawiki|BIP-49]], second account + Descriptor template: sh(wpkh(@0/**)) + Keys info: ["[6738736c/49'/0'/1']xpub6Bex1CHWGXNNwGVKHLqNC7kcV348FxkCxpZXyCWp1k27kin8sRPayjZUKDjyQeZzGUdyeAj2emoW5zStFFUAHRgd5w8iVVbLgZ7PmjAKAm9"] + Descriptor:sh(wpkh([6738736c/49'/0'/1']xpub6Bex1CHWGXNNwGVKHLqNC7kcV348FxkCxpZXyCWp1k27kin8sRPayjZUKDjyQeZzGUdyeAj2emoW5zStFFUAHRgd5w8iVVbLgZ7PmjAKAm9)) +
+[[bip-0084.mediawiki|BIP-84]], third account + Descriptor template: wpkh(@0/**) + Keys info: ["[6738736c/84'/0'/2']xpub6CRQzb8u9dmMcq5XAwwRn9gcoYCjndJkhKgD11WKzbVGd932UmrExWFxCAvRnDN3ez6ZujLmMvmLBaSWdfWVn75L83Qxu1qSX4fJNrJg2Gt"] + Descriptor:wpkh([6738736c/84'/0'/2']xpub6CRQzb8u9dmMcq5XAwwRn9gcoYCjndJkhKgD11WKzbVGd932UmrExWFxCAvRnDN3ez6ZujLmMvmLBaSWdfWVn75L83Qxu1qSX4fJNrJg2Gt) +
+[[bip-0086.mediawiki|BIP-86]], first account + Descriptor template: tr(@0/**) + Keys info: ["[6738736c/86'/0'/0']xpub6CryUDWPS28eR2cDyojB8G354izmx294BdjeSvH469Ty3o2E6Tq5VjBJCn8rWBgesvTJnyXNAJ3QpLFGuNwqFXNt3gn612raffLWfdHNkYL"] + Descriptor:tr([6738736c/86'/0'/0']xpub6CryUDWPS28eR2cDyojB8G354izmx294BdjeSvH469Ty3o2E6Tq5VjBJCn8rWBgesvTJnyXNAJ3QpLFGuNwqFXNt3gn612raffLWfdHNkYL) +
+[[bip-0048.mediawiki|BIP-48]] P2WSH multisig + Descriptor template: wsh(sortedmulti(2,@0/**,@1/**)) + Keys info: ["[6738736c/48'/0'/0'/2']xpub6FC1fXFP1GXLX5TKtcjHGT4q89SDRehkQLtbKJ2PzWcvbBHtyDsJPLtpLtkGqYNYZdVVAjRQ5kug9CsapegmmeRutpP7PW4u4wVF9JfkDhw", "[b2b1f0cf/48'/0'/0'/2']xpub6EWhjpPa6FqrcaPBuGBZRJVjzGJ1ZsMygRF26RwN932Vfkn1gyCiTbECVitBjRCkexEvetLdiqzTcYimmzYxyR1BZ79KNevgt61PDcukmC7"] + Descriptor:wsh(sortedmulti(2,[6738736c/48'/0'/0'/2']xpub6FC1fXFP1GXLX5TKtcjHGT4q89SDRehkQLtbKJ2PzWcvbBHtyDsJPLtpLtkGqYNYZdVVAjRQ5kug9CsapegmmeRutpP7PW4u4wVF9JfkDhw,[b2b1f0cf/48'/0'/0'/2']xpub6EWhjpPa6FqrcaPBuGBZRJVjzGJ1ZsMygRF26RwN932Vfkn1gyCiTbECVitBjRCkexEvetLdiqzTcYimmzYxyR1BZ79KNevgt61PDcukmC7)) +
+Miniscript: A 3-of-3 that becomes a 2-of-3 after 90 days + Descriptor template: wsh(thresh(3,pk(@0/**),s:pk(@1/**),s:pk(@2/**),sln:older(12960))) + Keys info: ["[6738736c/48'/0'/0'/100']xpub6FC1fXFP1GXQpyRFfSE1vzzySqs3Vg63bzimYLeqtNUYbzA87kMNTcuy9ubr7MmavGRjW2FRYHP4WGKjwutbf1ghgkUW9H7e3ceaPLRcVwa", "[b2b1f0cf/44'/0'/0'/100']xpub6EYajCJHe2CK53RLVXrN14uWoEttZgrRSaRztujsXg7yRhGtHmLBt9ot9Pd5ugfwWEu6eWyJYKSshyvZFKDXiNbBcoK42KRZbxwjRQpm5Js", "[a666a867/44'/0'/0'/100']xpub6Dgsze3ujLi1EiHoCtHFMS9VLS1UheVqxrHGfP7sBJ2DBfChEUHV4MDwmxAXR2ayeytpwm3zJEU3H3pjCR6q6U5sP2p2qzAD71x9z5QShK2"] + Descriptor:wsh(thresh(3,pk([6738736c/48'/0'/0'/100']xpub6FC1fXFP1GXQpyRFfSE1vzzySqs3Vg63bzimYLeqtNUYbzA87kMNTcuy9ubr7MmavGRjW2FRYHP4WGKjwutbf1ghgkUW9H7e3ceaPLRcVwa/<0,1>/*),s:pk([b2b1f0cf/44'/0'/0'/100']xpub6EYajCJHe2CK53RLVXrN14uWoEttZgrRSaRztujsXg7yRhGtHmLBt9ot9Pd5ugfwWEu6eWyJYKSshyvZFKDXiNbBcoK42KRZbxwjRQpm5Js/<0,1>/*),s:pk([a666a867/44'/0'/0'/100']xpub6Dgsze3ujLi1EiHoCtHFMS9VLS1UheVqxrHGfP7sBJ2DBfChEUHV4MDwmxAXR2ayeytpwm3zJEU3H3pjCR6q6U5sP2p2qzAD71x9z5QShK2/<0,1>/*),sln:older(12960))) +
+Miniscript: A singlesig wallet with automatic inheritance to a timelocked 2-of-3 multisig + Descriptor template: wsh(or_d(pk(@0/**),and_v(v:multi(2,@1/**,@2/**,@3/**),older(65535)))) + Keys info: ["[6738736c/48'/0'/0'/100']xpub6FC1fXFP1GXQpyRFfSE1vzzySqs3Vg63bzimYLeqtNUYbzA87kMNTcuy9ubr7MmavGRjW2FRYHP4WGKjwutbf1ghgkUW9H7e3ceaPLRcVwa", "[b2b1f0cf/44'/0'/0'/100']xpub6EYajCJHe2CK53RLVXrN14uWoEttZgrRSaRztujsXg7yRhGtHmLBt9ot9Pd5ugfwWEu6eWyJYKSshyvZFKDXiNbBcoK42KRZbxwjRQpm5Js", "[a666a867/44'/0'/0'/100']xpub6Dgsze3ujLi1EiHoCtHFMS9VLS1UheVqxrHGfP7sBJ2DBfChEUHV4MDwmxAXR2ayeytpwm3zJEU3H3pjCR6q6U5sP2p2qzAD71x9z5QShK2", "[bb641298/44'/0'/0'/100']xpub6Dz8PHFmXkYkykQ83ySkruky567XtJb9N69uXScJZqweYiQn6FyieajdiyjCvWzRZ2GoLHMRE1cwDfuJZ6461YvNRGVBJNnLA35cZrQKSRJ"] + Descriptor:wsh(or_d(pk([6738736c/48'/0'/0'/100']xpub6FC1fXFP1GXQpyRFfSE1vzzySqs3Vg63bzimYLeqtNUYbzA87kMNTcuy9ubr7MmavGRjW2FRYHP4WGKjwutbf1ghgkUW9H7e3ceaPLRcVwa),and_v(v:multi(2,[b2b1f0cf/44'/0'/0'/100']xpub6EYajCJHe2CK53RLVXrN14uWoEttZgrRSaRztujsXg7yRhGtHmLBt9ot9Pd5ugfwWEu6eWyJYKSshyvZFKDXiNbBcoK42KRZbxwjRQpm5Js,[a666a867/44'/0'/0'/100']xpub6Dgsze3ujLi1EiHoCtHFMS9VLS1UheVqxrHGfP7sBJ2DBfChEUHV4MDwmxAXR2ayeytpwm3zJEU3H3pjCR6q6U5sP2p2qzAD71x9z5QShK2,[bb641298/44'/0'/0'/100']xpub6Dz8PHFmXkYkykQ83ySkruky567XtJb9N69uXScJZqweYiQn6FyieajdiyjCvWzRZ2GoLHMRE1cwDfuJZ6461YvNRGVBJNnLA35cZrQKSRJ),older(65535)))) +
+ +TBD: add examples with taproot scripts and miniscript. + +=== Invalid policies === + +The following descriptor templates are invalid: + +* pkh(@0): Key placeholder with no path following it +* pkh(@0/0/**): Key placeholder with an explicit path present +* sh(multi(1,@1/**,@0/**)): Key placeholders out of order +* sh(multi(1,@0/**,@2/**)): Skipped key placeholder @1 +* sh(multi(1,@0/**,@0/**)): Repeated keys with the same path expression +* sh(multi(1,@0/<0;1>/*,@0/<1;2>/*)): Non-disjoint multipath expressions (@0/1/* appears twice) +* sh(multi(1,@0/**,xpub6AHA9hZDN11k2ijHMeS5QqHx2KP9aMBRhTDqANMnwVtdyw2TDYRmF8PjpvwUFcL1Et8Hj59S3gTSMcUQ5gAqTz3Wd8EsMTmF3DChhqPQBnU/<0;1>/*)): Expression with a non KP key present +* pkh(@0/<0;1;2>/*): Solved cardinality > 2 + +Remark: some of the descriptor templates above might be valid if optional extensions allowing them are added in the implementation. + +== Backwards Compatibility == + +The @ character used for key placeholders is not part of the syntax of output script descriptors, therefore any valid output descriptor with at least one `KEY` expression is not a valid descriptor template. Vice versa, any descriptor template with at least one key placeholder is not a valid output script descriptor. + +Adoption of wallet policies in software and harder wallets is opt-in. Conversion from wallet policies to the corresponding descriptors is programmatically extremely easy, and conversion from descriptors to wallet policies (when respecting the required patterns) can be automated. See the reference implementation below for some examples of conversion. + +Software wallets are recommended to allow exporting plain descriptors for the purposes of interoperability with software not using wallet policies. + +== Reference Implementation == + +Wallet policies are implemented in +* the [https://github.com/LedgerHQ/app-bitcoin-new Ledger bitcoin application] since version 2.1.0; +* the [https://github.com/digitalbitbox/bitbox02-firmware BitBox02 firmware] since version v9.15.0; +* [https://github.com/Blockstream/Jade Blockstream Jade] since version v1.0.24, via [https://github.com/ElementsProject/libwally-core libwally-core] v1.0.0. + +For development and testing purposes, we provide a [[bip-wallet-policies/wallet_policies.py|Python 3.7 reference implementation]] of simple classes to handle wallet policies, and the conversion to/from output script descriptors. +The reference implementation is for demonstration purposes only and not to be used in production environments. + +==Footnotes== + + + +== Acknowledgments == + +The authors would like to thank the people who provided feedback in the bitcoin-dev list, and in person. diff --git a/bip-wallet-policies/wallet_policies.py b/bip-wallet-policies/wallet_policies.py new file mode 100644 index 0000000000..42f615a2b8 --- /dev/null +++ b/bip-wallet-policies/wallet_policies.py @@ -0,0 +1,200 @@ +from typing import Iterable, List, Mapping, Tuple, Generator + + +def find_all(text: str, pattern: str, start: int = 0) -> Generator[int, None, None]: + """Generates all the positions of `pattern` as a substring of `text`, starting from index at least `start`.""" + while True: + start = text.find(pattern, start) + if start == -1: + return + yield start + start += len(pattern) + + +def find_first(text: str, start_pos: int, patterns: Iterable[str]) -> int: + """Returns the position of the first occurrence of any of the elements in `patterns` as a substring of `text`, + or -1 if none of the patterns is found.""" + matches = (text.find(x, start_pos) for x in patterns) + return min((x for x in matches if x != -1), default=-1) + + +def find_key_end_position(desc: str, start_pos: int) -> int: + """Assuming that `start_pos` is the beginning of a KEY expression (and not musig), finds the position of the end + of the key expression, excluding (if present) the final derivation steps after an xpub. This is the information + that goes into an entry of the vector of key information of the wallet policy.""" + + has_orig_info = True if desc[start_pos] == '[' else False + + if has_orig_info: + closing_bracket_pos = desc.find("]", start_pos) + if closing_bracket_pos == -1: + raise Exception("Invalid descriptor: could not find closing ']'") + key_pos_start = closing_bracket_pos + 1 + else: + key_pos_start = start_pos + + # find the earliest occurrence of ",", a ")" or a "/" (it must find at least 1) + end_pos = find_first(desc, key_pos_start, [",", ")", "/"]) + if end_pos == -1: + raise Exception( + "Invalid descriptor: cannot find the end of key expression") + + return end_pos + + +class WalletPolicy(object): + """Simple class to represent wallet policies. This is a toy implementation that does not parse the descriptor + template. A more robust implementation would build the abstract syntax tree of the template and of the descriptor, + allowing one to detect errors, and manipulate it semantically instead of relying on string manipulation.""" + + def __init__(self, descriptor_template: str, keys_info: List[str]): + self.descriptor_template = descriptor_template + self.keys_info = keys_info + + def to_descriptor(self) -> str: + """Converts a wallet policy into the descriptor (with the / syntax, if present).""" + + desc = self.descriptor_template + + # replace each "/**" with "/<0;1>/*" + desc = desc.replace("/**", "/<0;1>/*") + + # process all the @N expressions in decreasing order. This guarantees that string replacements + # works as expected (as any prefix expression is processed after). + for i in reversed(range(len(self.keys_info))): + desc = desc.replace(f"@{i}", self.keys_info[i]) + + # there should not be any remaining "@" expressions + if desc.find("@") != -1: + return Exception("Invalid descriptor template: contains invalid key index") + + return desc + + @classmethod + def from_descriptor(cls, descriptor: str) -> 'WalletPolicy': + """Converts a "reasonable" descriptor (with the / syntax) into the corresponding wallet policy.""" + + # list of pairs of integers, where the tuple (m,n) with m < n means a key expression starts at + # m (inclusive) and at n (exclusive) + key_expressions: List[Tuple[int, int]] = [] + + key_with_orig_pos_start = None + + def parse_key_expressions(only_first=False, handle_musig=False): + # Starting at the position in `key_with_orig_pos_start`, parses a number of key expressions, and updates + # the `key_expressions` array accordingly. + # If `only_first` is `True`, it stops after parsing a single key expression. + # If `handle_musig` is `True`, and a key expression is a `musig` operator, it recursively parses + # the keys in the musig expression. `musig` inside `musig` is not allowed. + + nonlocal key_with_orig_pos_start + if key_with_orig_pos_start is None: + raise Exception("Unexpected error") + + while True: + if handle_musig and descriptor[key_with_orig_pos_start:].startswith("musig"): + closing_parenthesis_pos = find_first( + descriptor, key_with_orig_pos_start, [")"]) + if closing_parenthesis_pos == -1: + raise Exception( + "Invalid descriptor: musig without closing parenthesis") + key_with_orig_pos_start = key_with_orig_pos_start + \ + len("musig(") + parse_key_expressions( + only_first=False, handle_musig=False) + + key_pos_end = closing_parenthesis_pos + 1 + else: + key_pos_end = find_key_end_position( + descriptor, key_with_orig_pos_start) + key_expressions.append( + (key_with_orig_pos_start, key_pos_end)) + + if descriptor[key_pos_end] == '/': + # find the actual end (comma or closing parenthesis) + key_pos_end = find_first( + descriptor, key_pos_end, [",", ")"]) + if key_pos_end == -1: + raise Exception( + "Invalid descriptor: unterminated key expression") + + if descriptor[key_pos_end] == ',': + # There is another key expression, repeat from after the comma + key_with_orig_pos_start = key_pos_end + 1 + else: + break + + if only_first: + break + + # operators for which the KEY is the first argument + operators_key_first = ["pk", "pkh", "pk_h", "pk_k", "tr"] + # operators for which the KEY is everything except the first argument + operators_key_all_but_first = [ + "multi", "sortedmulti", "multi_a", "sortedmulti_a"] + for op in operators_key_first + operators_key_all_but_first: + for op_pos_start in find_all(descriptor, op + "("): + + # ignore if not a whole word (otherwise "sortedmulti" would be found inside "multi") + if op_pos_start > 0 and 'a' <= desc[op_pos_start - 1] <= 'z': + continue + + if op in operators_key_all_but_first: + # skip the first argument (we now it's not a KEY expression, so it does not have a comma) + first_comma_pos = descriptor.find(",", op_pos_start) + if first_comma_pos == -1: + raise Exception( + "Invalid descriptor: multi, sortedmulti, multi_a and sortedmulti_a must have at least two arguments") + key_with_orig_pos_start = 1 + first_comma_pos + else: + # other operators, the first argument is already a KEY expression + key_with_orig_pos_start = op_pos_start + len(op) + 1 + + only_first = op in operators_key_first + parse_key_expressions( + only_first=only_first, handle_musig=True) + + result: List[str] = [] + keys: List[str] = [] + keys_to_idx: Mapping[str, int] = {} + + prev_end = 0 + for start, end in sorted(key_expressions): + result.append(descriptor[prev_end:start]) + + key = descriptor[start:end] + if key not in keys_to_idx: + idx = len(keys) + keys.append(key) + keys_to_idx[key] = idx + else: + idx = keys_to_idx[key] + result.append(f"@{idx}") + + prev_end = end + + result.append(descriptor[prev_end:]) + + return cls("".join(result), keys) + + +if __name__ == "__main__": + descriptors = [ + "pkh([d34db33f/44'/0'/0']xpub6ERApfZwUNrhLCkDtcHTcxd75RbzS1ed54G1LkBUHQVHQKqhMkhgbmJbZRkrgZw4koxb5JaHWkY4ALHY2grBGRjaDMzQLcgJvLJuZZvRcEL/**)", + "wsh(multi(1,xpub661MyMwAqRbcFW31YEwpkMuc5THy2PSt5bDMsktWQcFF8syAmRUapSCGu8ED9W6oDMSgv6Zz8idoc4a6mr8BDzTJY47LJhkJ8UB7WEGuduB/**,xpub69H7F5d8KSRgmmdJg2KhpAK8SR3DjMwAdkxj3ZuxV27CprR9LgpeyGmXUbC6wb7ERfvrnKZjXoUmmDznezpbZb7ap6r1D3tgFxHmwMkQTPH/**))", + "tr([12345678/44'/0'/0']xpub6BVZ6JrGsWsUbpP74S8rnz13hVFDtYtKyuTTEYPNSF6GFpDFpL1YXWg3BpwpUWAnsZZ7Qe3XKz7GL3BEx3RQVq61cxqSkjceq25S1xFKFVa,{pk(xpub6AGdromjXf5yf3m7ndaCoR9Ac3UjwTvQ7QQkZoyoh2vfGE9i1AwB2vCbvjTpBL1KRERUsGszg63SVNXsHZU3CiykQqtZPrdXKMdaG2vs6uu),pk(xpub6AnhdkteWC4kPQvkY3QQXGmDCMfmFoYzEQ7FwRFa4BQ1a22k4VL4BD3Jdcog2Sf2KzBscXXAdPRMgjCBDeq6bAryqnMaWX2FaVUGPxWMLDh)})", + "tr(xpub6AEWqA1MNRzBBXenkug4NtNguDKTNcXoKQj8fU9VQyid38yikruFRffjoDm9UEaHGEJ6jQxjYdWWZRxR7Xy5ePrQNjohXJuNzkRNSiiBUcE,sortedmulti_a(2,[11223344/44'/0'/0']xpub6AyJhEKxcPaPnYNuA7VBeUQ24v6mEzzPSX5AJm3TSyg1Zsti7rnGKy1Hg6JAdXKF4QUmFZbby9p97AjBNm2VFCEec2ip5C9JntyxosmCeMW,xpub6AQVHBgieCHpGo4GhpGAo4v9v7hfr2Kr4D8ZQJqJwbEyZwtW3pWYSLRQyrNYbTzpoq6XpFtaKZGnEGUMtiydCgqsJDAZNqs9L5QDNKqUBsV))", + "tr([11111111/44'/0'/0']xpub6CLZSUDtcUhJVDoPSY8pSRKi4W1RSSLBgwZ2AYmwTH9Yv5tPVFHZxJBUQ27QLLwHej6kfo9DQQbwaHmpXsQq59CjtsE2gNLHmojwgMrsQNe/**,{and_v(v:pk([22222222/44'/0'/0']xpub6CiztfGsUxmpwkWe6gvz8d5VHyFLDoiPpeUfWmQ2vWAhQL3Z1hhEc6PE4irFs4bzjS7dCB4yyinaubrCpFJq4bcKGCD4jjqTxaWiKAJ7mvJ/**),older(52596)),multi_a(2,[33333333/44'/0'/0']xpub6DTZd6od7is2wxXndmE7zaUifzFPwVKshVSGEZedfTJtUjfLyhy4hgCW15hvxRpGaDmtiFoJKaCEaSRfXrQBuYRx18zwquy46dwBsJnsrz2/**,[44444444/44'/0'/0']xpub6BnK4wFbPeLZM4VNjoUA4yLCru6kCT3bhDJNBhbzHLGp1fmgK6muz27h4drixJZeHG8vSS5U5EYyE3gE8ozG94iNg3NDYE8M5YafvhzhMR9/**)})", + "tr(musig([33333333/44'/0'/0']xpub6DTZd6od7is2wxXndmE7zaUifzFPwVKshVSGEZedfTJtUjfLyhy4hgCW15hvxRpGaDmtiFoJKaCEaSRfXrQBuYRx18zwquy46dwBsJnsrz2,[44444444/44'/0'/0']xpub6BnK4wFbPeLZM4VNjoUA4yLCru6kCT3bhDJNBhbzHLGp1fmgK6muz27h4drixJZeHG8vSS5U5EYyE3gE8ozG94iNg3NDYE8M5YafvhzhMR9)/**,{and_v(v:pk([22222222/44'/0'/0']xpub6CiztfGsUxmpwkWe6gvz8d5VHyFLDoiPpeUfWmQ2vWAhQL3Z1hhEc6PE4irFs4bzjS7dCB4yyinaubrCpFJq4bcKGCD4jjqTxaWiKAJ7mvJ/**),older(52596)),pk([11111111/44'/0'/0']xpub6CLZSUDtcUhJVDoPSY8pSRKi4W1RSSLBgwZ2AYmwTH9Yv5tPVFHZxJBUQ27QLLwHej6kfo9DQQbwaHmpXsQq59CjtsE2gNLHmojwgMrsQNe/**)})", + ] + + for desc in descriptors: + # Demoes the conversion from a "sane" descriptor to a wallet policy + print(f"Descriptor:\n{desc}") + wp = WalletPolicy.from_descriptor(desc) + print(f"Policy descriptor template:\n{wp.descriptor_template}") + print(f"Keys:\n{wp.keys_info}") + print("======================================================\n") + + # Converting back to descriptors also works, as long as we take care of /** + assert wp.to_descriptor().replace("/<0;1>/*", "/**") == desc From 25657cbee641fa63936a0313700c009466cd56d6 Mon Sep 17 00:00:00 2001 From: Salvatore Ingala <6681844+bigspider@users.noreply.github.com> Date: Mon, 8 Jan 2024 11:41:17 +0100 Subject: [PATCH 235/454] Update assigned BIP number; change type to "Standards Track" --- bip-wallet-policies.mediawiki => bip-0388.mediawiki | 6 +++--- {bip-wallet-policies => bip-0388}/wallet_policies.py | 0 2 files changed, 3 insertions(+), 3 deletions(-) rename bip-wallet-policies.mediawiki => bip-0388.mediawiki (99%) rename {bip-wallet-policies => bip-0388}/wallet_policies.py (100%) diff --git a/bip-wallet-policies.mediawiki b/bip-0388.mediawiki similarity index 99% rename from bip-wallet-policies.mediawiki rename to bip-0388.mediawiki index e46df1c646..a7114dd2a2 100644 --- a/bip-wallet-policies.mediawiki +++ b/bip-0388.mediawiki @@ -1,12 +1,12 @@
-  BIP: wallet-policies
+  BIP: 388
   Layer: Applications
   Title: Wallet Policies for Descriptor Wallets
   Author: Salvatore Ingala 
   Comments-Summary: No comments yet.
-  Comments-URI: https://github.com/bitcoin/bips/wiki/Comments:BIP-wallet-policies
+  Comments-URI: https://github.com/bitcoin/bips/wiki/Comments:BIP-0388
   Status: Draft
-  Type: Informational
+  Type: Standards Track
   Created: 2022-11-16
   License: BSD-2-Clause
 
diff --git a/bip-wallet-policies/wallet_policies.py b/bip-0388/wallet_policies.py similarity index 100% rename from bip-wallet-policies/wallet_policies.py rename to bip-0388/wallet_policies.py From 40c7760d781e760fe01bb6fe86a7731f506daa07 Mon Sep 17 00:00:00 2001 From: Salvatore Ingala <6681844+bigspider@users.noreply.github.com> Date: Sun, 5 May 2024 11:38:49 -0500 Subject: [PATCH 236/454] Apply suggestions from code review Co-authored-by: Mark "Murch" Erhardt --- bip-0388.mediawiki | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/bip-0388.mediawiki b/bip-0388.mediawiki index a7114dd2a2..f34d2e84d4 100644 --- a/bip-0388.mediawiki +++ b/bip-0388.mediawiki @@ -9,6 +9,7 @@ Type: Standards Track Created: 2022-11-16 License: BSD-2-Clause + Post-History: 2022-05-10: https://lists.linuxfoundation.org/pipermail/bitcoin-dev/2022-May/020423.html
== Abstract == @@ -64,7 +65,7 @@ Therefore, there are two fundamental design goals to strive for: * Minimize the amount of information that is shown on screen - so that the user can actually validate it. * Minimize the number of times the user has to validate such information. -Designing a secure protocol for the coordination of a descriptor wallet among distant parties is also a challenging problem that is out of scope in this document. See [[bip-00129.mediawiki|BIP-129 (Bitcoin Secure Multisig Setup)]] for an approach designed for multisignature wallets. Regardless the approach, the ability for the user to carefully verify all the details of the spending policies using the hardware signer's screen is a prerequisite for security in adversarial environments. +Designing a secure protocol for the coordination of a descriptor wallet among distant parties is also a challenging problem that is out of scope in this document. See [[bip-00129.mediawiki|BIP-129 (Bitcoin Secure Multisig Setup)]] for an approach designed for multisignature wallets. Regardless of the approach, the ability for the user to carefully verify all the details of the spending policies using the hardware signer's screen is a prerequisite for security in adversarial environments. === Policy registration as a solution === @@ -320,7 +321,7 @@ Remark: some of the descriptor templates above might be valid if optional extens The @ character used for key placeholders is not part of the syntax of output script descriptors, therefore any valid output descriptor with at least one `KEY` expression is not a valid descriptor template. Vice versa, any descriptor template with at least one key placeholder is not a valid output script descriptor. -Adoption of wallet policies in software and harder wallets is opt-in. Conversion from wallet policies to the corresponding descriptors is programmatically extremely easy, and conversion from descriptors to wallet policies (when respecting the required patterns) can be automated. See the reference implementation below for some examples of conversion. +Adoption of wallet policies in software and hardware wallets is opt-in. Conversion from wallet policies to the corresponding descriptors is programmatically extremely easy, and conversion from descriptors to wallet policies (when respecting the required patterns) can be automated. See the reference implementation below for some examples of conversion. Software wallets are recommended to allow exporting plain descriptors for the purposes of interoperability with software not using wallet policies. From 95cf53916113a44487e0381029d3602e5bb1db6a Mon Sep 17 00:00:00 2001 From: Salvatore Ingala <6681844+bigspider@users.noreply.github.com> Date: Tue, 7 May 2024 10:51:46 +0200 Subject: [PATCH 237/454] Improvements from PR review. - Removed large example of taproot policy; replaced with the textual description - Added an example of a taproot wallet policy containing miniscript --- bip-0388.mediawiki | 56 ++++++++-------------------------------------- 1 file changed, 9 insertions(+), 47 deletions(-) diff --git a/bip-0388.mediawiki b/bip-0388.mediawiki index f34d2e84d4..a62b262cf1 100644 --- a/bip-0388.mediawiki +++ b/bip-0388.mediawiki @@ -93,54 +93,13 @@ Once the previously registered policy is correctly identified and approved by th While reusing a pubkey in different branches of a miniscript is explicitly forbidden by miniscript (as it has certain negative security implications), it is still reasonable to reuse the same xpub in multiple places, albeit with different final steps of derivation (so that the actual pubkeys that are used in the script are indeed different). -For example, using Taproot, a 3-of-5 multisignature wallet could use: +In fact, there are many reasonable spending policies with a quadratic size in the number of participants. For example, using Taproot, a 3-of-5 multisignature wallet could use: * a key path with a 5-of-5 MuSig2 aggregated key * a script tree with 11 leaves: -** 10 different script using a 3-of-3 MuSig2 aggregated key, plus -** a final leaf with a fallback 3-of-5 multisignature using OP_CHECKSIGADD (in case interactive signing is not available). +** 10 different scripts using a 3-of-3 MuSig2 aggregated key, plus +** a final leaf with a fallback 3-of-5 multisignature using multi_a (in case interactive signing is not available). -This could look similar to: - -
-tr(musig(xpubA,xpubB,xpubC,xpubD,xpubE)/<0;1>/*), {
-  {
-    {
-      pk(musig(xpubA,xpubB,xpubC)/<2;3>/*),
-      {
-        pk(musig(xpubA,xpubB,xpubD)/<4;5>/*)
-        pk(musig(xpubA,xpubB,xpubE)/<6;7>/*),
-      }
-    },
-    {
-      pk(musig(xpubA,xpubC,xpubD)/<8;9>/*),
-      {
-        pk(musig(xpubA,xpubC,xpubE)/<10;11>/*),
-        pk(musig(xpubA,xpubD,xpubE)/<12;13>/*)
-      }
-    }
-  },
-  {
-    {
-      pk(musig(xpubB,xpubC,xpubD)/<14;15>/*),
-      pk(musig(xpubB,xpubC,xpubE)/<16;17>/*)
-    },
-    {
-      pk(musig(xpubB,xpubD,xpubE)/<18;19>/*),
-      {
-        pk(musig(xpubC,xpubD,xpubE)/<20;21>/*),
-        sortedmulti_a(3,
-          xpubA/<22;23>/*,
-          xpubB/<22;23>/*,
-          xpubC/<22;23>/*,
-          xpubD/<22;23>/*,
-          xpubE/<22;23>/*)
-      }
-    }
-  }
-})
-
- -Notice how each root xpub appears 8 times. With xpubs being up to 118 bytes long, the length of the full descriptor can get extremely long (the problem rapidly gets worse with larger multisignature schemes). +With each xpub being 118 bytes long, the repetition of xpubs makes the descriptor become extremely large. Replacing the common part of the key with a short key placeholder and moving the key expression separately helps to keep the size of the wallet policy small, which is crucial to allow human inspection during the registration flow. @@ -299,8 +258,11 @@ Miniscript: A singlesig wallet with automatic inheritance to a timelocked 2-of-3 Keys info: ["[6738736c/48'/0'/0'/100']xpub6FC1fXFP1GXQpyRFfSE1vzzySqs3Vg63bzimYLeqtNUYbzA87kMNTcuy9ubr7MmavGRjW2FRYHP4WGKjwutbf1ghgkUW9H7e3ceaPLRcVwa", "[b2b1f0cf/44'/0'/0'/100']xpub6EYajCJHe2CK53RLVXrN14uWoEttZgrRSaRztujsXg7yRhGtHmLBt9ot9Pd5ugfwWEu6eWyJYKSshyvZFKDXiNbBcoK42KRZbxwjRQpm5Js", "[a666a867/44'/0'/0'/100']xpub6Dgsze3ujLi1EiHoCtHFMS9VLS1UheVqxrHGfP7sBJ2DBfChEUHV4MDwmxAXR2ayeytpwm3zJEU3H3pjCR6q6U5sP2p2qzAD71x9z5QShK2", "[bb641298/44'/0'/0'/100']xpub6Dz8PHFmXkYkykQ83ySkruky567XtJb9N69uXScJZqweYiQn6FyieajdiyjCvWzRZ2GoLHMRE1cwDfuJZ6461YvNRGVBJNnLA35cZrQKSRJ"] Descriptor:wsh(or_d(pk([6738736c/48'/0'/0'/100']xpub6FC1fXFP1GXQpyRFfSE1vzzySqs3Vg63bzimYLeqtNUYbzA87kMNTcuy9ubr7MmavGRjW2FRYHP4WGKjwutbf1ghgkUW9H7e3ceaPLRcVwa),and_v(v:multi(2,[b2b1f0cf/44'/0'/0'/100']xpub6EYajCJHe2CK53RLVXrN14uWoEttZgrRSaRztujsXg7yRhGtHmLBt9ot9Pd5ugfwWEu6eWyJYKSshyvZFKDXiNbBcoK42KRZbxwjRQpm5Js,[a666a867/44'/0'/0'/100']xpub6Dgsze3ujLi1EiHoCtHFMS9VLS1UheVqxrHGfP7sBJ2DBfChEUHV4MDwmxAXR2ayeytpwm3zJEU3H3pjCR6q6U5sP2p2qzAD71x9z5QShK2,[bb641298/44'/0'/0'/100']xpub6Dz8PHFmXkYkykQ83ySkruky567XtJb9N69uXScJZqweYiQn6FyieajdiyjCvWzRZ2GoLHMRE1cwDfuJZ6461YvNRGVBJNnLA35cZrQKSRJ),older(65535))))
- -TBD: add examples with taproot scripts and miniscript. +Taproot wallet policy with sortedmulti_a and a miniscript leaf + Descriptor template: tr(@0/**,{sortedmulti_a(1,@0/<2;3>/*,@1/**),or_b(pk(@2/**),s:pk(@3/**))}) + Keys info: ["[6738736c/48'/0'/0'/100']xpub6FC1fXFP1GXQpyRFfSE1vzzySqs3Vg63bzimYLeqtNUYbzA87kMNTcuy9ubr7MmavGRjW2FRYHP4WGKjwutbf1ghgkUW9H7e3ceaPLRcVwa", "xpub6Fc2TRaCWNgfT49nRGG2G78d1dPnjhW66gEXi7oYZML7qEFN8e21b2DLDipTZZnfV6V7ivrMkvh4VbnHY2ChHTS9qM3XVLJiAgcfagYQk6K", "xpub6GxHB9kRdFfTqYka8tgtX9Gh3Td3A9XS8uakUGVcJ9NGZ1uLrGZrRVr67DjpMNCHprZmVmceFTY4X4wWfksy8nVwPiNvzJ5pjLxzPtpnfEM", "xpub6GjFUVVYewLj5no5uoNKCWuyWhQ1rKGvV8DgXBG9Uc6DvAKxt2dhrj1EZFrTNB5qxAoBkVW3wF8uCS3q1ri9fueAa6y7heFTcf27Q4gyeh6"] + Descriptor:tr([6738736c/48'/0'/0'/100']xpub6FC1fXFP1GXQpyRFfSE1vzzySqs3Vg63bzimYLeqtNUYbzA87kMNTcuy9ubr7MmavGRjW2FRYHP4WGKjwutbf1ghgkUW9H7e3ceaPLRcVwa/<0;1>/*,{sortedmulti_a(1,xpub6FC1fXFP1GXQpyRFfSE1vzzySqs3Vg63bzimYLeqtNUYbzA87kMNTcuy9ubr7MmavGRjW2FRYHP4WGKjwutbf1ghgkUW9H7e3ceaPLRcVwa/<2;3>/*,xpub6Fc2TRaCWNgfT49nRGG2G78d1dPnjhW66gEXi7oYZML7qEFN8e21b2DLDipTZZnfV6V7ivrMkvh4VbnHY2ChHTS9qM3XVLJiAgcfagYQk6K/<0;1>/*),or_b(pk(xpub6GxHB9kRdFfTqYka8tgtX9Gh3Td3A9XS8uakUGVcJ9NGZ1uLrGZrRVr67DjpMNCHprZmVmceFTY4X4wWfksy8nVwPiNvzJ5pjLxzPtpnfEM/<0;1>/*),s:pk(xpub6GjFUVVYewLj5no5uoNKCWuyWhQ1rKGvV8DgXBG9Uc6DvAKxt2dhrj1EZFrTNB5qxAoBkVW3wF8uCS3q1ri9fueAa6y7heFTcf27Q4gyeh6/<0;1>/*))}) +
=== Invalid policies === From a0c8501f960ac29878e137c03dcd6d8a3b9096b5 Mon Sep 17 00:00:00 2001 From: Salvatore Ingala <6681844+bigspider@users.noreply.github.com> Date: Tue, 7 May 2024 10:55:55 +0200 Subject: [PATCH 238/454] Added BIP-388 to README --- README.mediawiki | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/README.mediawiki b/README.mediawiki index be18dcf859..0ce7b8e81f 100644 --- a/README.mediawiki +++ b/README.mediawiki @@ -1184,6 +1184,13 @@ Those proposing changes should consider that ultimately consent may rest with th | Informational | Draft |- +| [[bip-0388.mediawiki|388]] +| Applications +| Wallet Policies for Descriptor Wallets +| Salvatore Ingala +| Standard +| Draft +|- | [[bip-0389.mediawiki|389]] | Applications | Multipath Descriptor Key Expressions From 4ddb0cc8933fe677103b8c1b2407922c76b98f71 Mon Sep 17 00:00:00 2001 From: katesalazar <52637275+katesalazar@users.noreply.github.com> Date: Sat, 4 May 2024 15:17:28 +0000 Subject: [PATCH 239/454] Update bip-0038.mediawiki Add missing closing double single quote. The italicized paragraph gets cautiously closed. --- bip-0038.mediawiki | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/bip-0038.mediawiki b/bip-0038.mediawiki index f5013db314..8a79bf66c9 100644 --- a/bip-0038.mediawiki +++ b/bip-0038.mediawiki @@ -39,7 +39,7 @@ This proposal is hereby placed in the public domain. :'''''User story:''' As a Bitcoin user who uses paper wallets, I would like the ability to add encryption, so that my Bitcoin paper storage can be two factor: something I have plus something I know.'' :'''''User story:''' As a Bitcoin user who would like to pay a person or a company with a private key, I do not want to worry that any part of the communication path may result in the interception of the key and theft of my funds. I would prefer to offer an encrypted private key, and then follow it up with the password using a different communication channel (e.g. a phone call or SMS).'' :'''''User story:''' (EC-multiplied keys) As a user of physical bitcoins, I would like a third party to be able to create password-protected Bitcoin private keys for me, without them knowing the password, so I can benefit from the physical bitcoin without the issuer having access to the private key. I would like to be able to choose a password whose minimum length and required format does not preclude me from memorizing it or engraving it on my physical bitcoin, without exposing me to an undue risk of password cracking and/or theft by the manufacturer of the item.'' -:'''''User story:''' (EC-multiplied keys) As a user of paper wallets, I would like the ability to generate a large number of Bitcoin addresses protected by the same password, while enjoying a high degree of security (highly expensive scrypt parameters), but without having to incur the scrypt delay for each address I generate. +:'''''User story:''' (EC-multiplied keys) As a user of paper wallets, I would like the ability to generate a large number of Bitcoin addresses protected by the same password, while enjoying a high degree of security (highly expensive scrypt parameters), but without having to incur the scrypt delay for each address I generate.'' ==Specification== This proposal makes use of the following functions and definitions: From c88a018409e6ce8ae07a2ef9b950cd8e9afcbb70 Mon Sep 17 00:00:00 2001 From: katesalazar <52637275+katesalazar@users.noreply.github.com> Date: Sat, 4 May 2024 15:21:20 +0000 Subject: [PATCH 240/454] Update bip-0038.mediawiki Separating the bold and the italic markup helps inconsistent parsing (see screenshots in PR #1586). --- bip-0038.mediawiki | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/bip-0038.mediawiki b/bip-0038.mediawiki index 8a79bf66c9..ffae832e54 100644 --- a/bip-0038.mediawiki +++ b/bip-0038.mediawiki @@ -36,10 +36,10 @@ Password and passphrase-protected private keys enable new practical use cases fo This proposal is hereby placed in the public domain. ==Rationale== -:'''''User story:''' As a Bitcoin user who uses paper wallets, I would like the ability to add encryption, so that my Bitcoin paper storage can be two factor: something I have plus something I know.'' -:'''''User story:''' As a Bitcoin user who would like to pay a person or a company with a private key, I do not want to worry that any part of the communication path may result in the interception of the key and theft of my funds. I would prefer to offer an encrypted private key, and then follow it up with the password using a different communication channel (e.g. a phone call or SMS).'' -:'''''User story:''' (EC-multiplied keys) As a user of physical bitcoins, I would like a third party to be able to create password-protected Bitcoin private keys for me, without them knowing the password, so I can benefit from the physical bitcoin without the issuer having access to the private key. I would like to be able to choose a password whose minimum length and required format does not preclude me from memorizing it or engraving it on my physical bitcoin, without exposing me to an undue risk of password cracking and/or theft by the manufacturer of the item.'' -:'''''User story:''' (EC-multiplied keys) As a user of paper wallets, I would like the ability to generate a large number of Bitcoin addresses protected by the same password, while enjoying a high degree of security (highly expensive scrypt parameters), but without having to incur the scrypt delay for each address I generate.'' +:'' '''User story:''' As a Bitcoin user who uses paper wallets, I would like the ability to add encryption, so that my Bitcoin paper storage can be two factor: something I have plus something I know.'' +:'' '''User story:''' As a Bitcoin user who would like to pay a person or a company with a private key, I do not want to worry that any part of the communication path may result in the interception of the key and theft of my funds. I would prefer to offer an encrypted private key, and then follow it up with the password using a different communication channel (e.g. a phone call or SMS).'' +:'' '''User story:''' (EC-multiplied keys) As a user of physical bitcoins, I would like a third party to be able to create password-protected Bitcoin private keys for me, without them knowing the password, so I can benefit from the physical bitcoin without the issuer having access to the private key. I would like to be able to choose a password whose minimum length and required format does not preclude me from memorizing it or engraving it on my physical bitcoin, without exposing me to an undue risk of password cracking and/or theft by the manufacturer of the item.'' +:'' '''User story:''' (EC-multiplied keys) As a user of paper wallets, I would like the ability to generate a large number of Bitcoin addresses protected by the same password, while enjoying a high degree of security (highly expensive scrypt parameters), but without having to incur the scrypt delay for each address I generate.'' ==Specification== This proposal makes use of the following functions and definitions: From cf2250e27cc682289facc27e1e2ff16e94d12aab Mon Sep 17 00:00:00 2001 From: Salvatore Ingala <6681844+bigspider@users.noreply.github.com> Date: Tue, 7 May 2024 22:10:44 +0200 Subject: [PATCH 241/454] Apply suggestions from code review Co-authored-by: Mark "Murch" Erhardt --- bip-0388.mediawiki | 36 ++++++++++++++++++------------------ 1 file changed, 18 insertions(+), 18 deletions(-) diff --git a/bip-0388.mediawiki b/bip-0388.mediawiki index a62b262cf1..d7ed0bec49 100644 --- a/bip-0388.mediawiki +++ b/bip-0388.mediawiki @@ -14,13 +14,13 @@ == Abstract == -Wallet policies build on top of output descriptors to represent in a compact, easier to inspect way the types of descriptors that are typically used to represent "accounts" in a software wallet, or a hardware signing device. A wallet policy always represents exactly two descriptors, which produce the receive and change addresses that are logically part of the same account. +Wallet policies build on top of output descriptors to represent the types of descriptors that are typically used to represent "accounts" in a software wallet, or a hardware signing device, in a compact, reviewable way. A wallet policy always represents exactly two descriptors, which produce the receive and change addresses that are logically part of the same account. -Reducing the generality of descriptors to just the essential features, and separating the extended pubkeys and other key information from the descriptor, allows to simplify the language in a way that suits devices with limited memory, where even keeping the entire descriptor in memory could be a major hurdle. +We simplify the language to suit devices with limited memory, where even keeping the entire descriptor in memory could be a major hurdle, by reducing the generality of descriptors to just the essential features and by separating the extended pubkeys and other key information from the descriptor. -Moreover, together with the gain in compactness, this simplifies user's inspection of the policy. +This results in a more compact representation and simplifies the inspection of the policy by the user. -Finally, by keeping the language extremely close to that of output script descriptors, the compilation of wallet policies to the corresponding descriptor is extremely easy, and even the reverse process is not too difficult for supported descriptors. +The compilation of wallet policies to the corresponding descriptor is trivial, and the reverse process is easy for supported descriptors, because the language is kept similar to that of output script descriptors. == Copyright == @@ -28,27 +28,27 @@ This BIP is licensed under the BSD 2-clause license. == Motivation == -''[[bip-0380.mediawiki|Output Script Descriptors]]'' were introduced in bitcoin-core as a way to represent collections of output scripts. It is a very general and flexible language, designed to catch all the possible use-cases of bitcoin wallets (that is, if you know the script and you have the necessary keys, it will be possible to sign transactions with any descriptor-based software wallet). +''[[bip-0380.mediawiki|Output Script Descriptors]]'' were introduced in Bitcoin Core as a way to represent collections of output scripts. It is a general and flexible language, designed to catch all the possible use-cases of bitcoin wallets (that is, if you know the script and you have the necessary keys, it will be possible to sign transactions with any descriptor-based software wallet). -Unfortunately, descriptors are not a perfect match for the typical usage of hardware signing devices (often also called ''hardware wallets''). Most of them have some of the following limitations when compared to a general-purpose machine running bitcoin-core: +Unfortunately, descriptors are not a perfect match for the typical usage of hardware signing devices (often also called ''hardware wallets''). Most of them have some of the following limitations when compared to a general-purpose machine running Bitcoin Core: * they are embedded devices with limited RAM, and computational power; * they cannot import additional private keys (that is, they can only sign with keys derived from a single seed via [[bip-0032.mediawiki|BIP-32]]); * they have limited storage, or they might not have persistent storage at all (''stateless design''). -Moreover, other limitations like the limited size of the screen might affect what design choices are available in practice. Therefore, minimizing the size of the information shown on-screen is important for a good user experience; that is crucial since the ability for the user to completely validate on-screen the kind of script used (and each of the involved keys) is a prerequisite for secure usage, as the machine that is interacting with the hardware signer (and running the software wallet) is considered untrusted. +Moreover, other limitations like the limited size of the screen might affect what design choices are available in practice. Therefore, minimizing the amount of information shown on-screen is important for a good user experience. The ability for the user to completely validate on-screen the kind of script used (and each of the involved keys) is crucial for secure usage, as the machine that is interacting with the hardware signer (and running the software wallet) is considered untrusted. -A more native, compact representation of the wallet receive/change might also benefit the UX of software wallets using descriptors to represent software wallets using descriptors (possibly with miniscript) for complex locking conditions. +A more native, compact representation of the wallet receive and change addresses might also benefit the UX of software wallets when they use descriptors (possibly with miniscript) for representing complex locking conditions. We remark that wallet policies are not related to the ''policy'' language, a higher level language that can be compiled to miniscript. === Security and UX concerns for hardware signing devices === -For a hardware signing device, allowing the usage of complex scripts presents challenges in terms of both security and user experience. +The usage of complex scripts presents challenges in terms of both security and user experience for a hardware signing device. ==== Security issues ==== -One of the security properties that hardware signing devices strive to guarantee is the following: as long as the user correctly verifies the information that is shown on the device's screen before approving, no action can be performed without the user's consent. +Hardware signing devices strive to guarantee that no action can be performed without the user’s consent as long as the user correctly verifies the information that is shown on the device’s screen before approving. This must hold even in scenarios where the attacker has full control of the machine that is connected to the signing device, and can execute arbitrary requests, or tamper with the legitimate user's requests. @@ -59,9 +59,9 @@ This makes it impossible for an attacker to surreptitiously modify the policy, t ==== UX issues ==== -With miniscript (and taproot trees) allowing substantially more complex spending policies to be used, it becomes more challenging to make sure that the user is practically able to verify the information on the screen. +Miniscript (and taproot trees) allow substantially more complex spending policies. It is a challenge to ensure that the user can practically verify such spending policies per the screen. -Therefore, there are two fundamental design goals to strive for: +We set two fundamental design goals: * Minimize the amount of information that is shown on screen - so that the user can actually validate it. * Minimize the number of times the user has to validate such information. @@ -144,7 +144,7 @@ Note that while [[bip-0389.mediawiki|BIP-389]] allows multipath `/@i for some number ''i'' represents the ''i''-th key in the vector of key information items (which must be of size at least ''i + 1'', or the wallet policy is invalid). -Note: while descriptor templates for miniscript are not formally defined in this version of the document (pending standardization) it is straightforward to adapt this approach by adding additional SCRIPT expressions. +Note: while descriptor templates for miniscript are not formally defined in this version of the document (pending standardization), it is straightforward to adapt this approach by adding additional SCRIPT expressions. ==== Keys information vector ==== @@ -161,11 +161,11 @@ Each element of the key origin information vector is a KEY expression. A wallet policy must have at least one key placeholder and the corresponding key. -The public keys obtained by deserializing elements of the keys information vector must be pairwise distinct'''Why must public keys be distinct?''' Reusing pubkeys could be insecure in the conext of wallet policies containing [https://bitcoin.sipa.be/miniscript/ miniscript]. Avoiding repeated public keys altogether avoids the problem at the source.. +The public keys obtained by deserializing elements of the keys information vector must be pairwise distinct'''Why must public keys be distinct?''' Reusing pubkeys could be insecure in the context of wallet policies containing [https://bitcoin.sipa.be/miniscript/ miniscript]. Avoiding repeated public keys altogether avoids the problem at the source.. If two key placeholders are @i//* and @i//* for the same index i, then the sets {M, N} and {P, Q} must be disjoint. -The key information vector should be ordered so that placeholder @i never appear for the first time before an occurrence of @j for some j < i; for example, the first placeholder is always @0, the next one is @1, etc. +The key information vector should be ordered so that placeholder @i never appears for the first time before an occurrence of @j for some j < i; for example, the first placeholder is always @0, the next one is @1, etc. === Descriptor derivation === @@ -183,7 +183,7 @@ produces the following multipath descriptor: === Implementation guidelines === -Implementations must not necessarily implement all the possible wallet policies defined by this standard, but it is recommended to clearly document any limitation. +It is acceptable to implement only a subset of the possible wallet policies defined by this standard. It is recommended that any limitations are clearly documented. Implementations can add additional metadata that is stored together with the wallet policy for the purpose of wallet policy registration and later usage. Metadata can be vendor-specific and is out of the scope of this document. @@ -274,10 +274,10 @@ The following descriptor templates are invalid: * sh(multi(1,@0/**,@2/**)): Skipped key placeholder @1 * sh(multi(1,@0/**,@0/**)): Repeated keys with the same path expression * sh(multi(1,@0/<0;1>/*,@0/<1;2>/*)): Non-disjoint multipath expressions (@0/1/* appears twice) -* sh(multi(1,@0/**,xpub6AHA9hZDN11k2ijHMeS5QqHx2KP9aMBRhTDqANMnwVtdyw2TDYRmF8PjpvwUFcL1Et8Hj59S3gTSMcUQ5gAqTz3Wd8EsMTmF3DChhqPQBnU/<0;1>/*)): Expression with a non KP key present +* sh(multi(1,@0/**,xpub6AHA9hZDN11k2ijHMeS5QqHx2KP9aMBRhTDqANMnwVtdyw2TDYRmF8PjpvwUFcL1Et8Hj59S3gTSMcUQ5gAqTz3Wd8EsMTmF3DChhqPQBnU/<0;1>/*)): Expression with a non-KP key present * pkh(@0/<0;1;2>/*): Solved cardinality > 2 -Remark: some of the descriptor templates above might be valid if optional extensions allowing them are added in the implementation. +Remark: some of the examples of invalid descriptor templates may be valid via optional extensions. == Backwards Compatibility == From 7d0c08e38acac3ef14095d0e8664c7332b7be381 Mon Sep 17 00:00:00 2001 From: Salvatore Ingala <6681844+bigspider@users.noreply.github.com> Date: Tue, 7 May 2024 22:24:23 +0200 Subject: [PATCH 242/454] More nits from PR review --- bip-0388.mediawiki | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/bip-0388.mediawiki b/bip-0388.mediawiki index d7ed0bec49..4efc588106 100644 --- a/bip-0388.mediawiki +++ b/bip-0388.mediawiki @@ -14,7 +14,7 @@ == Abstract == -Wallet policies build on top of output descriptors to represent the types of descriptors that are typically used to represent "accounts" in a software wallet, or a hardware signing device, in a compact, reviewable way. A wallet policy always represents exactly two descriptors, which produce the receive and change addresses that are logically part of the same account. +Wallet policies build on top of output script descriptors to represent the types of descriptors that are typically used to represent "accounts" in a software wallet, or a hardware signing device, in a compact, reviewable way. A wallet policy always represents exactly two descriptors, which produce the receive and change addresses that are logically part of the same account. We simplify the language to suit devices with limited memory, where even keeping the entire descriptor in memory could be a major hurdle, by reducing the generality of descriptors to just the essential features and by separating the extended pubkeys and other key information from the descriptor. @@ -101,7 +101,7 @@ In fact, there are many reasonable spending policies with a quadratic size in th With each xpub being 118 bytes long, the repetition of xpubs makes the descriptor become extremely large. -Replacing the common part of the key with a short key placeholder and moving the key expression separately helps to keep the size of the wallet policy small, which is crucial to allow human inspection during the registration flow. +Replacing the common part of the key with a short key placeholder and organizing all the key expressions in a separate list helps to keep the size of the wallet policy small, which is crucial to allow human inspection during the registration flow. == Specification == @@ -146,7 +146,7 @@ The placeholder @i for some number ''i'' represents the ''i''-th key in Note: while descriptor templates for miniscript are not formally defined in this version of the document (pending standardization), it is straightforward to adapt this approach by adding additional SCRIPT expressions. -==== Keys information vector ==== +==== Key information vector ==== Each element of the key origin information vector is a KEY expression. @@ -161,7 +161,7 @@ Each element of the key origin information vector is a KEY expression. A wallet policy must have at least one key placeholder and the corresponding key. -The public keys obtained by deserializing elements of the keys information vector must be pairwise distinct'''Why must public keys be distinct?''' Reusing pubkeys could be insecure in the context of wallet policies containing [https://bitcoin.sipa.be/miniscript/ miniscript]. Avoiding repeated public keys altogether avoids the problem at the source.. +The public keys obtained by deserializing elements of the key information vector must be pairwise distinct'''Why must public keys be distinct?''' Reusing pubkeys could be insecure in the context of wallet policies containing [https://bitcoin.sipa.be/miniscript/ miniscript]. Avoiding repeated public keys altogether avoids the problem at the source.. If two key placeholders are @i//* and @i//* for the same index i, then the sets {M, N} and {P, Q} must be disjoint. @@ -197,7 +197,7 @@ In order to allow supporting legacy derivation schemes (for example, using simpl However, care needs to be taken in view of the following considerations: -* Allowing derivation schemes with a different length or cardinality in the same wallet policy would make it difficult to guarantee that there are no repeated pubkeys for every possible address generated by the policy. For example, `@0/<0;1>/*` and `@1/*` would generate the same pubkeys if the second public key in the keys information vector is one of the first two unhardened children of the first public key. This could cause malleability with potential security implications (for example, in policies containing miniscript). +* Allowing derivation schemes with a different length or cardinality in the same wallet policy would make it difficult to guarantee that there are no repeated pubkeys for every possible address generated by the policy. For example, `@0/<0;1>/*` and `@1/*` would generate the same pubkeys if the second public key in the key information vector is one of the first two unhardened children of the first public key. This could cause malleability with potential security implications (for example, in policies containing miniscript). * Allowing naked pubkeys with no /* suffix (for example a descriptor template like wsh(multi(2,@0,@1/<0;1>/*))) would cause a pubkey to be repeated in every output generated from the policy, which would result in a total loss of privacy. == Examples == @@ -281,7 +281,7 @@ Remark: some of the examples of invalid descriptor templates may be valid via op == Backwards Compatibility == -The @ character used for key placeholders is not part of the syntax of output script descriptors, therefore any valid output descriptor with at least one `KEY` expression is not a valid descriptor template. Vice versa, any descriptor template with at least one key placeholder is not a valid output script descriptor. +The @ character used for key placeholders is not part of the syntax of output script descriptors, therefore any valid descriptor with at least one `KEY` expression is not a valid descriptor template. Vice versa, any descriptor template with at least one key placeholder is not a valid output script descriptor. Adoption of wallet policies in software and hardware wallets is opt-in. Conversion from wallet policies to the corresponding descriptors is programmatically extremely easy, and conversion from descriptors to wallet policies (when respecting the required patterns) can be automated. See the reference implementation below for some examples of conversion. From 96f4e5a4c4cd2e5ba4e74212077b858a3b047f31 Mon Sep 17 00:00:00 2001 From: josibake Date: Mon, 15 Jan 2024 12:23:22 +0100 Subject: [PATCH 243/454] Add BIP for Silent Payments Co-Authored-By: Ruben Somsen --- bip-0352.mediawiki | 437 ++++++++++++++++++++ bip-0352/scan_data_downloader_per_month.png | Bin 0 -> 54276 bytes 2 files changed, 437 insertions(+) create mode 100644 bip-0352.mediawiki create mode 100644 bip-0352/scan_data_downloader_per_month.png diff --git a/bip-0352.mediawiki b/bip-0352.mediawiki new file mode 100644 index 0000000000..2f8f767b43 --- /dev/null +++ b/bip-0352.mediawiki @@ -0,0 +1,437 @@ +
+  BIP: 352
+  Layer: Applications
+  Title: Silent Payments
+  Author: josibake 
+          Ruben Somsen 
+  Comments-URI: https://github.com/bitcoin/bips/wiki/Comments:BIP-0352
+  Status: Draft
+  Type: Standards Track
+  Created: 2023-03-09
+  License: BSD-2-Clause
+
+ +== Introduction == + +=== Abstract === + +This document specifies a protocol for static payment addresses in Bitcoin without on-chain linkability of payments or a need for on-chain notifications. + +=== Copyright === + +This BIP is licensed under the BSD 2-clause license. + +=== Motivation === + +Using a new address for each Bitcoin transaction is a crucial aspect of maintaining privacy. This often requires a secure interaction between sender and receiver so that the receiver can hand out a fresh address, a batch of fresh addresses, or a method for the sender to generate addresses on-demand, such as an xpub. + +However, interaction is often infeasible and in many cases undesirable. To solve for this, various protocols have been proposed which use a static payment address and notifications sent via the blockchain'''Why not use out-of-band notifications''' Out of band notifications (e.g. using something other than the Bitcoin blockchain) have been proposed as a way of addressing the privacy and cost concerns of using the Bitcoin blockchain as a messaging layer. This, however, simply moves the privacy and cost concerns somewhere else and increases the risk of losing money due to a notification not being reliably delivered, or even censored, and makes this notification data critical for backup to recover funds.. These protocols eliminate the need for interaction, but at the expense of increased costs for one-time payments and a noticeable footprint in the blockchain, potentially revealing metadata about the sender and receiver. Notification schemes also allow the receiver to link all payments from the same sender, compromising sender privacy. + +This proposal aims to address the limitations of these current approaches by presenting a solution that eliminates the need for interaction, eliminates the need for notifications, and protects both sender and receiver privacy. These benefits come at the cost of requiring wallets to scan the blockchain in order to detect payments. This added requirement is generally feasible for full nodes but poses a challenge for light clients. While it is possible today to implement a privacy-preserving light client at the cost of increased bandwidth, light client support is considered an area of open research (see [[#appendix-a-light-client-support|Appendix A: Light Client Support]]). + +The design keeps collaborative transactions such as CoinJoins and inputs with MuSig and FROST keys in mind, but it is recommended that the keys of all inputs of a transaction belong to the same entity as there is no formal proof that the protocol is secure in a collaborative setting. + +== Goals == + +We aim to present a protocol which satisfies the following properties: + +* No increase in the size or cost of transactions +* Resulting transactions blend in with other bitcoin transactions and can't be distinguished +* Transactions can't be linked to a silent payment address by an outside observer +* No sender-receiver interaction required +* No linking of multiple payments to the same sender +* Each silent payment goes to a unique address, avoiding accidental address reuse +* Supports payment labeling +* Uses existing seed phrase or descriptor methods for backup and recovery +* Separates scanning and spending responsibilities +* Compatible with other spending protocols, such as CoinJoin +* Light client/SPV wallet support +* Protocol is upgradeable + +== Overview == + +We first present an informal overview of the protocol. In what follows, uppercase letters represent public keys, lowercase letters represent private keys, ''||'' refers to byte concatenation, ''G'' represents the generator point for secp256k1, and ''n'' represents the curve order for secp256k1. Each section of the overview is incomplete on its own and is meant to build on the previous section in order to introduce and briefly explain each aspect of the protocol. For the full protocol specification, see [[#specification|Specification]]. + +''' Simple case ''' + +Bob publishes a public key ''B'' as a silent payment address. Alice discovers Bob's silent payment address, selects a UTXO with private key ''a'', public key ''A'' and creates a destination output ''P'' for Bob in the following manner: + +* Let ''P = B + hash(a·B)·G'' +* Encode ''P'' as a [https://github.com/bitcoin/bips/blob/master/bip-0341.mediawiki BIP341] taproot output + +Since ''a·B == b·A'' ([https://en.wikipedia.org/wiki/Elliptic-curve_Diffie%E2%80%93Hellman Elliptic-curve Diffie–Hellman]), Bob scans with his private key ''b'' by collecting the input public keys for each transaction with at least one unspent taproot output and performing the ECDH calculation until ''P'' is found (i.e. calculating ''P = B + hash(b·A)·G'' and seeing that ''P'' is present in the transaction outputs). + +''' Creating more than one output ''' + +In order to allow Alice to create more than one output for Bob'''Why allow for more than one output?''' Allowing Alice to break her payment to Bob into multiple amounts opens up a number of privacy improving techniques for Alice, making the transaction look like a CoinJoin or better hiding the change amount by splitting both the payment and change outputs into multiple amounts. It also allows for Alice and Carol to both have their own unique output paying Bob in the event they are in a collaborative transaction and both paying Bob's silent payment address., we include an integer in the following manner: + +* Let ''k = 0'' +* Let ''P0 = B + hash(a·B || k)·G'' +* For additional outputs: +** Increment ''k'' by one (''k++'') +** Let ''Pi = B + hash(a·B || k)·G'' + +Bob detects this output the same as before by searching for ''P0 = B + hash(b·A || 0)·G''. Once he detects the first output, he must: + +* Check for ''P1 = B + hash(b·A || 1)·G'' +* If ''P1'' is not found, stop +* If ''P1'' is found, continue to check for ''P2'' and so on until an additional output is not found + +Since Bob will only perform these subsequent checks after a transaction with at least one output paying him is found, the increase to his overall scanning requirement is negligible. It should also be noted that the order in which these outputs appear in the transaction does not affect the outcome. + +''' Preventing address reuse ''' + +If Alice were to use a different UTXO from the same public key ''A'' for a subsequent payment to Bob, she would end up deriving the same destinations ''Pi''. To prevent this, Alice should include an input hash in the following manner: + +* Let ''input_hash = hash(outpoint || A)'''''Why include A in the input hash calculation?''' By committing to A in input hash, this ensures that the sender cannot maliciously choose a private key ''a′'' in a subsequent transaction where ''a′ = input_hash·a / input_hash′'', which would force address reuse in the protocol. +* Let ''P0 = B + hash(input_hash·a·B || 0)·G'' + +Bob must calculate the same ''input_hash'' when scanning. + +''' Using all inputs ''' + +In our simplified example we have been referring to Alice's transactions as having only one input ''A'', but in reality a Bitcoin transaction can have many inputs. Instead of requiring Alice to pick a particular input and requiring Bob to check each input separately, we can instead require Alice to perform the tweak with the sum of the input public keys'''What about inputs without public keys?''' Inputs without public keys can still be spent in the transaction but are simply ignored in the silent payments protocol.. This significantly reduces Bob's scanning requirement, makes light client support more feasible'''How does using all inputs help light clients?''' If Alice uses a random input for the tweak, Bob necessarily has to have access to and check all transaction inputs, which requires performing an ECC multiplication per input. If instead Alice performs the tweak with the sum of the input public keys, Bob only needs the summed 33 byte public key per transaction and only does one ECC multiplication per transaction. Bob can then use BIP158 block filters to determine if any of the outputs exist in a block and thus avoids downloading transactions which don't belong to him. It is still an open question as to how Bob can source the 33 bytes per transaction in a trustless manner, see [[#appendix-a-light-client-support|Appendix A: Light Client Support]] for more details., and protects Alice's privacy in collaborative transaction protocols such as CoinJoin'''Why does using all inputs matter for CoinJoin?''' If Alice uses a random input to create the output for Bob, this necessarily reveals to Bob which input Alice has control of. If Alice is paying Bob as part of a CoinJoin, this would reveal which input belongs to her, degrading the anonymity set of the CoinJoin and giving Bob more information about Alice. If instead all inputs are used, Bob has no way of knowing which input(s) belong to Alice. This comes at the cost of increased complexity as the CoinJoin participants now need to coordinate to create the silent payment output and would need to use [https://gist.github.com/RubenSomsen/be7a4760dd4596d06963d67baf140406 Blind Diffie–Hellman] to prevent the other participants from learning who Alice is paying. Note it is currently not recommended to use this protocol for CoinJoins due to a lack of a formal security proof.. + +Alice performs the tweak with the sum of her input private keys in the following manner: + +* Let ''A = A1 + A2 + ... + An'' +* Let ''input_hash = hash(outpointL || A)'', where ''outpointL'' is the smallest outpoint lexicographically'''Why use the lexicographically smallest outpoint for the hash?''' Recall that the purpose of including the input hash is so that the sender and receiver can both come up with a deterministic nonce that ensures that a unique address is generated each time, even when reusing the same scriptPubKey as an input. Choosing the smallest outpoint lexicographically satisifes this requirement, while also ensuring that the generated output is not dependent on the final ordering of inputs in the transaction. Using a single outpoint also works well with memory constrained devices (such as hardware signing devices) as it does not require the device to have the entire transaction in memory in order to generate the silent payment output. +* Let ''a = a1 + a2 + ... + an'' +* Let ''P0 = B + hash(input_hash·a·B || 0)·G'' + +''' Spend and Scan Key ''' + +Since Bob needs his private key ''b'' to check for incoming payments, this requires ''b'' to be exposed to an online device. To minimize the risks involved, Bob can instead publish an address of the form ''(Bscan, Bspend)''. This allows Bob to keep ''bspend'' in offline cold storage and perform the scanning with the public key ''Bspend'' and private key ''bscan''. Alice performs the tweak using both of Bob's public keys in the following manner: + +* Let ''P0 = Bspend + hash(input_hash·a·Bscan || 0)·G'' + +Bob detects this payment by calculating ''P0 = Bspend + hash(input_hash·bscan·A || 0)·G'' with his online device and can spend from his cold storage signing device using ''(bspend + hash(input_hash·bscan·A || 0)) mod n'' as the private key. + +''' Labels ''' + +For a single silent payment address of the form ''(Bscan, Bspend)'', Bob may wish to differentiate incoming payments. Naively, Bob could publish multiple silent payment addresses, but this would require him to scan for each one, which becomes prohibitively expensive. Instead, Bob can label his spend public key ''Bspend'' with an integer ''m'' in the following way: + +* Let ''Bm = Bspend + hash(bscan || m)·G'' where m is an incrementable integer starting from 1 +* Publish ''(Bscan, B1)'', ''(Bscan, B2)'' etc. + +Alice performs the tweak as before using one of the published ''(Bscan, Bm)'' pairs. Bob detects the labeled payment in the following manner: + +* Let ''P0 = Bspend + hash(input_hash·bscan·A || 0)·G'' +* Subtract ''P0'' from each of the transaction outputs and check if the remainder matches any of the labels (''hash(bscan || 1)·G'', ''hash(bscan || 2)·G'' etc.) that the wallet has previously used + +It is important to note that an outside observer can easily deduce that each published ''(Bscan, Bm)'' pair is owned by the same entity as each published address will have ''Bscan'' in common. As such, labels are not meant as a way for Bob to manage separate identities, but rather a way for Bob to determine the source of an incoming payment. + +''' Labels for change ''' + +Bob can also use labels for managing his own change outputs. We reserve ''m = 0'' for this use case. This gives Bob an alternative to using BIP32 for managing change, while still allowing him to know which of his unspent outputs were change when recovering his wallet from the master key. It is important that the wallet never hands out the label with ''m = 0'' in order to ensure nobody else can create payments that are wrongly labeled as change. + +While the use of labels is optional, every receiving silent payments wallet should at least scan for the change label when recovering from backup in order to ensure maximum cross-compatibility. + +== Specification == + +We use the following functions and conventions: + +* ''outpoint'' (36 bytes): the COutPoint of an input (32-byte txid, least significant byte first || 4-byte vout, least significant byte first)'''Why are outpoints little-endian?''' Despite using big endian throughout the rest of the BIP, outpoints are sorted and hashed matching their transaction serialization, which is little-endian. This allows a wallet to parse a serialized transaction for use in silent payments without needing to re-order the bytes when computing the input hash. Note: despite outpoints being stored and serialized as little-endian, the transaction hash (txid) is always displayed as big-endian. +* ser32(i): serializes a 32-bit unsigned integer ''i'' as a 4-byte sequence, most significant byte first. +* ser256(p): serializes the integer p as a 32-byte sequence, most significant byte first. +* serP(P): serializes the coordinate pair P = (x,y) as a byte sequence using SEC1's compressed form: (0x02 or 0x03) || ser256(x), where the header byte depends on the parity of the omitted Y coordinate. + +For everything not defined above, we use the notation from [https://github.com/bitcoin/bips/blob/master/bip-0340.mediawiki#specification BIP340]. This includes the ''hashtag(x)'' notation to refer to ''SHA256(SHA256(tag) || SHA256(tag) || x)''. + +=== Versions === + +This document defines version 0 (''sp1q''). Version is communicated through the address in the same way as Segwit addresses. Future upgrades to silent payments will require a new version. As much as possible, future upgrades should support receiving from older wallets (e.g. a silent payments v0 wallet can send to both v0 and v1 addresses). Any changes that break compatibility with older silent payment versions should be a new BIP. + +Future silent payments versions will use the following scheme: + +{| class="wikitable" +|- +! +!0 +!1 +!2 +!3 +!4 +!5 +!6 +!7 +!Compatibility +|- +!+0 +|q||p||z||r||y||9||x||8||rowspan="4" | backwards compatible +|- +!+8 +|g||f||2||t||v||d||w||0 +|- +!+16 +|s||3||j||n||5||4||k||h +|- +!+24 +|c||e||6||m||u||a||7|| - +|} + +''v31'' (l) is reserved for a backwards incompatible change, if needed. For silent payments v0: + +* If the receiver's silent payment address version is: +** ''v0'': check that the data part is exactly 66-bytes. Otherwise, fail +** ''v1'' through ''v30'': read the first 66-bytes of the data part and discard the remaining bytes +** ''v31'': fail +* Receiver addresses are always [https://github.com/bitcoin/bips/blob/master/bip-0341.mediawiki BIP341] taproot outputs'''Why only taproot outputs?''' Providing too much optionality for the protocol makes it difficult to implement and can be at odds with the goal of providing the best privacy. Limiting to taproot outputs helps simplify the implementation significantly while also putting users in the best eventual anonymity set. +* The sender should sign with one of the sighash flags ''DEFAULT'', ''ALL'', ''SINGLE'', ''NONE'' (''ANYONECANPAY'' is unsafe). It is strongly recommended implementations use ''SIGHASH_ALL'' (''SIGHASH_DEFAULT'' for taproot inputs) when possible'''Why is it unsafe to use ''SIGHASH_ANYONECANPAY''?''' Since the output address for the receiver is derived from the sum of the [[#inputs-for-shared-secret-derivation|Inputs For Shared Secret Derivation]] public keys, the inputs must not change once the sender has signed the transaction. If the inputs are allowed to change after the fact, the receiver will not be able to calculate the shared secret needed to find and spend the output. It is currently an open question on how a future version of silent payments could be made to work with new sighash flags such as ''SIGHASH_GROUP'' and ''SIGHASH_ANYPREVOUT''. +* Inputs used to derive the shared secret are from the ''[[#inputs-for-shared-secret-derivation|Inputs For Shared Secret Derivation]]'' list + +=== Scanning silent payment eligible transactions === + +For silent payments v0 a transaction MUST be scanned if and only if all of the following are true: + +* The transaction contains at least one BIP341 taproot output (note: spent transactions optionally can be skipped by only considering transactions with at least one unspent taproot output) +* The transaction has at least one input from the ''[[#inputs-for-shared-secret-derivation|Inputs For Shared Secret Derivation]]'' list +* The transaction does not spend an output with SegWit version > 1'''Why skip transactions that spend SegWit version > 1?''' Skipping transactions that spend unknown output scripts allows us to have a clean upgrade path for silent payments by avoiding the need to scan the same transaction multiple times with different rule sets. If a new SegWit version is added in the future and silent payments v1 is released with support, we would want to avoid having to first scan the transaction with the silent payment v0 rules and then again with the silent payment v1 rules. Note: this restriction only applies to the inputs of a transaction. + +=== Address encoding === + +A silent payment address is constructed in the following manner: + +* Let ''Bscan, bscan = Receiver's scan public key and corresponding private key'' +* Let ''Bspend, bspend = Receiver's spend public key and corresponding private key'' +* Let ''Bm = Bspend + hashBIP0352/Label(ser256(bscan) || ser32(m))·G'', where ''hashBIP0352/Label(ser256(bscan) || ser32(m))·G'' is an optional integer tweak for labeling +** If no label is applied then ''Bm = Bspend'' +* The final address is a [https://github.com/bitcoin/bips/blob/master/bip-0350.mediawiki Bech32m] encoding of: +** The human-readable part "sp" for mainnet, "tsp" for testnets (e.g. signet, testnet) +** The data-part values: +*** The character "q", to represent a silent payment address of version 0 +*** The 66 byte concatenation of the receiver's public keys, ''serP(Bscan) || serP(Bm)'' + +Note: [https://github.com/bitcoin/bips/blob/master/bip-0173.mediawiki BIP173] imposes a 90 character limit for Bech32 segwit addresses and limits versions to 0 through 16, whereas a silent payment address requires ''at least'' 117 characters ''' Why do silent payment addresses need at least 117 characters?''' A silent payment address is a bech32m encoding comprised of the following parts: + + +* HRP [2-3 characters] +* separator [1 character] +* version [1-2 characters] +* payload, 66 bytes concatenated pubkeys [ceil(66*8/5) = 106 characters] +* checksum [6 characters] + + +For a silent payments v0 address, this results in a 117 character address when using a 3 character HRP. Future versions of silent payment addresses may add to the payload, which is why a 1023 character limit is suggested. and allows versions up to 31. Additionally, since higher versions may add to the data field, it is recommended implementations use a limit of 1023 characters (see [https://github.com/bitcoin/bips/blob/master/bip-0173.mediawiki#checksum-design BIP173: Checksum design] for more details). + +=== Inputs For Shared Secret Derivation === + +While any UTXO with known output scripts can be used to fund the transaction, the sender and receiver MUST use inputs from the following list when deriving the shared secret: + +* ''P2TR'' +* ''P2WPKH'' +* ''P2SH-P2WPKH'' +* ''P2PKH'' + +Inputs with conditional branches or multiple public keys (e.g. ''CHECKMULTISIG'') are excluded from shared secret derivation as this introduces malleability and would allow a sender to re-sign with a different set of public keys after the silent payment output has been derived. This is not a concern when the sender controls all of the inputs, but is an issue for CoinJoins and other collaborative protocols, where a malicious participant can participate in deriving the silent payment address with one set of keys and then re-broadcast the transaction with signatures for a different set of public keys. P2TR can have hidden conditional branches (script path), but we work around this by using only the output public key. + +For all of the output types listed, only X-only and compressed public keys are permitted''' Why only compressed public keys ''' Uncompressed and hybrid public keys are less common than compressed keys and generally considered to be a bad idea due to their blockspace inefficiency. Additionally, [https://github.com/bitcoin/bips/blob/master/bip-0143.mediawiki#restrictions-on-public-key-type BIP143] recommends restricting P2WPKH inputs to compressed keys as a default policy.. + +''' P2TR ''' + +'' Keypath spend '' + + witness: + scriptSig: (empty) + scriptPubKey: 1 <32-byte-x-only-key> + (0x5120{32-byte-x-only-key}) + +The sender uses the private key corresponding to the taproot output key (i.e. the tweaked private key). This can be a single private key or an aggregate key (e.g. taproot outputs using MuSig or FROST)'''Are key aggregation techniques like FROST and MuSig supported?''' While we do not recommend it due to lack of a security proof (except if all participants are trusted or are the same entity), any taproot output able to do a key path theoretically is supported. Any offline key aggregation technique can be used, such as FROST or MuSig. This would require participants to perform the ECDH step collaboratively e.g. ''ECDH = a1·Bscan + a2·Bscan + ... + at·Bscan'' and ''P = Bspend + hash(input_hash·ECDH || 0)·G''. Additionally, it may be necessary for the participants to provide a DLEQ proof to ensure they are not acting maliciously.. The receiver obtains the public key from the ''scriptPubKey'' (i.e. the taproot output key). + +'' Script path spend '' + + witness: + scriptSig: (empty) + scriptPubKey: 1 <32-byte-x-only-key> + (0x5120{32-byte-x-only-key}) + +Same as a keypath spend, the sender MUST use the private key corresponding to the taproot output key. If this key is not available, the output cannot be included as an input to the transaction. Same as a keypath spend, the receiver obtains the public key from the ''scriptPubKey'' (i.e. the taproot output key)''' Why not skip all taproot script path spends? ''' This causes malleability issues for CoinJoins. If the silent payments protocol skipped taproot script path spends, this would allow an attacker to join a CoinJoin round, participate in deriving the silent payment address using the tweaked private key for a key path spend, and then broadcast their own version of the transaction using the script path spend. If the receiver were to only consider key path spends, they would skip the attacker's script path spend input when deriving the shared secret and not be able to find the funds. Additionally, there may be scenarios where the sender can perform ECDH with the key path private key but spends the output using the script path.. + +The one exception is script path spends that use NUMS point ''H'' as their internal key (where ''H'' is constructed by taking the hash of the standard uncompressed encoding of the secp256k1 base point ''G'' as X coordinate, see [https://github.com/bitcoin/bips/blob/master/bip-0341.mediawiki#constructing-and-spending-taproot-outputs BIP341: Constructing and spending Taproot outputs] for more details), in which case the input will be skipped for the purposes of shared secret derivation'''Why skip outputs with H as the internal taproot key?''' If use cases get popularized where the taproot key path cannot be used, these outputs can still be included without getting in the way of making a silent payment, provided they specifically use H as their internal taproot key.. The receiver determines whether or not to skip the input by checking in the control block if the taproot internal key is equal to ''H''. + +''' P2WPKH ''' + + witness: <33-byte-compressed-key> + scriptSig: (empty) + scriptPubKey: 0 <20-byte-key-hash> + (0x0014{20-byte-key-hash}) + +The sender performs the tweak using the private key for the output and the receiver obtains the public key as the last witness item. + +''' P2SH-P2WPKH ''' + + witness: <33-byte-compressed-key> + scriptSig: <0 <20-byte-key-hash>> + (0x160014{20-byte-key-hash}) + scriptPubKey: HASH160 <20-byte-script-hash> EQUAL + (0xA914{20-byte-script-hash}87) + +The sender performs the tweak using the private key for the nested ''P2WPKH'' output and the receiver obtains the public key as the last witness item. + +''' P2PKH ''' + + scriptSig: <33-byte-compressed-key> + scriptPubKey: OP_DUP HASH160 <20-byte-key-hash> OP_EQUALVERIFY OP_CHECKSIG + (0x76A914{20-byte-key-hash}88AC) + +The receiver obtains the public key from the ''scriptSig''. The receiver MUST parse the ''scriptSig'' for the public key, even if the ''scriptSig'' does not match the template specified (e.g. OP_DROP ). This is to address the [https://en.bitcoin.it/wiki/Transaction_malleability third-party malleability of ''P2PKH'' ''scriptSigs'']. + +=== Input hash === + +The sender and receiver MUST calculate an input hash for the transaction in the following manner: + +* Let ''A = A1 + A2 + ... + An'', where each ''Ai'' is the public key of an input from the ''[[#inputs-for-shared-secret-derivation|Inputs For Shared Secret Derivation]]'' list +* Let ''input_hash = hashBIP0352/Inputs(outpointL || A)'', where ''outpointL'' is the smallest outpoint lexicographically by txid and vout used in the transaction + +=== Sender === + +==== Selecting inputs ==== + +The sending wallet performs coin selection as usual with the following restrictions: + +* At least one input MUST be from the ''[[#inputs-for-shared-secret-derivation|Inputs For Shared Secret Derivation]]'' list +* Exclude inputs with SegWit version > 1 (see ''[[#scanning-silent-payment-eligible-transactions|Scanning silent payment eligible transactions]]'') +* For each taproot output spent the sending wallet MUST have access to the private key corresponding to the taproot output key, unless ''H'' is used as the internal public key + +==== Creating outputs ==== + +After the inputs have been selected, the sender can create one or more outputs for one or more silent payment addresses in the following manner: + +* Generate the ''input_hash'' with the smallest outpoint lexicographically, using the method described above +* Collect the private keys for each input from the ''[[#inputs-for-shared-secret-derivation|Inputs For Shared Secret Derivation]]'' list +* For each private key ''ai'' corresponding to a [https://github.com/bitcoin/bips/blob/master/bip-0341.mediawiki BIP341] taproot output, check that the private key produces a point with an even Y coordinate and negate the private key if not'''Why do taproot private keys need to be checked?''' Recall from [https://github.com/bitcoin/bips/blob/master/bip-0340.mediawiki BIP340] that each X-only public key has two corresponding private keys, ''d'' and ''n - d''. To maintain parity between sender and receiver, it is necessary to use the private key corresponding to the even Y coordinate when performing the ECDH step since the receiver will assume the even Y coordinate when summing the taproot X-only public keys. +* Let ''a = a1 + a2 + ... + an'', where each ''ai'' has been negated if necessary +* Group receiver silent payment addresses by ''Bscan'' (e.g. each group consists of one ''Bscan'' and one or more ''Bm'') +* For each group: +** Let ''ecdh_shared_secret = input_hash·a·Bscan'' +** Let ''k = 0'' +** For each ''Bm'' in the group: +*** Let ''tk = hashBIP0352/SharedSecret(serP(ecdh_shared_secret) || ser32(k))'' +**** If ''tk'' is not valid tweak, i.e., if ''tk = 0'' or ''tk'' is larger or equal to the secp256k1 group order, fail +*** Let ''Pmn = Bm + tk·G'' +*** Encode ''Pmn'' as a [https://github.com/bitcoin/bips/blob/master/bip-0341.mediawiki BIP341] taproot output +*** Optionally, repeat with k++ to create additional outputs for the current ''Bm'' +*** If no additional outputs are required, continue to the next ''Bm'' with ''k++''''' Why not re-use ''tk'' when paying different labels to the same receiver?''' If paying the same entity but to two separate labeled addresses in the same transaction without incrementing ''k'', an outside observer could subtract the two output values and observe that this value is the same as the difference between two published silent payment addresses and learn who the recipient is. +** Optionally, if the sending wallet implements receiving silent payments, it can create change outputs by sending to its own silent payment address using label ''m = 0'', following the steps above + +=== Receiver === + +==== Key Derivation ==== + +Two keys are needed to create a silent payments address: the spend key and the scan key. To ensure compatibility, wallets MAY use BIP32 derivation with the following derivation paths for the spend and scan key. When using BIP32 derivation, wallet software MUST use hardened derivation'''Why use BIP32 hardened derivation?''' Using BIP32 derivation allows users to add silent payments to an existing master seed. It also ensures that a user's silent payment funds are recoverable in any BIP32/BIP43 compatible wallet. Using hardened derivation ensures that it is safe to export the scan private key without exposing the master key or spend private key. for both the spend and scan key. + +A scan and spend key pair using BIP32 derivation are defined (taking inspiration from [https://github.com/bitcoin/bips/blob/master/bip-0044.mediawiki BIP44]) in the following manner: + + scan_private_key: m / purpose' / coin_type' / account' / 1' / 0 + spend_private_key: m / purpose' / coin_type' / account' / 0' / 0 + +purpose is a constant set to ''352'' following the BIP43 recommendation. Refer to [https://github.com/bitcoin/bips/blob/master/bip-0043.mediawiki BIP43] and [https://github.com/bitcoin/bips/blob/master/bip-0044.mediawiki BIP44] for more details. + +==== Scanning ==== + +If each of the checks in ''[[#scanning-silent-payment-eligible-transactions|Scanning silent payment eligible transactions]]'' passes, the receiving wallet must: + +* Generate the ''input_hash'' with the smallest outpoint lexicographically, using the method described above +* Let ''A = A1 + A2 + ... + An'', where each ''Ai'' is the public key of an input from the ''[[#inputs-for-shared-secret-derivation|Inputs For Shared Secret Derivation]]'' list +* Let ''ecdh_shared_secret = input_hash·bscan·A'' +* Check for outputs: +** Let ''outputs_to_check'' be the taproot output keys from all taproot outputs in the transaction (spent and unspent). +** Starting with ''k = 0'': +*** Let ''tk = hashBIP0352/SharedSecret(serP(ecdh_shared_secret) || ser32(k))'' +**** If ''tk'' is not valid tweak, i.e., if ''tk = 0'' or ''tk'' is larger or equal to the secp256k1 group order, fail +*** Compute ''Pk = Bspend + tk·G'' +*** For each ''output'' in ''outputs_to_check'': +**** If ''Pk'' equals ''output'': +***** Add ''Pk'' to the wallet +***** Remove ''output'' from ''outputs_to_check'' and rescan ''outputs_to_check'' with ''k++'' +**** Else, check for labels (always check for the change label, i.e. ''hashBIP0352/Label(ser256(bscan) || ser32(m))'' where ''m = 0'')''' Why precompute labels?''' Precomputing the labels is not strictly necessary: a wallet could track the max number of labels it has used (call it ''M'') and scan for labels by adding ''hash(bscan || m)·G'' to ''P0'' for each label ''m'' up to ''M'' and comparing to the transaction outputs. This is more performant than precomputing the labels and checking via subtraction in cases where the number of eligible outputs exceeds the number of labels in use. In practice this will mainly apply to users that choose never to use labels, or users that use a single label for generating silent payment change outputs. If using a large number of labels, the wallet would need to add all possible labels to each output. This ends up being ''n·M'' additions, where ''n'' is the number of outputs in the transaction and ''M'' is the number of labels in the wallet. By precomputing the labels, the wallet only needs to compute ''hash(bscan || m)·G'' once when creating the labeled address and can determine if a label was used via a lookup, rather than adding each label to each output.: +***** Compute ''label = output - Pk'' +***** Check if ''label'' exists in the list of labels used by the wallet +***** If a match is found: +****** Add ''Pk + label'' to the wallet +****** Remove ''output'' from ''outputs_to_check'' and rescan ''outputs_to_check'' with ''k++'' +***** If a label is not found, negate ''output'' and check a second time''' Why negate the output?''' Unfortunately taproot outputs are X-only, meaning we don't know what the correct Y coordinate is. This causes this specific calculation to fail 50% of the time, so we need to repeat it with the other Y coordinate by negating the output. +*** If no matches are found, stop + +==== Spending ==== + +Recall that a silent payment output is of the form ''Bspend + tk·G + hashBIP0352/Label(ser256(bscan) || ser32(m))·G'', where ''hashBIP0352/Label(ser256(bscan) || ser32(m))·G'' is an optional label. To spend a silent payment output: + +* Let ''d = (bspend + tk + hashBIP0352/Label(ser256(bscan) || ser32(m))) mod n'', where ''hashBIP0352/Label(ser256(bscan) || ser32(m))'' is the optional label +* Spend the [https://github.com/bitcoin/bips/blob/master/bip-0341.mediawiki BIP341] output with the private key ''d'' + +==== Backup and Recovery ==== + +Since each silent payment output address is derived independently, regular backups are recommended. When recovering from a backup, the wallet will need to scan since the last backup to detect new payments. + +If using a seed/seed phrase only style backup, the user can recover the wallet's unspent outputs from the UTXO set (i.e. only scanning transactions with at least one unspent taproot output) and can recover the full wallet history by scanning the blockchain starting from the wallet birthday. If a wallet uses labels, this information SHOULD be included in the backup. If the user does not know whether labels were used, it is strongly recommended they always precompute and check a large number of labels (e.g. 100k labels) to use when re-scanning. This ensures that the wallet can recover all funds from only a seed/seed phrase backup. The change label should simply always be scanned for, even when no other labels were used. This ensures the use of a change label is not critical for backups and maximizes cross-compatibility. + +== Backward Compatibility == + +Silent payments introduces a new address format and protocol for sending and as such is not compatible with older wallet software or wallets which have not implemented the silent payments protocol. + +=== Functional tests === + +Below is a list of functional tests which should be included in sending and receiving implementations. + +==== Sending ==== + +* Ensure taproot outputs are excluded during coin selection if the sender does not have access to the key path private key (unless using ''H'' as the taproot internal key) +* Ensure the silent payment address is re-derived if inputs are added or removed during RBF + +==== Receiving ==== + +* Ensure the public key can be extracted from non-standard ''P2PKH'' scriptSigs +* Ensure taproot script path spends are included, using the taproot output key (unless ''H'' is used as the taproot internal key) +* Ensure the scanner can extract the public key from each of the input types supported (e.g. ''P2WPKH'', ''P2SH-P2WPKH'', etc.) + +== Appendix A: Light Client Support == + +This section proposes a few ideas for how light clients could support scanning for incoming silent payments (sending is fairly straightforward) in ways that preserve bandwidth and privacy. While this is out of scope for the current BIP, it is included to motivate further research into this topic. In this context, a light client refers to any bitcoin wallet client which does not process blocks and does not have a direct connection to a node which does process blocks (e.g. a full node). Based on this definition, clients that directly connect to a personal electrum server or a bitcoin node are not light clients. + +This distinction makes the problem for light clients more clear: light clients need a way to source the necessary data for performing the tweaks and a way of determining if any of the generated outputs exist in a block. + +=== Tweak Data === + +Recall that a silent payment eligible transaction follows [[#scanning-silent-payment-eligible-transactions|certain conditions]] and should have at least one unspent taproot output. Full nodes (or any index server backed by a full node, such as electrum server) can build an index which collects all of the eligible public keys for a silent payments eligible transaction, sums them up, multiplies the sum by the ''input_hash'', and serves them to clients. This would be 33 bytes per silent payment eligible transaction. + +For a typical bitcoin block of ~3500 txs, lets assume every transaction is a silent payments eligible transaction. This means a client would need to request ''33 bytes * 3500'' of data per block (roughly 100 kB per block). If a client were to request data for every block, this would amount to ~450 MB per month, assuming 100% taproot usage and all outputs remain unspent for > 1 month. As of today, these numbers are closer to 2–10 kB per block (10–50 MB per month)''' Data for Appendix A ''' These numbers are based on data from January 2023 until June 2023 (the last 6 months of data at time time of writing). See [https://github.com/josibake/bitcoin-data-analysis/blob/main/notebooks/silent-payments-light-client-data.ipynb Silent payments light client data] for the full analysis.. + +=== Transaction cut-through === + +It is unlikely a light client would need to scan every block and as such can take advantage of transaction cut-through, depending on how often they choose to scan for new blocks. Empirically, ~75% of transactions with at least one unspent taproot output will have spent all taproot UTXOs in 326 blocks or less. This means a client which only scans once every 3 days could ''significantly'' cut down on the number of blocks and the number of transactions per block that they need to request by only asking for data on transactions that were created since their last scan and that still have at least one unspent taproot output as of the current block height. Assuming 100% taproot usage, a client that scans once a month would likely only need around 50 MB worth of data. Based on current taproot adoption, a light client scanning once every 3 days would use roughly 15 MB per month and a client scanning once per month would use less than 5 MB per month. + +[[File:bip-0352/scan_data_downloader_per_month.png]] + +=== BIP158 === + +Once a light client has the tweak data for a block, they can determine whether or not an output to them exists in the block using BIP158 block filters. Per BIP158, they would then request the entire block and add the transaction to their wallet, though it maybe be possible to only request the prevout txids and vouts for all transactions with at least one taproot output, along with the scriptPubKeys and amounts. This would allow the client to download the necessary data for constructing a spending transaction, without downloading the entire block. How this affects the security assumptions of BIP158 is an open question. + +=== Out-of-band notifications === + +Assuming a secure messaging protocol exists, the sender can send an encrypted (using the scan public key of the silent payment address) notification to the receiver with the following information: +* The spend public key (communicates the label) +* The shared secret portion of the private key (i.e ''hash(ecdh_shared_secret || k)'') +* The outpoint and amount (so it's immediately spendable) + +It is important to note that these notifications are not required. At any point, the receiver can fall back to scanning for silent payment transactions if they don't trust the notifications they are receiving, are being spammed with fake notifications, or if they are concerned that they are not receiving notifications. + +A malicious notification could potentially cause the following issues: + +* You did not actually receive money to the stated key +** This can be probabilistically resolved by matching the key against the BIP158 block filters and assuming it's not a false positive, or fully resolved by downloading the block +* You received money but the outpoint or amount is incorrect, so attempts to spend it will fail or cause you to overpay fees +** There doesn't seem to be much motivation for malicious senders to ever do this, but light clients need to take into account that this can occur and should ideally check for it by downloading the block +* The private key is correct but it wasn't actually derived using the silent payment protocol, causing recovery from back-up to fail (unsafe - no implementation should ever allow this) +** This can be detected by downloading the tweak data of the corresponding block and should be resolved by immediately spending the output + +Wallet designers can choose which tradeoffs they find appropriate. For example, a wallet could check the block filter to at least probabilistically confirm the likely existence of the UTXO, thus efficiently cutting down on spam. The payment could then be marked as unconfirmed until a scan is performed and the existence of the UTXO in accordance to the silent payment specification is verified. + + +== Acknowledgements == + +This document is the result of many discussions and contains contributions by a number of people. The authors wish to thank all those who provided valuable feedback and reviews, including the participants of the [https://gist.github.com/RubenSomsen/21c477c90c942acf45f8e8f5c1ad4fae BIP47 Prague discussion], the [https://github.com/josibake/silent-payments-workshop Advancing Bitcoin silent payments Workshop], and [https://btctranscripts.com/bitcoin-core-dev-tech/2023-04-26-silent-payments/ coredev]. The authors would like to also thank [https://github.com/w0xlt w0xlt] for writing the initial implementation of silent payments. + +== Rationale and References == + + diff --git a/bip-0352/scan_data_downloader_per_month.png b/bip-0352/scan_data_downloader_per_month.png new file mode 100644 index 0000000000000000000000000000000000000000..ffcd0ddddb8c685b39055fd19112c81c8186109b GIT binary patch literal 54276 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%0DGQd??AjV1Xk_3E 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 z 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 literal 0 HcmV?d00001 From 33a99a1a17a569493cbf009bcd5458939c153f54 Mon Sep 17 00:00:00 2001 From: josibake Date: Mon, 15 Jan 2024 12:05:08 +0100 Subject: [PATCH 244/454] Add reference.py with test vectors * reference.py contains the silent payment specific code * secp256k1.py for doing the EC operations * bech32m.py contains code for encoding/decoding bech32(m) addresses * bitcoin_utils.py contains some helper code, not specific to silent payments * send_and_receive_test_vectors.json contains the wallet unit test vectors Co-Authored-By: S3RK <1466284+S3RK@users.noreply.github.com> Co-Authored-By: Oghenovo Usiwoma <37949128+Eunovo@users.noreply.github.com> Co-authored-by: S.Blagogee <34041358+setavenger@users.noreply.github.com> --- bip-0352.mediawiki | 52 + bip-0352/bech32m.py | 135 + bip-0352/bitcoin_utils.py | 158 ++ bip-0352/reference.py | 335 +++ bip-0352/secp256k1.py | 696 +++++ bip-0352/send_and_receive_test_vectors.json | 2673 +++++++++++++++++++ 6 files changed, 4049 insertions(+) create mode 100644 bip-0352/bech32m.py create mode 100644 bip-0352/bitcoin_utils.py create mode 100755 bip-0352/reference.py create mode 100644 bip-0352/secp256k1.py create mode 100644 bip-0352/send_and_receive_test_vectors.json diff --git a/bip-0352.mediawiki b/bip-0352.mediawiki index 2f8f767b43..8f41bca299 100644 --- a/bip-0352.mediawiki +++ b/bip-0352.mediawiki @@ -370,6 +370,58 @@ If using a seed/seed phrase only style backup, the user can recover the wallet's Silent payments introduces a new address format and protocol for sending and as such is not compatible with older wallet software or wallets which have not implemented the silent payments protocol. +== Test Vectors == + +A [[bip-0352/send_and_receive_test_vectors.json|collection of test vectors in JSON format]] are provided, along with a [[bip-0352/reference.py|python reference implementation]]. Each test vector consists of a sending test case and corresponding receiving test case. This is to allow sending and receiving to be implemented separately. To ensure determinism while testing, sort the array of ''Bm'' by amount (see the [[bip-0352/reference.py|reference implementation]]). Test cases use the following schema: + +''' test_case ''' + + { + "comment": "Comment describing the behavior being tested", + "sending": [], + "receiving": [], + } + +''' sender ''' + + { + "given": { + "vin": [], + "recipients": [] + }, + "expected": { + "outputs": [], + "n_outouts": , + }, + } + +''' recipient ''' + + { + "given": { + "vin": [], + "key_material": { + "scan_priv_key": , + "spend_priv_key": , + } + "labels": [], + }, + "expected": { + "addresses": [], + "outputs": [ + { + "priv_key_tweak": , + "pub_key": , + "signature": + }, + ... + ], + "n_outputs": + } + } + +Wallets should include inputs not in the ''[[#inputs-for-shared-secret-derivation|Inputs For Shared Secret Derivation]]'' list when testing to ensure that only inputs from the list are being used for shared secret derivation. Additionally, receiving wallets should include non-silent payment outputs for themselves in testing to ensure silent payments scanning does not interfere with regular outputs detection. + === Functional tests === Below is a list of functional tests which should be included in sending and receiving implementations. diff --git a/bip-0352/bech32m.py b/bip-0352/bech32m.py new file mode 100644 index 0000000000..795e153863 --- /dev/null +++ b/bip-0352/bech32m.py @@ -0,0 +1,135 @@ +# Copyright (c) 2017, 2020 Pieter Wuille +# +# Permission is hereby granted, free of charge, to any person obtaining a copy +# of this software and associated documentation files (the "Software"), to deal +# in the Software without restriction, including without limitation the rights +# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +# copies of the Software, and to permit persons to whom the Software is +# furnished to do so, subject to the following conditions: +# +# The above copyright notice and this permission notice shall be included in +# all copies or substantial portions of the Software. +# +# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +# THE SOFTWARE. + +"""Reference implementation for Bech32/Bech32m and segwit addresses.""" + + +from enum import Enum + +class Encoding(Enum): + """Enumeration type to list the various supported encodings.""" + BECH32 = 1 + BECH32M = 2 + +CHARSET = "qpzry9x8gf2tvdw0s3jn54khce6mua7l" +BECH32M_CONST = 0x2bc830a3 + +def bech32_polymod(values): + """Internal function that computes the Bech32 checksum.""" + generator = [0x3b6a57b2, 0x26508e6d, 0x1ea119fa, 0x3d4233dd, 0x2a1462b3] + chk = 1 + for value in values: + top = chk >> 25 + chk = (chk & 0x1ffffff) << 5 ^ value + for i in range(5): + chk ^= generator[i] if ((top >> i) & 1) else 0 + return chk + + +def bech32_hrp_expand(hrp): + """Expand the HRP into values for checksum computation.""" + return [ord(x) >> 5 for x in hrp] + [0] + [ord(x) & 31 for x in hrp] + + +def bech32_verify_checksum(hrp, data): + """Verify a checksum given HRP and converted data characters.""" + const = bech32_polymod(bech32_hrp_expand(hrp) + data) + if const == 1: + return Encoding.BECH32 + if const == BECH32M_CONST: + return Encoding.BECH32M + return None + +def bech32_create_checksum(hrp, data, spec): + """Compute the checksum values given HRP and data.""" + values = bech32_hrp_expand(hrp) + data + const = BECH32M_CONST if spec == Encoding.BECH32M else 1 + polymod = bech32_polymod(values + [0, 0, 0, 0, 0, 0]) ^ const + return [(polymod >> 5 * (5 - i)) & 31 for i in range(6)] + + +def bech32_encode(hrp, data, spec): + """Compute a Bech32 string given HRP and data values.""" + combined = data + bech32_create_checksum(hrp, data, spec) + return hrp + '1' + ''.join([CHARSET[d] for d in combined]) + +def bech32_decode(bech): + """Validate a Bech32/Bech32m string, and determine HRP and data.""" + if ((any(ord(x) < 33 or ord(x) > 126 for x in bech)) or + (bech.lower() != bech and bech.upper() != bech)): + return (None, None, None) + bech = bech.lower() + pos = bech.rfind('1') + + # remove the requirement that bech32m be less than 90 chars + if pos < 1 or pos + 7 > len(bech): + return (None, None, None) + if not all(x in CHARSET for x in bech[pos+1:]): + return (None, None, None) + hrp = bech[:pos] + data = [CHARSET.find(x) for x in bech[pos+1:]] + spec = bech32_verify_checksum(hrp, data) + if spec is None: + return (None, None, None) + return (hrp, data[:-6], spec) + +def convertbits(data, frombits, tobits, pad=True): + """General power-of-2 base conversion.""" + acc = 0 + bits = 0 + ret = [] + maxv = (1 << tobits) - 1 + max_acc = (1 << (frombits + tobits - 1)) - 1 + for value in data: + if value < 0 or (value >> frombits): + return None + acc = ((acc << frombits) | value) & max_acc + bits += frombits + while bits >= tobits: + bits -= tobits + ret.append((acc >> bits) & maxv) + if pad: + if bits: + ret.append((acc << (tobits - bits)) & maxv) + elif bits >= frombits or ((acc << (tobits - bits)) & maxv): + return None + return ret + + +def decode(hrp, addr): + """Decode a segwit address.""" + hrpgot, data, spec = bech32_decode(addr) + if hrpgot != hrp: + return (None, None) + decoded = convertbits(data[1:], 5, 8, False) + if decoded is None or len(decoded) < 2: + return (None, None) + if data[0] > 16: + return (None, None) + return (data[0], decoded) + + +def encode(hrp, witver, witprog): + """Encode a segwit address.""" + spec = Encoding.BECH32 if witver == 0 else Encoding.BECH32M + ret = bech32_encode(hrp, [witver] + convertbits(witprog, 8, 5), spec) + if decode(hrp, ret) == (None, None): + return None + return ret diff --git a/bip-0352/bitcoin_utils.py b/bip-0352/bitcoin_utils.py new file mode 100644 index 0000000000..443c096d0e --- /dev/null +++ b/bip-0352/bitcoin_utils.py @@ -0,0 +1,158 @@ +import hashlib +import struct +from io import BytesIO +from secp256k1 import ECKey +from typing import Union + + +def from_hex(hex_string): + """Deserialize from a hex string representation (e.g. from RPC)""" + return BytesIO(bytes.fromhex(hex_string)) + + +def ser_uint32(u: int) -> bytes: + return u.to_bytes(4, "big") + + +def ser_uint256(u): + return u.to_bytes(32, 'little') + + +def deser_uint256(f): + return int.from_bytes(f.read(32), 'little') + + +def deser_txid(txid: str): + # recall that txids are serialized little-endian, but displayed big-endian + # this means when converting from a human readable hex txid, we need to first + # reverse it before deserializing it + dixt = "".join(map(str.__add__, txid[-2::-2], txid[-1::-2])) + return bytes.fromhex(dixt) + + +def deser_compact_size(f: BytesIO): + view = f.getbuffer() + nbytes = view.nbytes; + view.release() + if (nbytes == 0): + return 0 # end of stream + + nit = struct.unpack(" bytes: + return hashlib.new("ripemd160", hashlib.sha256(s).digest()).digest() + + +def is_p2tr(spk: bytes) -> bool: + if len(spk) != 34: + return False + # OP_1 OP_PUSHBYTES_32 <32 bytes> + return (spk[0] == 0x51) & (spk[1] == 0x20) + + +def is_p2wpkh(spk: bytes) -> bool: + if len(spk) != 22: + return False + # OP_0 OP_PUSHBYTES_20 <20 bytes> + return (spk[0] == 0x00) & (spk[1] == 0x14) + + +def is_p2sh(spk: bytes) -> bool: + if len(spk) != 23: + return False + # OP_HASH160 OP_PUSHBYTES_20 <20 bytes> OP_EQUAL + return (spk[0] == 0xA9) & (spk[1] == 0x14) & (spk[-1] == 0x87) + + +def is_p2pkh(spk: bytes) -> bool: + if len(spk) != 25: + return False + # OP_DUP OP_HASH160 OP_PUSHBYTES_20 <20 bytes> OP_EQUALVERIFY OP_CHECKSIG + return (spk[0] == 0x76) & (spk[1] == 0xA9) & (spk[2] == 0x14) & (spk[-2] == 0x88) & (spk[-1] == 0xAC) diff --git a/bip-0352/reference.py b/bip-0352/reference.py new file mode 100755 index 0000000000..c98dac8965 --- /dev/null +++ b/bip-0352/reference.py @@ -0,0 +1,335 @@ +#!/usr/bin/env python3 +# For running the test vectors, run this script: +# ./reference.py send_and_receive_test_vectors.json + +import hashlib +import json +from typing import List, Tuple, Dict, cast +from sys import argv, exit +from functools import reduce +from itertools import permutations + +# local files +from bech32m import convertbits, bech32_encode, decode, Encoding +from secp256k1 import ECKey, ECPubKey, TaggedHash, NUMS_H +from bitcoin_utils import ( + deser_txid, + from_hex, + hash160, + is_p2pkh, + is_p2sh, + is_p2wpkh, + is_p2tr, + ser_uint32, + COutPoint, + CTxInWitness, + VinInfo, + ) + + +def get_pubkey_from_input(vin: VinInfo) -> ECPubKey: + if is_p2pkh(vin.prevout): + # skip the first 3 op_codes and grab the 20 byte hash + # from the scriptPubKey + spk_hash = vin.prevout[3:3 + 20] + for i in range(len(vin.scriptSig), 0, -1): + if i - 33 >= 0: + # starting from the back, we move over the scriptSig with a 33 byte + # window (to match a compressed pubkey). we hash this and check if it matches + # the 20 byte has from the scriptPubKey. for standard scriptSigs, this will match + # right away because the pubkey is the last item in the scriptSig. + # if its a non-standard (malleated) scriptSig, we will still find the pubkey if its + # a compressed pubkey. + # + # note: this is an incredibly inefficient implementation, for demonstration purposes only. + pubkey_bytes = vin.scriptSig[i - 33:i] + pubkey_hash = hash160(pubkey_bytes) + if pubkey_hash == spk_hash: + pubkey = ECPubKey().set(pubkey_bytes) + if (pubkey.valid) & (pubkey.compressed): + return pubkey + if is_p2sh(vin.prevout): + redeem_script = vin.scriptSig[1:] + if is_p2wpkh(redeem_script): + pubkey = ECPubKey().set(vin.txinwitness.scriptWitness.stack[-1]) + if (pubkey.valid) & (pubkey.compressed): + return pubkey + if is_p2wpkh(vin.prevout): + txin = vin.txinwitness + pubkey = ECPubKey().set(txin.scriptWitness.stack[-1]) + if (pubkey.valid) & (pubkey.compressed): + return pubkey + if is_p2tr(vin.prevout): + witnessStack = vin.txinwitness.scriptWitness.stack + if (len(witnessStack) >= 1): + if (len(witnessStack) > 1 and witnessStack[-1][0] == 0x50): + # Last item is annex + witnessStack.pop() + + if (len(witnessStack) > 1): + # Script-path spend + control_block = witnessStack[-1] + # control block is <32 byte internal key> and 0 or more <32 byte hash> + internal_key = control_block[1:33] + if (internal_key == NUMS_H.to_bytes(32, 'big')): + # Skip if NUMS_H + return ECPubKey() + + pubkey = ECPubKey().set(vin.prevout[2:]) + if (pubkey.valid) & (pubkey.compressed): + return pubkey + + + return ECPubKey() + + +def get_input_hash(outpoints: List[COutPoint], sum_input_pubkeys: ECPubKey) -> bytes: + lowest_outpoint = sorted(outpoints, key=lambda outpoint: outpoint.serialize())[0] + return TaggedHash("BIP0352/Inputs", lowest_outpoint.serialize() + cast(bytes, sum_input_pubkeys.get_bytes(False))) + + + +def encode_silent_payment_address(B_scan: ECPubKey, B_m: ECPubKey, hrp: str = "tsp", version: int = 0) -> str: + data = convertbits(cast(bytes, B_scan.get_bytes(False)) + cast(bytes, B_m.get_bytes(False)), 8, 5) + return bech32_encode(hrp, [version] + cast(List[int], data), Encoding.BECH32M) + + +def generate_label(b_scan: ECKey, m: int) -> bytes: + return TaggedHash("BIP0352/Label", b_scan.get_bytes() + ser_uint32(m)) + + +def create_labeled_silent_payment_address(b_scan: ECKey, B_spend: ECPubKey, m: int, hrp: str = "tsp", version: int = 0) -> str: + G = ECKey().set(1).get_pubkey() + B_scan = b_scan.get_pubkey() + B_m = B_spend + generate_label(b_scan, m) * G + labeled_address = encode_silent_payment_address(B_scan, B_m, hrp, version) + + return labeled_address + + +def decode_silent_payment_address(address: str, hrp: str = "tsp") -> Tuple[ECPubKey, ECPubKey]: + _, data = decode(hrp, address) + if data is None: + return ECPubKey(), ECPubKey() + B_scan = ECPubKey().set(data[:33]) + B_spend = ECPubKey().set(data[33:]) + + return B_scan, B_spend + + +def create_outputs(input_priv_keys: List[Tuple[ECKey, bool]], input_hash: bytes, recipients: List[str], hrp="tsp") -> List[str]: + G = ECKey().set(1).get_pubkey() + negated_keys = [] + for key, is_xonly in input_priv_keys: + k = ECKey().set(key.get_bytes()) + if is_xonly and k.get_pubkey().get_y() % 2 != 0: + k.negate() + negated_keys.append(k) + + a_sum = sum(negated_keys) + silent_payment_groups: Dict[ECPubKey, List[ECPubKey]] = {} + for recipient in recipients: + B_scan, B_m = decode_silent_payment_address(recipient, hrp=hrp) + if B_scan in silent_payment_groups: + silent_payment_groups[B_scan].append(B_m) + else: + silent_payment_groups[B_scan] = [B_m] + + outputs = [] + for B_scan, B_m_values in silent_payment_groups.items(): + ecdh_shared_secret = input_hash * a_sum * B_scan + k = 0 + for B_m in B_m_values: + t_k = TaggedHash("BIP0352/SharedSecret", ecdh_shared_secret.get_bytes(False) + ser_uint32(k)) + P_km = B_m + t_k * G + outputs.append(P_km.get_bytes().hex()) + k += 1 + + return list(set(outputs)) + + +def scanning(b_scan: ECKey, B_spend: ECPubKey, A_sum: ECPubKey, input_hash: bytes, outputs_to_check: List[ECPubKey], labels: Dict[str, str] = {}) -> List[Dict[str, str]]: + G = ECKey().set(1).get_pubkey() + ecdh_shared_secret = input_hash * b_scan * A_sum + k = 0 + wallet = [] + while True: + t_k = TaggedHash("BIP0352/SharedSecret", ecdh_shared_secret.get_bytes(False) + ser_uint32(k)) + P_k = B_spend + t_k * G + for output in outputs_to_check: + if P_k == output: + wallet.append({"pub_key": P_k.get_bytes().hex(), "priv_key_tweak": t_k.hex()}) + outputs_to_check.remove(output) + k += 1 + break + elif labels: + m_G_sub = output - P_k + if m_G_sub.get_bytes(False).hex() in labels: + P_km = P_k + m_G_sub + wallet.append({ + "pub_key": P_km.get_bytes().hex(), + "priv_key_tweak": (ECKey().set(t_k).add( + bytes.fromhex(labels[m_G_sub.get_bytes(False).hex()]) + )).get_bytes().hex(), + }) + outputs_to_check.remove(output) + k += 1 + break + else: + output.negate() + m_G_sub = output - P_k + if m_G_sub.get_bytes(False).hex() in labels: + P_km = P_k + m_G_sub + wallet.append({ + "pub_key": P_km.get_bytes().hex(), + "priv_key_tweak": (ECKey().set(t_k).add( + bytes.fromhex(labels[m_G_sub.get_bytes(False).hex()]) + )).get_bytes().hex(), + }) + outputs_to_check.remove(output) + k += 1 + break + else: + break + return wallet + + +if __name__ == "__main__": + if len(argv) != 2 or argv[1] in ('-h', '--help'): + print("Usage: ./reference.py send_and_receive_test_vectors.json") + exit(0) + + with open(argv[1], "r") as f: + test_data = json.loads(f.read()) + + # G , needed for generating the labels "database" + G = ECKey().set(1).get_pubkey() + for case in test_data: + print(case["comment"]) + # Test sending + for sending_test in case["sending"]: + given = sending_test["given"] + expected = sending_test["expected"] + + vins = [ + VinInfo( + outpoint=COutPoint(hash=deser_txid(input["txid"]), n=input["vout"]), + scriptSig=bytes.fromhex(input["scriptSig"]), + txinwitness=CTxInWitness().deserialize(from_hex(input["txinwitness"])), + prevout=bytes.fromhex(input["prevout"]["scriptPubKey"]["hex"]), + private_key=ECKey().set(bytes.fromhex(input["private_key"])), + ) + for input in given["vin"] + ] + # Conver the tuples to lists so they can be easily compared to the json list of lists from the given test vectors + input_priv_keys = [] + input_pub_keys = [] + for vin in vins: + pubkey = get_pubkey_from_input(vin) + if not pubkey.valid: + continue + input_priv_keys.append(( + vin.private_key, + is_p2tr(vin.prevout), + )) + input_pub_keys.append(pubkey) + + sending_outputs = [] + if (len(input_pub_keys) > 0): + A_sum = reduce(lambda x, y: x + y, input_pub_keys) + input_hash = get_input_hash([vin.outpoint for vin in vins], A_sum) + sending_outputs = create_outputs(input_priv_keys, input_hash, given["recipients"], hrp="sp") + + # Note: order doesn't matter for creating/finding the outputs. However, different orderings of the recipient addresses + # will produce different generated outputs if sending to multiple silent payment addresses belonging to the + # same sender but with different labels. Because of this, expected["outputs"] contains all possible valid output sets, + # based on all possible permutations of recipient address orderings. Must match exactly one of the possible output sets. + assert(any(set(sending_outputs) == set(lst) for lst in expected["outputs"])), "Sending test failed" + else: + assert(sending_outputs == expected["outputs"][0] == []), "Sending test failed" + + # Test receiving + msg = hashlib.sha256(b"message").digest() + aux = hashlib.sha256(b"random auxiliary data").digest() + for receiving_test in case["receiving"]: + given = receiving_test["given"] + expected = receiving_test["expected"] + outputs_to_check = [ + ECPubKey().set(bytes.fromhex(p)) for p in given["outputs"] + ] + vins = [ + VinInfo( + outpoint=COutPoint(hash=deser_txid(input["txid"]), n=input["vout"]), + scriptSig=bytes.fromhex(input["scriptSig"]), + txinwitness=CTxInWitness().deserialize(from_hex(input["txinwitness"])), + prevout=bytes.fromhex(input["prevout"]["scriptPubKey"]["hex"]), + ) + for input in given["vin"] + ] + # Check that the given inputs for the receiving test match what was generated during the sending test + receiving_addresses = [] + b_scan = ECKey().set(bytes.fromhex(given["key_material"]["scan_priv_key"])) + b_spend = ECKey().set( + bytes.fromhex(given["key_material"]["spend_priv_key"]) + ) + B_scan = b_scan.get_pubkey() + B_spend = b_spend.get_pubkey() + receiving_addresses.append( + encode_silent_payment_address(B_scan, B_spend, hrp="sp") + ) + if given["labels"]: + for label in given["labels"]: + receiving_addresses.append( + create_labeled_silent_payment_address( + b_scan, B_spend, m=label, hrp="sp" + ) + ) + + # Check that the silent payment addresses match for the given BIP32 seed and labels dictionary + assert (receiving_addresses == expected["addresses"]), "Receiving addresses don't match" + input_pub_keys = [] + for vin in vins: + pubkey = get_pubkey_from_input(vin) + if not pubkey.valid: + continue + input_pub_keys.append(pubkey) + + add_to_wallet = [] + if (len(input_pub_keys) > 0): + A_sum = reduce(lambda x, y: x + y, input_pub_keys) + input_hash = get_input_hash([vin.outpoint for vin in vins], A_sum) + pre_computed_labels = { + (generate_label(b_scan, label) * G).get_bytes(False).hex(): generate_label(b_scan, label).hex() + for label in given["labels"] + } + add_to_wallet = scanning( + b_scan=b_scan, + B_spend=B_spend, + A_sum=A_sum, + input_hash=input_hash, + outputs_to_check=outputs_to_check, + labels=pre_computed_labels, + ) + + # Check that the private key is correct for the found output public key + for output in add_to_wallet: + pub_key = ECPubKey().set(bytes.fromhex(output["pub_key"])) + full_private_key = b_spend.add(bytes.fromhex(output["priv_key_tweak"])) + if full_private_key.get_pubkey().get_y() % 2 != 0: + full_private_key.negate() + + sig = full_private_key.sign_schnorr(msg, aux) + assert pub_key.verify_schnorr(sig, msg), f"Invalid signature for {pub_key}" + output["signature"] = sig.hex() + + # Note: order doesn't matter for creating/finding the outputs. However, different orderings of the recipient addresses + # will produce different generated outputs if sending to multiple silent payment addresses belonging to the + # same sender but with different labels. Because of this, expected["outputs"] contains all possible valid output sets, + # based on all possible permutations of recipient address orderings. Must match exactly one of the possible found output + # sets in expected["outputs"] + generated_set = {frozenset(d.items()) for d in add_to_wallet} + expected_set = {frozenset(d.items()) for d in expected["outputs"]} + assert generated_set == expected_set, "Receive test failed" + + + print("All tests passed") diff --git a/bip-0352/secp256k1.py b/bip-0352/secp256k1.py new file mode 100644 index 0000000000..0ccbc4e6a4 --- /dev/null +++ b/bip-0352/secp256k1.py @@ -0,0 +1,696 @@ +# Copyright (c) 2019 Pieter Wuille +# Distributed under the MIT software license, see the accompanying +# file COPYING or http://www.opensource.org/licenses/mit-license.php. +"""Test-only secp256k1 elliptic curve implementation + +WARNING: This code is slow, uses bad randomness, does not properly protect +keys, and is trivially vulnerable to side channel attacks. Do not use for +anything but tests.""" +import random +import hashlib +import hmac + +def TaggedHash(tag, data): + ss = hashlib.sha256(tag.encode('utf-8')).digest() + ss += ss + ss += data + return hashlib.sha256(ss).digest() + +def modinv(a, n): + """Compute the modular inverse of a modulo n + + See https://en.wikipedia.org/wiki/Extended_Euclidean_algorithm#Modular_integers. + """ + t1, t2 = 0, 1 + r1, r2 = n, a + while r2 != 0: + q = r1 // r2 + t1, t2 = t2, t1 - q * t2 + r1, r2 = r2, r1 - q * r2 + if r1 > 1: + return None + if t1 < 0: + t1 += n + return t1 + +def jacobi_symbol(n, k): + """Compute the Jacobi symbol of n modulo k + + See http://en.wikipedia.org/wiki/Jacobi_symbol + + For our application k is always prime, so this is the same as the Legendre symbol.""" + assert k > 0 and k & 1, "jacobi symbol is only defined for positive odd k" + n %= k + t = 0 + while n != 0: + while n & 1 == 0: + n >>= 1 + r = k & 7 + t ^= (r == 3 or r == 5) + n, k = k, n + t ^= (n & k & 3 == 3) + n = n % k + if k == 1: + return -1 if t else 1 + return 0 + +def modsqrt(a, p): + """Compute the square root of a modulo p when p % 4 = 3. + + The Tonelli-Shanks algorithm can be used. See https://en.wikipedia.org/wiki/Tonelli-Shanks_algorithm + + Limiting this function to only work for p % 4 = 3 means we don't need to + iterate through the loop. The highest n such that p - 1 = 2^n Q with Q odd + is n = 1. Therefore Q = (p-1)/2 and sqrt = a^((Q+1)/2) = a^((p+1)/4) + + secp256k1's is defined over field of size 2**256 - 2**32 - 977, which is 3 mod 4. + """ + if p % 4 != 3: + raise NotImplementedError("modsqrt only implemented for p % 4 = 3") + sqrt = pow(a, (p + 1)//4, p) + if pow(sqrt, 2, p) == a % p: + return sqrt + return None + +def int_or_bytes(s): + "Convert 32-bytes to int while accepting also int and returning it as is." + if isinstance(s, bytes): + assert(len(s) == 32) + s = int.from_bytes(s, 'big') + elif not isinstance(s, int): + raise TypeError + return s + +class EllipticCurve: + def __init__(self, p, a, b): + """Initialize elliptic curve y^2 = x^3 + a*x + b over GF(p).""" + self.p = p + self.a = a % p + self.b = b % p + + def affine(self, p1): + """Convert a Jacobian point tuple p1 to affine form, or None if at infinity. + + An affine point is represented as the Jacobian (x, y, 1)""" + x1, y1, z1 = p1 + if z1 == 0: + return None + inv = modinv(z1, self.p) + inv_2 = (inv**2) % self.p + inv_3 = (inv_2 * inv) % self.p + return ((inv_2 * x1) % self.p, (inv_3 * y1) % self.p, 1) + + def has_even_y(self, p1): + """Whether the point p1 has an even Y coordinate when expressed in affine coordinates.""" + return not (p1[2] == 0 or self.affine(p1)[1] & 1) + + def negate(self, p1): + """Negate a Jacobian point tuple p1.""" + x1, y1, z1 = p1 + return (x1, (self.p - y1) % self.p, z1) + + def on_curve(self, p1): + """Determine whether a Jacobian tuple p is on the curve (and not infinity)""" + x1, y1, z1 = p1 + z2 = pow(z1, 2, self.p) + z4 = pow(z2, 2, self.p) + return z1 != 0 and (pow(x1, 3, self.p) + self.a * x1 * z4 + self.b * z2 * z4 - pow(y1, 2, self.p)) % self.p == 0 + + def is_x_coord(self, x): + """Test whether x is a valid X coordinate on the curve.""" + x_3 = pow(x, 3, self.p) + return jacobi_symbol(x_3 + self.a * x + self.b, self.p) != -1 + + def lift_x(self, x): + """Given an X coordinate on the curve, return a corresponding affine point.""" + x_3 = pow(x, 3, self.p) + v = x_3 + self.a * x + self.b + y = modsqrt(v, self.p) + if y is None: + return None + return (x, y, 1) + + def double(self, p1): + """Double a Jacobian tuple p1 + + See https://en.wikibooks.org/wiki/Cryptography/Prime_Curve/Jacobian_Coordinates - Point Doubling""" + x1, y1, z1 = p1 + if z1 == 0: + return (0, 1, 0) + y1_2 = (y1**2) % self.p + y1_4 = (y1_2**2) % self.p + x1_2 = (x1**2) % self.p + s = (4*x1*y1_2) % self.p + m = 3*x1_2 + if self.a: + m += self.a * pow(z1, 4, self.p) + m = m % self.p + x2 = (m**2 - 2*s) % self.p + y2 = (m*(s - x2) - 8*y1_4) % self.p + z2 = (2*y1*z1) % self.p + return (x2, y2, z2) + + def add_mixed(self, p1, p2): + """Add a Jacobian tuple p1 and an affine tuple p2 + + See https://en.wikibooks.org/wiki/Cryptography/Prime_Curve/Jacobian_Coordinates - Point Addition (with affine point)""" + x1, y1, z1 = p1 + x2, y2, z2 = p2 + assert(z2 == 1) + # Adding to the point at infinity is a no-op + if z1 == 0: + return p2 + z1_2 = (z1**2) % self.p + z1_3 = (z1_2 * z1) % self.p + u2 = (x2 * z1_2) % self.p + s2 = (y2 * z1_3) % self.p + if x1 == u2: + if (y1 != s2): + # p1 and p2 are inverses. Return the point at infinity. + return (0, 1, 0) + # p1 == p2. The formulas below fail when the two points are equal. + return self.double(p1) + h = u2 - x1 + r = s2 - y1 + h_2 = (h**2) % self.p + h_3 = (h_2 * h) % self.p + u1_h_2 = (x1 * h_2) % self.p + x3 = (r**2 - h_3 - 2*u1_h_2) % self.p + y3 = (r*(u1_h_2 - x3) - y1*h_3) % self.p + z3 = (h*z1) % self.p + return (x3, y3, z3) + + def add(self, p1, p2): + """Add two Jacobian tuples p1 and p2 + + See https://en.wikibooks.org/wiki/Cryptography/Prime_Curve/Jacobian_Coordinates - Point Addition""" + x1, y1, z1 = p1 + x2, y2, z2 = p2 + # Adding the point at infinity is a no-op + if z1 == 0: + return p2 + if z2 == 0: + return p1 + # Adding an Affine to a Jacobian is more efficient since we save field multiplications and squarings when z = 1 + if z1 == 1: + return self.add_mixed(p2, p1) + if z2 == 1: + return self.add_mixed(p1, p2) + z1_2 = (z1**2) % self.p + z1_3 = (z1_2 * z1) % self.p + z2_2 = (z2**2) % self.p + z2_3 = (z2_2 * z2) % self.p + u1 = (x1 * z2_2) % self.p + u2 = (x2 * z1_2) % self.p + s1 = (y1 * z2_3) % self.p + s2 = (y2 * z1_3) % self.p + if u1 == u2: + if (s1 != s2): + # p1 and p2 are inverses. Return the point at infinity. + return (0, 1, 0) + # p1 == p2. The formulas below fail when the two points are equal. + return self.double(p1) + h = u2 - u1 + r = s2 - s1 + h_2 = (h**2) % self.p + h_3 = (h_2 * h) % self.p + u1_h_2 = (u1 * h_2) % self.p + x3 = (r**2 - h_3 - 2*u1_h_2) % self.p + y3 = (r*(u1_h_2 - x3) - s1*h_3) % self.p + z3 = (h*z1*z2) % self.p + return (x3, y3, z3) + + def mul(self, ps): + """Compute a (multi) point multiplication + + ps is a list of (Jacobian tuple, scalar) pairs. + """ + r = (0, 1, 0) + for i in range(255, -1, -1): + r = self.double(r) + for (p, n) in ps: + if ((n >> i) & 1): + r = self.add(r, p) + return r + +SECP256K1_FIELD_SIZE = 2**256 - 2**32 - 977 +SECP256K1 = EllipticCurve(SECP256K1_FIELD_SIZE, 0, 7) +SECP256K1_G = (0x79BE667EF9DCBBAC55A06295CE870B07029BFCDB2DCE28D959F2815B16F81798, 0x483ADA7726A3C4655DA4FBFC0E1108A8FD17B448A68554199C47D08FFB10D4B8, 1) +SECP256K1_ORDER = 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEBAAEDCE6AF48A03BBFD25E8CD0364141 +SECP256K1_ORDER_HALF = SECP256K1_ORDER // 2 +NUMS_H = 0x50929b74c1a04954b78b4b6035e97a5e078a5a0f28ec96d547bfee9ace803ac0 + +class ECPubKey(): + """A secp256k1 public key""" + + def __init__(self): + """Construct an uninitialized public key""" + self.valid = False + + def __repr__(self): + return self.get_bytes().hex() + + def __eq__(self, other): + assert isinstance(other, ECPubKey) + return self.get_bytes() == other.get_bytes() + + def __hash__(self): + return hash(self.get_bytes()) + + def set(self, data): + """Construct a public key from a serialization in compressed or uncompressed DER format or BIP340 format""" + if (len(data) == 65 and data[0] == 0x04): + p = (int.from_bytes(data[1:33], 'big'), int.from_bytes(data[33:65], 'big'), 1) + self.valid = SECP256K1.on_curve(p) + if self.valid: + self.p = p + self.compressed = False + elif (len(data) == 33 and (data[0] == 0x02 or data[0] == 0x03)): + x = int.from_bytes(data[1:33], 'big') + if SECP256K1.is_x_coord(x): + p = SECP256K1.lift_x(x) + # if the oddness of the y co-ord isn't correct, find the other + # valid y + if (p[1] & 1) != (data[0] & 1): + p = SECP256K1.negate(p) + self.p = p + self.valid = True + self.compressed = True + else: + self.valid = False + elif (len(data) == 32): + x = int.from_bytes(data[0:32], 'big') + if SECP256K1.is_x_coord(x): + p = SECP256K1.lift_x(x) + # if the oddness of the y co-ord isn't correct, find the other + # valid y + if p[1]%2 != 0: + p = SECP256K1.negate(p) + self.p = p + self.valid = True + self.compressed = True + else: + self.valid = False + else: + self.valid = False + return self + + @property + def is_compressed(self): + return self.compressed + + @property + def is_valid(self): + return self.valid + + def get_y(self): + return SECP256K1.affine(self.p)[1] + + def get_x(self): + return SECP256K1.affine(self.p)[0] + + def get_bytes(self, bip340=True): + assert(self.valid) + p = SECP256K1.affine(self.p) + if p is None: + return None + if bip340: + return bytes(p[0].to_bytes(32, 'big')) + elif self.compressed: + return bytes([0x02 + (p[1] & 1)]) + p[0].to_bytes(32, 'big') + else: + return bytes([0x04]) + p[0].to_bytes(32, 'big') + p[1].to_bytes(32, 'big') + + def verify_ecdsa(self, sig, msg, low_s=True): + """Verify a strictly DER-encoded ECDSA signature against this pubkey. + + See https://en.wikipedia.org/wiki/Elliptic_Curve_Digital_Signature_Algorithm for the + ECDSA verifier algorithm""" + assert(self.valid) + + # Extract r and s from the DER formatted signature. Return false for + # any DER encoding errors. + if (sig[1] + 2 != len(sig)): + return False + if (len(sig) < 4): + return False + if (sig[0] != 0x30): + return False + if (sig[2] != 0x02): + return False + rlen = sig[3] + if (len(sig) < 6 + rlen): + return False + if rlen < 1 or rlen > 33: + return False + if sig[4] >= 0x80: + return False + if (rlen > 1 and (sig[4] == 0) and not (sig[5] & 0x80)): + return False + r = int.from_bytes(sig[4:4+rlen], 'big') + if (sig[4+rlen] != 0x02): + return False + slen = sig[5+rlen] + if slen < 1 or slen > 33: + return False + if (len(sig) != 6 + rlen + slen): + return False + if sig[6+rlen] >= 0x80: + return False + if (slen > 1 and (sig[6+rlen] == 0) and not (sig[7+rlen] & 0x80)): + return False + s = int.from_bytes(sig[6+rlen:6+rlen+slen], 'big') + + # Verify that r and s are within the group order + if r < 1 or s < 1 or r >= SECP256K1_ORDER or s >= SECP256K1_ORDER: + return False + if low_s and s >= SECP256K1_ORDER_HALF: + return False + z = int.from_bytes(msg, 'big') + + # Run verifier algorithm on r, s + w = modinv(s, SECP256K1_ORDER) + u1 = z*w % SECP256K1_ORDER + u2 = r*w % SECP256K1_ORDER + R = SECP256K1.affine(SECP256K1.mul([(SECP256K1_G, u1), (self.p, u2)])) + if R is None or R[0] != r: + return False + return True + + def verify_schnorr(self, sig, msg): + assert(len(msg) == 32) + assert(len(sig) == 64) + assert(self.valid) + r = int.from_bytes(sig[0:32], 'big') + if r >= SECP256K1_FIELD_SIZE: + return False + s = int.from_bytes(sig[32:64], 'big') + if s >= SECP256K1_ORDER: + return False + e = int.from_bytes(TaggedHash("BIP0340/challenge", sig[0:32] + self.get_bytes() + msg), 'big') % SECP256K1_ORDER + R = SECP256K1.mul([(SECP256K1_G, s), (self.p, SECP256K1_ORDER - e)]) + if not SECP256K1.has_even_y(R): + return False + if ((r * R[2] * R[2]) % SECP256K1_FIELD_SIZE) != R[0]: + return False + return True + + def __add__(self, other): + """Adds two ECPubKey points.""" + assert isinstance(other, ECPubKey) + assert self.valid + assert other.valid + ret = ECPubKey() + ret.p = SECP256K1.add(other.p, self.p) + ret.valid = True + ret.compressed = self.compressed + return ret + + def __radd__(self, other): + """Allows this ECPubKey to be added to 0 for sum()""" + if other == 0: + return self + else: + return self + other + + def __mul__(self, other): + """Multiplies ECPubKey point with a scalar(int/32bytes/ECKey).""" + if isinstance(other, ECKey): + assert self.valid + assert other.secret is not None + multiplier = other.secret + else: + # int_or_bytes checks that other is `int` or `bytes` + multiplier = int_or_bytes(other) + + assert multiplier < SECP256K1_ORDER + multiplier = multiplier % SECP256K1_ORDER + ret = ECPubKey() + ret.p = SECP256K1.mul([(self.p, multiplier)]) + ret.valid = True + ret.compressed = self.compressed + return ret + + def __rmul__(self, other): + """Multiplies a scalar(int/32bytes/ECKey) with an ECPubKey point""" + return self * other + + def __sub__(self, other): + """Subtract one point from another""" + assert isinstance(other, ECPubKey) + assert self.valid + assert other.valid + ret = ECPubKey() + ret.p = SECP256K1.add(self.p, SECP256K1.negate(other.p)) + ret.valid = True + ret.compressed = self.compressed + return ret + + def tweak_add(self, tweak): + assert(self.valid) + t = int_or_bytes(tweak) + if t >= SECP256K1_ORDER: + return None + tweaked = SECP256K1.affine(SECP256K1.mul([(self.p, 1), (SECP256K1_G, t)])) + if tweaked is None: + return None + ret = ECPubKey() + ret.p = tweaked + ret.valid = True + ret.compressed = self.compressed + return ret + + def mul(self, data): + """Multiplies ECPubKey point with scalar data.""" + assert self.valid + other = ECKey() + other.set(data, True) + return self * other + + def negate(self): + self.p = SECP256K1.affine(SECP256K1.negate(self.p)) + +def rfc6979_nonce(key): + """Compute signing nonce using RFC6979.""" + v = bytes([1] * 32) + k = bytes([0] * 32) + k = hmac.new(k, v + b"\x00" + key, 'sha256').digest() + v = hmac.new(k, v, 'sha256').digest() + k = hmac.new(k, v + b"\x01" + key, 'sha256').digest() + v = hmac.new(k, v, 'sha256').digest() + return hmac.new(k, v, 'sha256').digest() + +class ECKey(): + """A secp256k1 private key""" + + def __init__(self): + self.valid = False + + def __repr__(self): + return str(self.secret) + + def __eq__(self, other): + assert isinstance(other, ECKey) + return self.secret == other.secret + + def __hash__(self): + return hash(self.secret) + + def set(self, secret, compressed=True): + """Construct a private key object from either 32-bytes or an int secret and a compressed flag.""" + secret = int_or_bytes(secret) + + self.valid = (secret > 0 and secret < SECP256K1_ORDER) + if self.valid: + self.secret = secret + self.compressed = compressed + return self + + def generate(self, compressed=True): + """Generate a random private key (compressed or uncompressed).""" + self.set(random.randrange(1, SECP256K1_ORDER).to_bytes(32, 'big'), compressed) + return self + + def get_bytes(self): + """Retrieve the 32-byte representation of this key.""" + assert(self.valid) + return self.secret.to_bytes(32, 'big') + + def as_int(self): + return self.secret + + def from_int(self, secret, compressed=True): + self.valid = (secret > 0 and secret < SECP256K1_ORDER) + if self.valid: + self.secret = secret + self.compressed = compressed + + def __add__(self, other): + """Add key secrets. Returns compressed key.""" + assert isinstance(other, ECKey) + assert other.secret > 0 and other.secret < SECP256K1_ORDER + assert self.valid is True + ret_data = ((self.secret + other.secret) % SECP256K1_ORDER).to_bytes(32, 'big') + ret = ECKey() + ret.set(ret_data, True) + return ret + + def __radd__(self, other): + """Allows this ECKey to be added to 0 for sum()""" + if other == 0: + return self + else: + return self + other + + def __sub__(self, other): + """Subtract key secrets. Returns compressed key.""" + assert isinstance(other, ECKey) + assert other.secret > 0 and other.secret < SECP256K1_ORDER + assert self.valid is True + ret_data = ((self.secret - other.secret) % SECP256K1_ORDER).to_bytes(32, 'big') + ret = ECKey() + ret.set(ret_data, True) + return ret + + def __mul__(self, other): + """Multiply a private key by another private key or multiply a public key by a private key. Returns compressed key.""" + if isinstance(other, ECKey): + assert other.secret > 0 and other.secret < SECP256K1_ORDER + assert self.valid is True + ret_data = ((self.secret * other.secret) % SECP256K1_ORDER).to_bytes(32, 'big') + ret = ECKey() + ret.set(ret_data, True) + return ret + elif isinstance(other, ECPubKey): + return other * self + else: + # ECKey().set() checks that other is an `int` or `bytes` + assert self.valid + second = ECKey().set(other, self.compressed) + return self * second + + def __rmul__(self, other): + return self * other + + def add(self, data): + """Add key to scalar data. Returns compressed key.""" + other = ECKey() + other.set(data, True) + return self + other + + def mul(self, data): + """Multiply key secret with scalar data. Returns compressed key.""" + other = ECKey() + other.set(data, True) + return self * other + + def negate(self): + """Negate a private key.""" + assert self.valid + self.secret = SECP256K1_ORDER - self.secret + + @property + def is_valid(self): + return self.valid + + @property + def is_compressed(self): + return self.compressed + + def get_pubkey(self): + """Compute an ECPubKey object for this secret key.""" + assert(self.valid) + ret = ECPubKey() + p = SECP256K1.mul([(SECP256K1_G, self.secret)]) + ret.p = p + ret.valid = True + ret.compressed = self.compressed + return ret + + def sign_ecdsa(self, msg, low_s=True, rfc6979=False): + """Construct a DER-encoded ECDSA signature with this key. + + See https://en.wikipedia.org/wiki/Elliptic_Curve_Digital_Signature_Algorithm for the + ECDSA signer algorithm.""" + assert(self.valid) + z = int.from_bytes(msg, 'big') + # Note: no RFC6979 by default, but a simple random nonce (some tests rely on distinct transactions for the same operation) + if rfc6979: + k = int.from_bytes(rfc6979_nonce(self.secret.to_bytes(32, 'big') + msg), 'big') + else: + k = random.randrange(1, SECP256K1_ORDER) + R = SECP256K1.affine(SECP256K1.mul([(SECP256K1_G, k)])) + r = R[0] % SECP256K1_ORDER + s = (modinv(k, SECP256K1_ORDER) * (z + self.secret * r)) % SECP256K1_ORDER + if low_s and s > SECP256K1_ORDER_HALF: + s = SECP256K1_ORDER - s + # Represent in DER format. The byte representations of r and s have + # length rounded up (255 bits becomes 32 bytes and 256 bits becomes 33 + # bytes). + rb = r.to_bytes((r.bit_length() + 8) // 8, 'big') + sb = s.to_bytes((s.bit_length() + 8) // 8, 'big') + return b'\x30' + bytes([4 + len(rb) + len(sb), 2, len(rb)]) + rb + bytes([2, len(sb)]) + sb + + def sign_schnorr(self, msg, aux=None): + """Create a Schnorr signature (see BIP340).""" + if aux is None: + aux = bytes(32) + + assert self.valid + assert len(msg) == 32 + assert len(aux) == 32 + + t = (self.secret ^ int.from_bytes(TaggedHash("BIP0340/aux", aux), 'big')).to_bytes(32, 'big') + kp = int.from_bytes(TaggedHash("BIP0340/nonce", t + self.get_pubkey().get_bytes() + msg), 'big') % SECP256K1_ORDER + assert kp != 0 + R = SECP256K1.affine(SECP256K1.mul([(SECP256K1_G, kp)])) + k = kp if SECP256K1.has_even_y(R) else SECP256K1_ORDER - kp + e = int.from_bytes(TaggedHash("BIP0340/challenge", R[0].to_bytes(32, 'big') + self.get_pubkey().get_bytes() + msg), 'big') % SECP256K1_ORDER + return R[0].to_bytes(32, 'big') + ((k + e * self.secret) % SECP256K1_ORDER).to_bytes(32, 'big') + + def tweak_add(self, tweak): + """Return a tweaked version of this private key.""" + assert(self.valid) + t = int_or_bytes(tweak) + if t >= SECP256K1_ORDER: + return None + tweaked = (self.secret + t) % SECP256K1_ORDER + if tweaked == 0: + return None + ret = ECKey() + ret.set(tweaked.to_bytes(32, 'big'), self.compressed) + return ret + +def generate_key_pair(secret=None, compressed=True): + """Convenience function to generate a private-public key pair.""" + d = ECKey() + if secret: + d.set(secret, compressed) + else: + d.generate(compressed) + + P = d.get_pubkey() + return d, P + +def generate_bip340_key_pair(): + """Convenience function to generate a BIP0340 private-public key pair.""" + d = ECKey() + d.generate() + P = d.get_pubkey() + if P.get_y()%2 != 0: + d.negate() + P.negate() + return d, P + +def generate_schnorr_nonce(): + """Generate a random valid BIP340 nonce. + + See https://github.com/bitcoin/bips/blob/master/bip-0340.mediawiki. + This implementation ensures the y-coordinate of the nonce point is even.""" + kp = random.randrange(1, SECP256K1_ORDER) + assert kp != 0 + R = SECP256K1.affine(SECP256K1.mul([(SECP256K1_G, kp)])) + k = kp if R[1] % 2 == 0 else SECP256K1_ORDER - kp + k_key = ECKey() + k_key.set(k.to_bytes(32, 'big'), True) + return k_key diff --git a/bip-0352/send_and_receive_test_vectors.json b/bip-0352/send_and_receive_test_vectors.json new file mode 100644 index 0000000000..f9b205b8d3 --- /dev/null +++ b/bip-0352/send_and_receive_test_vectors.json @@ -0,0 +1,2673 @@ +[ + { + "comment": "Simple send: two inputs", + "sending": [ + { + "given": { + "vin": [ + { + "txid": "f4184fc596403b9d638783cf57adfe4c75c605f6356fbc91338530e9831e9e16", + "vout": 0, + "scriptSig": "483046022100ad79e6801dd9a8727f342f31c71c4912866f59dc6e7981878e92c5844a0ce929022100fb0d2393e813968648b9753b7e9871d90ab3d815ebf91820d704b19f4ed224d621025a1e61f898173040e20616d43e9f496fba90338a39faa1ed98fcbaeee4dd9be5", + "txinwitness": "", + "prevout": { + "scriptPubKey": { + "hex": "76a91419c2f3ae0ca3b642bd3e49598b8da89f50c1416188ac" + } + }, + "private_key": "eadc78165ff1f8ea94ad7cfdc54990738a4c53f6e0507b42154201b8e5dff3b1" + }, + { + "txid": "a1075db55d416d3ca199f55b6084e2115b9345e16c5cf302fc80e9d5fbf5d48d", + "vout": 0, + "scriptSig": "48304602210086783ded73e961037e77d49d9deee4edc2b23136e9728d56e4491c80015c3a63022100fda4c0f21ea18de29edbce57f7134d613e044ee150a89e2e64700de2d4e83d4e2103bd85685d03d111699b15d046319febe77f8de5286e9e512703cdee1bf3be3792", + "txinwitness": "", + "prevout": { + "scriptPubKey": { + "hex": "76a914d9317c66f54ff0a152ec50b1d19c25be50c8e15988ac" + } + }, + "private_key": "93f5ed907ad5b2bdbbdcb5d9116ebc0a4e1f92f910d5260237fa45a9408aad16" + } + ], + "recipients": [ + "sp1qqgste7k9hx0qftg6qmwlkqtwuy6cycyavzmzj85c6qdfhjdpdjtdgqjuexzk6murw56suy3e0rd2cgqvycxttddwsvgxe2usfpxumr70xc9pkqwv" + ] + }, + "expected": { + "outputs": [ + [ + "3e9fce73d4e77a4809908e3c3a2e54ee147b9312dc5044a193d1fc85de46e3c1" + ] + ] + } + } + ], + "receiving": [ + { + "given": { + "vin": [ + { + "txid": "f4184fc596403b9d638783cf57adfe4c75c605f6356fbc91338530e9831e9e16", + "vout": 0, + "scriptSig": "483046022100ad79e6801dd9a8727f342f31c71c4912866f59dc6e7981878e92c5844a0ce929022100fb0d2393e813968648b9753b7e9871d90ab3d815ebf91820d704b19f4ed224d621025a1e61f898173040e20616d43e9f496fba90338a39faa1ed98fcbaeee4dd9be5", + "txinwitness": "", + "prevout": { + "scriptPubKey": { + "hex": "76a91419c2f3ae0ca3b642bd3e49598b8da89f50c1416188ac" + } + } + }, + { + "txid": "a1075db55d416d3ca199f55b6084e2115b9345e16c5cf302fc80e9d5fbf5d48d", + "vout": 0, + "scriptSig": "48304602210086783ded73e961037e77d49d9deee4edc2b23136e9728d56e4491c80015c3a63022100fda4c0f21ea18de29edbce57f7134d613e044ee150a89e2e64700de2d4e83d4e2103bd85685d03d111699b15d046319febe77f8de5286e9e512703cdee1bf3be3792", + "txinwitness": "", + "prevout": { + "scriptPubKey": { + "hex": "76a914d9317c66f54ff0a152ec50b1d19c25be50c8e15988ac" + } + } + } + ], + "outputs": [ + "3e9fce73d4e77a4809908e3c3a2e54ee147b9312dc5044a193d1fc85de46e3c1" + ], + "key_material": { + "spend_priv_key": "9d6ad855ce3417ef84e836892e5a56392bfba05fa5d97ccea30e266f540e08b3", + "scan_priv_key": "0f694e068028a717f8af6b9411f9a133dd3565258714cc226594b34db90c1f2c" + }, + "labels": [] + }, + "expected": { + "addresses": [ + "sp1qqgste7k9hx0qftg6qmwlkqtwuy6cycyavzmzj85c6qdfhjdpdjtdgqjuexzk6murw56suy3e0rd2cgqvycxttddwsvgxe2usfpxumr70xc9pkqwv" + ], + "outputs": [ + { + "priv_key_tweak": "f438b40179a3c4262de12986c0e6cce0634007cdc79c1dcd3e20b9ebc2e7eef6", + "pub_key": "3e9fce73d4e77a4809908e3c3a2e54ee147b9312dc5044a193d1fc85de46e3c1", + "signature": "74f85b856337fbe837643b86f462118159f93ac4acc2671522f27e8f67b079959195ccc7a5dbee396d2909f5d680d6e30cda7359aa2755822509b70d6b0687a1" + } + ] + } + } + ] + }, + { + "comment": "Simple send: two inputs, order reversed", + "sending": [ + { + "given": { + "vin": [ + { + "txid": "a1075db55d416d3ca199f55b6084e2115b9345e16c5cf302fc80e9d5fbf5d48d", + "vout": 0, + "scriptSig": "483046022100ad79e6801dd9a8727f342f31c71c4912866f59dc6e7981878e92c5844a0ce929022100fb0d2393e813968648b9753b7e9871d90ab3d815ebf91820d704b19f4ed224d621025a1e61f898173040e20616d43e9f496fba90338a39faa1ed98fcbaeee4dd9be5", + "txinwitness": "", + "prevout": { + "scriptPubKey": { + "hex": "76a91419c2f3ae0ca3b642bd3e49598b8da89f50c1416188ac" + } + }, + "private_key": "eadc78165ff1f8ea94ad7cfdc54990738a4c53f6e0507b42154201b8e5dff3b1" + }, + { + "txid": "f4184fc596403b9d638783cf57adfe4c75c605f6356fbc91338530e9831e9e16", + "vout": 0, + "scriptSig": "48304602210086783ded73e961037e77d49d9deee4edc2b23136e9728d56e4491c80015c3a63022100fda4c0f21ea18de29edbce57f7134d613e044ee150a89e2e64700de2d4e83d4e2103bd85685d03d111699b15d046319febe77f8de5286e9e512703cdee1bf3be3792", + "txinwitness": "", + "prevout": { + "scriptPubKey": { + "hex": "76a914d9317c66f54ff0a152ec50b1d19c25be50c8e15988ac" + } + }, + "private_key": "93f5ed907ad5b2bdbbdcb5d9116ebc0a4e1f92f910d5260237fa45a9408aad16" + } + ], + "recipients": [ + "sp1qqgste7k9hx0qftg6qmwlkqtwuy6cycyavzmzj85c6qdfhjdpdjtdgqjuexzk6murw56suy3e0rd2cgqvycxttddwsvgxe2usfpxumr70xc9pkqwv" + ] + }, + "expected": { + "outputs": [ + [ + "3e9fce73d4e77a4809908e3c3a2e54ee147b9312dc5044a193d1fc85de46e3c1" + ] + ] + } + } + ], + "receiving": [ + { + "given": { + "vin": [ + { + "txid": "a1075db55d416d3ca199f55b6084e2115b9345e16c5cf302fc80e9d5fbf5d48d", + "vout": 0, + "scriptSig": "483046022100ad79e6801dd9a8727f342f31c71c4912866f59dc6e7981878e92c5844a0ce929022100fb0d2393e813968648b9753b7e9871d90ab3d815ebf91820d704b19f4ed224d621025a1e61f898173040e20616d43e9f496fba90338a39faa1ed98fcbaeee4dd9be5", + "txinwitness": "", + "prevout": { + "scriptPubKey": { + "hex": "76a91419c2f3ae0ca3b642bd3e49598b8da89f50c1416188ac" + } + } + }, + { + "txid": "f4184fc596403b9d638783cf57adfe4c75c605f6356fbc91338530e9831e9e16", + "vout": 0, + "scriptSig": "48304602210086783ded73e961037e77d49d9deee4edc2b23136e9728d56e4491c80015c3a63022100fda4c0f21ea18de29edbce57f7134d613e044ee150a89e2e64700de2d4e83d4e2103bd85685d03d111699b15d046319febe77f8de5286e9e512703cdee1bf3be3792", + "txinwitness": "", + "prevout": { + "scriptPubKey": { + "hex": "76a914d9317c66f54ff0a152ec50b1d19c25be50c8e15988ac" + } + } + } + ], + "outputs": [ + "3e9fce73d4e77a4809908e3c3a2e54ee147b9312dc5044a193d1fc85de46e3c1" + ], + "key_material": { + "spend_priv_key": "9d6ad855ce3417ef84e836892e5a56392bfba05fa5d97ccea30e266f540e08b3", + "scan_priv_key": "0f694e068028a717f8af6b9411f9a133dd3565258714cc226594b34db90c1f2c" + }, + "labels": [] + }, + "expected": { + "addresses": [ + "sp1qqgste7k9hx0qftg6qmwlkqtwuy6cycyavzmzj85c6qdfhjdpdjtdgqjuexzk6murw56suy3e0rd2cgqvycxttddwsvgxe2usfpxumr70xc9pkqwv" + ], + "outputs": [ + { + "priv_key_tweak": "f438b40179a3c4262de12986c0e6cce0634007cdc79c1dcd3e20b9ebc2e7eef6", + "pub_key": "3e9fce73d4e77a4809908e3c3a2e54ee147b9312dc5044a193d1fc85de46e3c1", + "signature": "74f85b856337fbe837643b86f462118159f93ac4acc2671522f27e8f67b079959195ccc7a5dbee396d2909f5d680d6e30cda7359aa2755822509b70d6b0687a1" + } + ] + } + } + ] + }, + { + "comment": "Simple send: two inputs from the same transaction", + "sending": [ + { + "given": { + "vin": [ + { + "txid": "f4184fc596403b9d638783cf57adfe4c75c605f6356fbc91338530e9831e9e16", + "vout": 3, + "scriptSig": "483046022100ad79e6801dd9a8727f342f31c71c4912866f59dc6e7981878e92c5844a0ce929022100fb0d2393e813968648b9753b7e9871d90ab3d815ebf91820d704b19f4ed224d621025a1e61f898173040e20616d43e9f496fba90338a39faa1ed98fcbaeee4dd9be5", + "txinwitness": "", + "prevout": { + "scriptPubKey": { + "hex": "76a91419c2f3ae0ca3b642bd3e49598b8da89f50c1416188ac" + } + }, + "private_key": "eadc78165ff1f8ea94ad7cfdc54990738a4c53f6e0507b42154201b8e5dff3b1" + }, + { + "txid": "f4184fc596403b9d638783cf57adfe4c75c605f6356fbc91338530e9831e9e16", + "vout": 7, + "scriptSig": "48304602210086783ded73e961037e77d49d9deee4edc2b23136e9728d56e4491c80015c3a63022100fda4c0f21ea18de29edbce57f7134d613e044ee150a89e2e64700de2d4e83d4e2103bd85685d03d111699b15d046319febe77f8de5286e9e512703cdee1bf3be3792", + "txinwitness": "", + "prevout": { + "scriptPubKey": { + "hex": "76a914d9317c66f54ff0a152ec50b1d19c25be50c8e15988ac" + } + }, + "private_key": "93f5ed907ad5b2bdbbdcb5d9116ebc0a4e1f92f910d5260237fa45a9408aad16" + } + ], + "recipients": [ + "sp1qqgste7k9hx0qftg6qmwlkqtwuy6cycyavzmzj85c6qdfhjdpdjtdgqjuexzk6murw56suy3e0rd2cgqvycxttddwsvgxe2usfpxumr70xc9pkqwv" + ] + }, + "expected": { + "outputs": [ + [ + "79e71baa2ba3fc66396de3a04f168c7bf24d6870ec88ca877754790c1db357b6" + ] + ] + } + } + ], + "receiving": [ + { + "given": { + "vin": [ + { + "txid": "f4184fc596403b9d638783cf57adfe4c75c605f6356fbc91338530e9831e9e16", + "vout": 3, + "scriptSig": "483046022100ad79e6801dd9a8727f342f31c71c4912866f59dc6e7981878e92c5844a0ce929022100fb0d2393e813968648b9753b7e9871d90ab3d815ebf91820d704b19f4ed224d621025a1e61f898173040e20616d43e9f496fba90338a39faa1ed98fcbaeee4dd9be5", + "txinwitness": "", + "prevout": { + "scriptPubKey": { + "hex": "76a91419c2f3ae0ca3b642bd3e49598b8da89f50c1416188ac" + } + } + }, + { + "txid": "f4184fc596403b9d638783cf57adfe4c75c605f6356fbc91338530e9831e9e16", + "vout": 7, + "scriptSig": "48304602210086783ded73e961037e77d49d9deee4edc2b23136e9728d56e4491c80015c3a63022100fda4c0f21ea18de29edbce57f7134d613e044ee150a89e2e64700de2d4e83d4e2103bd85685d03d111699b15d046319febe77f8de5286e9e512703cdee1bf3be3792", + "txinwitness": "", + "prevout": { + "scriptPubKey": { + "hex": "76a914d9317c66f54ff0a152ec50b1d19c25be50c8e15988ac" + } + } + } + ], + "outputs": [ + "79e71baa2ba3fc66396de3a04f168c7bf24d6870ec88ca877754790c1db357b6" + ], + "key_material": { + "spend_priv_key": "9d6ad855ce3417ef84e836892e5a56392bfba05fa5d97ccea30e266f540e08b3", + "scan_priv_key": "0f694e068028a717f8af6b9411f9a133dd3565258714cc226594b34db90c1f2c" + }, + "labels": [] + }, + "expected": { + "addresses": [ + "sp1qqgste7k9hx0qftg6qmwlkqtwuy6cycyavzmzj85c6qdfhjdpdjtdgqjuexzk6murw56suy3e0rd2cgqvycxttddwsvgxe2usfpxumr70xc9pkqwv" + ], + "outputs": [ + { + "priv_key_tweak": "4851455bfbe1ab4f80156570aa45063201aa5c9e1b1dcd29f0f8c33d10bf77ae", + "pub_key": "79e71baa2ba3fc66396de3a04f168c7bf24d6870ec88ca877754790c1db357b6", + "signature": "10332eea808b6a13f70059a8a73195808db782012907f5ba32b6eae66a2f66b4f65147e2b968a1678c5f73d57d5d195dbaf667b606ff80c8490eac1f3b710657" + } + ] + } + } + ] + }, + { + "comment": "Simple send: two inputs from the same transaction, order reversed", + "sending": [ + { + "given": { + "vin": [ + { + "txid": "a1075db55d416d3ca199f55b6084e2115b9345e16c5cf302fc80e9d5fbf5d48d", + "vout": 7, + "scriptSig": "483046022100ad79e6801dd9a8727f342f31c71c4912866f59dc6e7981878e92c5844a0ce929022100fb0d2393e813968648b9753b7e9871d90ab3d815ebf91820d704b19f4ed224d621025a1e61f898173040e20616d43e9f496fba90338a39faa1ed98fcbaeee4dd9be5", + "txinwitness": "", + "prevout": { + "scriptPubKey": { + "hex": "76a91419c2f3ae0ca3b642bd3e49598b8da89f50c1416188ac" + } + }, + "private_key": "eadc78165ff1f8ea94ad7cfdc54990738a4c53f6e0507b42154201b8e5dff3b1" + }, + { + "txid": "a1075db55d416d3ca199f55b6084e2115b9345e16c5cf302fc80e9d5fbf5d48d", + "vout": 3, + "scriptSig": "48304602210086783ded73e961037e77d49d9deee4edc2b23136e9728d56e4491c80015c3a63022100fda4c0f21ea18de29edbce57f7134d613e044ee150a89e2e64700de2d4e83d4e2103bd85685d03d111699b15d046319febe77f8de5286e9e512703cdee1bf3be3792", + "txinwitness": "", + "prevout": { + "scriptPubKey": { + "hex": "76a914d9317c66f54ff0a152ec50b1d19c25be50c8e15988ac" + } + }, + "private_key": "93f5ed907ad5b2bdbbdcb5d9116ebc0a4e1f92f910d5260237fa45a9408aad16" + } + ], + "recipients": [ + "sp1qqgste7k9hx0qftg6qmwlkqtwuy6cycyavzmzj85c6qdfhjdpdjtdgqjuexzk6murw56suy3e0rd2cgqvycxttddwsvgxe2usfpxumr70xc9pkqwv" + ] + }, + "expected": { + "outputs": [ + [ + "f4c2da807f89cb1501f1a77322a895acfb93c28e08ed2724d2beb8e44539ba38" + ] + ] + } + } + ], + "receiving": [ + { + "given": { + "vin": [ + { + "txid": "a1075db55d416d3ca199f55b6084e2115b9345e16c5cf302fc80e9d5fbf5d48d", + "vout": 7, + "scriptSig": "483046022100ad79e6801dd9a8727f342f31c71c4912866f59dc6e7981878e92c5844a0ce929022100fb0d2393e813968648b9753b7e9871d90ab3d815ebf91820d704b19f4ed224d621025a1e61f898173040e20616d43e9f496fba90338a39faa1ed98fcbaeee4dd9be5", + "txinwitness": "", + "prevout": { + "scriptPubKey": { + "hex": "76a91419c2f3ae0ca3b642bd3e49598b8da89f50c1416188ac" + } + } + }, + { + "txid": "a1075db55d416d3ca199f55b6084e2115b9345e16c5cf302fc80e9d5fbf5d48d", + "vout": 3, + "scriptSig": "48304602210086783ded73e961037e77d49d9deee4edc2b23136e9728d56e4491c80015c3a63022100fda4c0f21ea18de29edbce57f7134d613e044ee150a89e2e64700de2d4e83d4e2103bd85685d03d111699b15d046319febe77f8de5286e9e512703cdee1bf3be3792", + "txinwitness": "", + "prevout": { + "scriptPubKey": { + "hex": "76a914d9317c66f54ff0a152ec50b1d19c25be50c8e15988ac" + } + } + } + ], + "outputs": [ + "f4c2da807f89cb1501f1a77322a895acfb93c28e08ed2724d2beb8e44539ba38" + ], + "key_material": { + "spend_priv_key": "9d6ad855ce3417ef84e836892e5a56392bfba05fa5d97ccea30e266f540e08b3", + "scan_priv_key": "0f694e068028a717f8af6b9411f9a133dd3565258714cc226594b34db90c1f2c" + }, + "labels": [] + }, + "expected": { + "addresses": [ + "sp1qqgste7k9hx0qftg6qmwlkqtwuy6cycyavzmzj85c6qdfhjdpdjtdgqjuexzk6murw56suy3e0rd2cgqvycxttddwsvgxe2usfpxumr70xc9pkqwv" + ], + "outputs": [ + { + "priv_key_tweak": "ab0c9b87181bf527879f48db9f14a02233619b986f8e8f2d5d408ce68a709f51", + "pub_key": "f4c2da807f89cb1501f1a77322a895acfb93c28e08ed2724d2beb8e44539ba38", + "signature": "398a9790865791a9db41a8015afad3a47d60fec5086c50557806a49a1bc038808632b8fe679a7bb65fc6b455be994502eed849f1da3729cd948fc7be73d67295" + } + ] + } + } + ] + }, + { + "comment": "Outpoint ordering byte-lexicographically vs. vout-integer", + "sending": [ + { + "given": { + "vin": [ + { + "txid": "f4184fc596403b9d638783cf57adfe4c75c605f6356fbc91338530e9831e9e16", + "vout": 1, + "scriptSig": "483046022100ad79e6801dd9a8727f342f31c71c4912866f59dc6e7981878e92c5844a0ce929022100fb0d2393e813968648b9753b7e9871d90ab3d815ebf91820d704b19f4ed224d621025a1e61f898173040e20616d43e9f496fba90338a39faa1ed98fcbaeee4dd9be5", + "txinwitness": "", + "prevout": { + "scriptPubKey": { + "hex": "76a91419c2f3ae0ca3b642bd3e49598b8da89f50c1416188ac" + } + }, + "private_key": "eadc78165ff1f8ea94ad7cfdc54990738a4c53f6e0507b42154201b8e5dff3b1" + }, + { + "txid": "f4184fc596403b9d638783cf57adfe4c75c605f6356fbc91338530e9831e9e16", + "vout": 256, + "scriptSig": "48304602210086783ded73e961037e77d49d9deee4edc2b23136e9728d56e4491c80015c3a63022100fda4c0f21ea18de29edbce57f7134d613e044ee150a89e2e64700de2d4e83d4e2103bd85685d03d111699b15d046319febe77f8de5286e9e512703cdee1bf3be3792", + "txinwitness": "", + "prevout": { + "scriptPubKey": { + "hex": "76a914d9317c66f54ff0a152ec50b1d19c25be50c8e15988ac" + } + }, + "private_key": "93f5ed907ad5b2bdbbdcb5d9116ebc0a4e1f92f910d5260237fa45a9408aad16" + } + ], + "recipients": [ + "sp1qqgste7k9hx0qftg6qmwlkqtwuy6cycyavzmzj85c6qdfhjdpdjtdgqjuexzk6murw56suy3e0rd2cgqvycxttddwsvgxe2usfpxumr70xc9pkqwv" + ] + }, + "expected": { + "outputs": [ + [ + "a85ef8701394b517a4b35217c4bd37ac01ebeed4b008f8d0879f9e09ba95319c" + ] + ] + } + } + ], + "receiving": [ + { + "given": { + "vin": [ + { + "txid": "f4184fc596403b9d638783cf57adfe4c75c605f6356fbc91338530e9831e9e16", + "vout": 1, + "scriptSig": "483046022100ad79e6801dd9a8727f342f31c71c4912866f59dc6e7981878e92c5844a0ce929022100fb0d2393e813968648b9753b7e9871d90ab3d815ebf91820d704b19f4ed224d621025a1e61f898173040e20616d43e9f496fba90338a39faa1ed98fcbaeee4dd9be5", + "txinwitness": "", + "prevout": { + "scriptPubKey": { + "hex": "76a91419c2f3ae0ca3b642bd3e49598b8da89f50c1416188ac" + } + } + }, + { + "txid": "f4184fc596403b9d638783cf57adfe4c75c605f6356fbc91338530e9831e9e16", + "vout": 256, + "scriptSig": "48304602210086783ded73e961037e77d49d9deee4edc2b23136e9728d56e4491c80015c3a63022100fda4c0f21ea18de29edbce57f7134d613e044ee150a89e2e64700de2d4e83d4e2103bd85685d03d111699b15d046319febe77f8de5286e9e512703cdee1bf3be3792", + "txinwitness": "", + "prevout": { + "scriptPubKey": { + "hex": "76a914d9317c66f54ff0a152ec50b1d19c25be50c8e15988ac" + } + } + } + ], + "outputs": [ + "a85ef8701394b517a4b35217c4bd37ac01ebeed4b008f8d0879f9e09ba95319c" + ], + "key_material": { + "spend_priv_key": "9d6ad855ce3417ef84e836892e5a56392bfba05fa5d97ccea30e266f540e08b3", + "scan_priv_key": "0f694e068028a717f8af6b9411f9a133dd3565258714cc226594b34db90c1f2c" + }, + "labels": [] + }, + "expected": { + "addresses": [ + "sp1qqgste7k9hx0qftg6qmwlkqtwuy6cycyavzmzj85c6qdfhjdpdjtdgqjuexzk6murw56suy3e0rd2cgqvycxttddwsvgxe2usfpxumr70xc9pkqwv" + ], + "outputs": [ + { + "priv_key_tweak": "c8ac0292997b5bca98b3ebd99a57e253071137550f270452cd3df8a3e2266d36", + "pub_key": "a85ef8701394b517a4b35217c4bd37ac01ebeed4b008f8d0879f9e09ba95319c", + "signature": "c036ee38bfe46aba03234339ae7219b31b824b52ef9d5ce05810a0d6f62330dedc2b55652578aa5bdabf930fae941acd839d5a66f8fce7caa9710ccb446bddd1" + } + ] + } + } + ] + }, + { + "comment": "Single recipient: multiple UTXOs from the same public key", + "sending": [ + { + "given": { + "vin": [ + { + "txid": "f4184fc596403b9d638783cf57adfe4c75c605f6356fbc91338530e9831e9e16", + "vout": 0, + "scriptSig": "483046022100ad79e6801dd9a8727f342f31c71c4912866f59dc6e7981878e92c5844a0ce929022100fb0d2393e813968648b9753b7e9871d90ab3d815ebf91820d704b19f4ed224d621025a1e61f898173040e20616d43e9f496fba90338a39faa1ed98fcbaeee4dd9be5", + "txinwitness": "", + "prevout": { + "scriptPubKey": { + "hex": "76a91419c2f3ae0ca3b642bd3e49598b8da89f50c1416188ac" + } + }, + "private_key": "eadc78165ff1f8ea94ad7cfdc54990738a4c53f6e0507b42154201b8e5dff3b1" + }, + { + "txid": "a1075db55d416d3ca199f55b6084e2115b9345e16c5cf302fc80e9d5fbf5d48d", + "vout": 0, + "scriptSig": "483046022100ad79e6801dd9a8727f342f31c71c4912866f59dc6e7981878e92c5844a0ce929022100fb0d2393e813968648b9753b7e9871d90ab3d815ebf91820d704b19f4ed224d621025a1e61f898173040e20616d43e9f496fba90338a39faa1ed98fcbaeee4dd9be5", + "txinwitness": "", + "prevout": { + "scriptPubKey": { + "hex": "76a91419c2f3ae0ca3b642bd3e49598b8da89f50c1416188ac" + } + }, + "private_key": "eadc78165ff1f8ea94ad7cfdc54990738a4c53f6e0507b42154201b8e5dff3b1" + } + ], + "recipients": [ + "sp1qqgste7k9hx0qftg6qmwlkqtwuy6cycyavzmzj85c6qdfhjdpdjtdgqjuexzk6murw56suy3e0rd2cgqvycxttddwsvgxe2usfpxumr70xc9pkqwv" + ] + }, + "expected": { + "outputs": [ + [ + "548ae55c8eec1e736e8d3e520f011f1f42a56d166116ad210b3937599f87f566" + ] + ] + } + } + ], + "receiving": [ + { + "given": { + "vin": [ + { + "txid": "f4184fc596403b9d638783cf57adfe4c75c605f6356fbc91338530e9831e9e16", + "vout": 0, + "scriptSig": "483046022100ad79e6801dd9a8727f342f31c71c4912866f59dc6e7981878e92c5844a0ce929022100fb0d2393e813968648b9753b7e9871d90ab3d815ebf91820d704b19f4ed224d621025a1e61f898173040e20616d43e9f496fba90338a39faa1ed98fcbaeee4dd9be5", + "txinwitness": "", + "prevout": { + "scriptPubKey": { + "hex": "76a91419c2f3ae0ca3b642bd3e49598b8da89f50c1416188ac" + } + } + }, + { + "txid": "a1075db55d416d3ca199f55b6084e2115b9345e16c5cf302fc80e9d5fbf5d48d", + "vout": 0, + "scriptSig": "483046022100ad79e6801dd9a8727f342f31c71c4912866f59dc6e7981878e92c5844a0ce929022100fb0d2393e813968648b9753b7e9871d90ab3d815ebf91820d704b19f4ed224d621025a1e61f898173040e20616d43e9f496fba90338a39faa1ed98fcbaeee4dd9be5", + "txinwitness": "", + "prevout": { + "scriptPubKey": { + "hex": "76a91419c2f3ae0ca3b642bd3e49598b8da89f50c1416188ac" + } + } + } + ], + "outputs": [ + "548ae55c8eec1e736e8d3e520f011f1f42a56d166116ad210b3937599f87f566" + ], + "key_material": { + "spend_priv_key": "9d6ad855ce3417ef84e836892e5a56392bfba05fa5d97ccea30e266f540e08b3", + "scan_priv_key": "0f694e068028a717f8af6b9411f9a133dd3565258714cc226594b34db90c1f2c" + }, + "labels": [] + }, + "expected": { + "addresses": [ + "sp1qqgste7k9hx0qftg6qmwlkqtwuy6cycyavzmzj85c6qdfhjdpdjtdgqjuexzk6murw56suy3e0rd2cgqvycxttddwsvgxe2usfpxumr70xc9pkqwv" + ], + "outputs": [ + { + "priv_key_tweak": "f032695e2636619efa523fffaa9ef93c8802299181fd0461913c1b8daf9784cd", + "pub_key": "548ae55c8eec1e736e8d3e520f011f1f42a56d166116ad210b3937599f87f566", + "signature": "f238386c5d5e5444f8d2c75aabbcb28c346f208c76f60823f5de3b67b79e0ec72ea5de2d7caec314e0971d3454f122dda342b3eede01b3857e83654e36b25f76" + } + ] + } + } + ] + }, + { + "comment": "Single recipient: taproot only inputs with even y-values", + "sending": [ + { + "given": { + "vin": [ + { + "txid": "f4184fc596403b9d638783cf57adfe4c75c605f6356fbc91338530e9831e9e16", + "vout": 0, + "scriptSig": "", + "txinwitness": "0140c459b671370d12cfb5acee76da7e3ba7cc29b0b4653e3af8388591082660137d087fdc8e89a612cd5d15be0febe61fc7cdcf3161a26e599a4514aa5c3e86f47b", + "prevout": { + "scriptPubKey": { + "hex": "51205a1e61f898173040e20616d43e9f496fba90338a39faa1ed98fcbaeee4dd9be5" + } + }, + "private_key": "eadc78165ff1f8ea94ad7cfdc54990738a4c53f6e0507b42154201b8e5dff3b1" + }, + { + "txid": "a1075db55d416d3ca199f55b6084e2115b9345e16c5cf302fc80e9d5fbf5d48d", + "vout": 0, + "scriptSig": "", + "txinwitness": "0140bd1e708f92dbeaf24a6b8dd22e59c6274355424d62baea976b449e220fd75b13578e262ab11b7aa58e037f0c6b0519b66803b7d9decaa1906dedebfb531c56c1", + "prevout": { + "scriptPubKey": { + "hex": "5120782eeb913431ca6e9b8c2fd80a5f72ed2024ef72a3c6fb10263c379937323338" + } + }, + "private_key": "fc8716a97a48ba9a05a98ae47b5cd201a25a7fd5d8b73c203c5f7b6b6b3b6ad7" + } + ], + "recipients": [ + "sp1qqgste7k9hx0qftg6qmwlkqtwuy6cycyavzmzj85c6qdfhjdpdjtdgqjuexzk6murw56suy3e0rd2cgqvycxttddwsvgxe2usfpxumr70xc9pkqwv" + ] + }, + "expected": { + "outputs": [ + [ + "de88bea8e7ffc9ce1af30d1132f910323c505185aec8eae361670421e749a1fb" + ] + ] + } + } + ], + "receiving": [ + { + "given": { + "vin": [ + { + "txid": "f4184fc596403b9d638783cf57adfe4c75c605f6356fbc91338530e9831e9e16", + "vout": 0, + "scriptSig": "", + "txinwitness": "0140c459b671370d12cfb5acee76da7e3ba7cc29b0b4653e3af8388591082660137d087fdc8e89a612cd5d15be0febe61fc7cdcf3161a26e599a4514aa5c3e86f47b", + "prevout": { + "scriptPubKey": { + "hex": "51205a1e61f898173040e20616d43e9f496fba90338a39faa1ed98fcbaeee4dd9be5" + } + } + }, + { + "txid": "a1075db55d416d3ca199f55b6084e2115b9345e16c5cf302fc80e9d5fbf5d48d", + "vout": 0, + "scriptSig": "", + "txinwitness": "0140bd1e708f92dbeaf24a6b8dd22e59c6274355424d62baea976b449e220fd75b13578e262ab11b7aa58e037f0c6b0519b66803b7d9decaa1906dedebfb531c56c1", + "prevout": { + "scriptPubKey": { + "hex": "5120782eeb913431ca6e9b8c2fd80a5f72ed2024ef72a3c6fb10263c379937323338" + } + } + } + ], + "outputs": [ + "de88bea8e7ffc9ce1af30d1132f910323c505185aec8eae361670421e749a1fb" + ], + "key_material": { + "spend_priv_key": "9d6ad855ce3417ef84e836892e5a56392bfba05fa5d97ccea30e266f540e08b3", + "scan_priv_key": "0f694e068028a717f8af6b9411f9a133dd3565258714cc226594b34db90c1f2c" + }, + "labels": [] + }, + "expected": { + "addresses": [ + "sp1qqgste7k9hx0qftg6qmwlkqtwuy6cycyavzmzj85c6qdfhjdpdjtdgqjuexzk6murw56suy3e0rd2cgqvycxttddwsvgxe2usfpxumr70xc9pkqwv" + ], + "outputs": [ + { + "priv_key_tweak": "3fb9ce5ce1746ced103c8ed254e81f6690764637ddbc876ec1f9b3ddab776b03", + "pub_key": "de88bea8e7ffc9ce1af30d1132f910323c505185aec8eae361670421e749a1fb", + "signature": "c5acd25a8f021a4192f93bc34403fd8b76484613466336fb259c72d04c169824f2690ca34e96cee86b69f376c8377003268fda56feeb1b873e5783d7e19bcca5" + } + ] + } + } + ] + }, + { + "comment": "Single recipient: taproot only with mixed even/odd y-values", + "sending": [ + { + "given": { + "vin": [ + { + "txid": "f4184fc596403b9d638783cf57adfe4c75c605f6356fbc91338530e9831e9e16", + "vout": 0, + "scriptSig": "", + "txinwitness": "0140c459b671370d12cfb5acee76da7e3ba7cc29b0b4653e3af8388591082660137d087fdc8e89a612cd5d15be0febe61fc7cdcf3161a26e599a4514aa5c3e86f47b", + "prevout": { + "scriptPubKey": { + "hex": "51205a1e61f898173040e20616d43e9f496fba90338a39faa1ed98fcbaeee4dd9be5" + } + }, + "private_key": "eadc78165ff1f8ea94ad7cfdc54990738a4c53f6e0507b42154201b8e5dff3b1" + }, + { + "txid": "a1075db55d416d3ca199f55b6084e2115b9345e16c5cf302fc80e9d5fbf5d48d", + "vout": 0, + "scriptSig": "", + "txinwitness": "01400a4d0dca6293f40499394d7eefe14a1de11e0e3454f51de2e802592abf5ee549042a1b1a8fb2e149ee9dd3f086c1b69b2f182565ab6ecf599b1ec9ebadfda6c5", + "prevout": { + "scriptPubKey": { + "hex": "51208c8d23d4764feffcd5e72e380802540fa0f88e3d62ad5e0b47955f74d7b283c4" + } + }, + "private_key": "1d37787c2b7116ee983e9f9c13269df29091b391c04db94239e0d2bc2182c3bf" + } + ], + "recipients": [ + "sp1qqgste7k9hx0qftg6qmwlkqtwuy6cycyavzmzj85c6qdfhjdpdjtdgqjuexzk6murw56suy3e0rd2cgqvycxttddwsvgxe2usfpxumr70xc9pkqwv" + ] + }, + "expected": { + "outputs": [ + [ + "77cab7dd12b10259ee82c6ea4b509774e33e7078e7138f568092241bf26b99f1" + ] + ] + } + } + ], + "receiving": [ + { + "given": { + "vin": [ + { + "txid": "f4184fc596403b9d638783cf57adfe4c75c605f6356fbc91338530e9831e9e16", + "vout": 0, + "scriptSig": "", + "txinwitness": "0140c459b671370d12cfb5acee76da7e3ba7cc29b0b4653e3af8388591082660137d087fdc8e89a612cd5d15be0febe61fc7cdcf3161a26e599a4514aa5c3e86f47b", + "prevout": { + "scriptPubKey": { + "hex": "51205a1e61f898173040e20616d43e9f496fba90338a39faa1ed98fcbaeee4dd9be5" + } + } + }, + { + "txid": "a1075db55d416d3ca199f55b6084e2115b9345e16c5cf302fc80e9d5fbf5d48d", + "vout": 0, + "scriptSig": "", + "txinwitness": "01400a4d0dca6293f40499394d7eefe14a1de11e0e3454f51de2e802592abf5ee549042a1b1a8fb2e149ee9dd3f086c1b69b2f182565ab6ecf599b1ec9ebadfda6c5", + "prevout": { + "scriptPubKey": { + "hex": "51208c8d23d4764feffcd5e72e380802540fa0f88e3d62ad5e0b47955f74d7b283c4" + } + } + } + ], + "outputs": [ + "77cab7dd12b10259ee82c6ea4b509774e33e7078e7138f568092241bf26b99f1" + ], + "key_material": { + "spend_priv_key": "9d6ad855ce3417ef84e836892e5a56392bfba05fa5d97ccea30e266f540e08b3", + "scan_priv_key": "0f694e068028a717f8af6b9411f9a133dd3565258714cc226594b34db90c1f2c" + }, + "labels": [] + }, + "expected": { + "addresses": [ + "sp1qqgste7k9hx0qftg6qmwlkqtwuy6cycyavzmzj85c6qdfhjdpdjtdgqjuexzk6murw56suy3e0rd2cgqvycxttddwsvgxe2usfpxumr70xc9pkqwv" + ], + "outputs": [ + { + "priv_key_tweak": "f5382508609771068ed079b24e1f72e4a17ee6d1c979066bf1d4e2a5676f09d4", + "pub_key": "77cab7dd12b10259ee82c6ea4b509774e33e7078e7138f568092241bf26b99f1", + "signature": "ff65833b8fd1ed3ef9d0443b4f702b45a3f2dd457ba247687e8207745c3be9d2bdad0ab3f07118f8b2efc6a04b95f7b3e218daf8a64137ec91bd2fc67fc137a5" + } + ] + } + } + ] + }, + { + "comment": "Single recipient: taproot input with even y-value and non-taproot input", + "sending": [ + { + "given": { + "vin": [ + { + "txid": "f4184fc596403b9d638783cf57adfe4c75c605f6356fbc91338530e9831e9e16", + "vout": 0, + "scriptSig": "", + "txinwitness": "0140c459b671370d12cfb5acee76da7e3ba7cc29b0b4653e3af8388591082660137d087fdc8e89a612cd5d15be0febe61fc7cdcf3161a26e599a4514aa5c3e86f47b", + "prevout": { + "scriptPubKey": { + "hex": "51205a1e61f898173040e20616d43e9f496fba90338a39faa1ed98fcbaeee4dd9be5" + } + }, + "private_key": "eadc78165ff1f8ea94ad7cfdc54990738a4c53f6e0507b42154201b8e5dff3b1" + }, + { + "txid": "a1075db55d416d3ca199f55b6084e2115b9345e16c5cf302fc80e9d5fbf5d48d", + "vout": 0, + "scriptSig": "463044021f24e010c6e475814740ba24c8cf9362c4db1276b7f46a7b1e63473159a80ec30221008198e8ece7b7f88e6c6cc6bb8c86f9f00b7458222a8c91addf6e1577bcf7697e2103e0ec4f64b3fa2e463ccfcf4e856e37d5e1e20275bc89ec1def9eb098eff1f85d", + "txinwitness": "", + "prevout": { + "scriptPubKey": { + "hex": "76a9148cbc7dfe44f1579bff3340bbef1eddeaeb1fc97788ac" + } + }, + "private_key": "8d4751f6e8a3586880fb66c19ae277969bd5aa06f61c4ee2f1e2486efdf666d3" + } + ], + "recipients": [ + "sp1qqgste7k9hx0qftg6qmwlkqtwuy6cycyavzmzj85c6qdfhjdpdjtdgqjuexzk6murw56suy3e0rd2cgqvycxttddwsvgxe2usfpxumr70xc9pkqwv" + ] + }, + "expected": { + "outputs": [ + [ + "30523cca96b2a9ae3c98beb5e60f7d190ec5bc79b2d11a0b2d4d09a608c448f0" + ] + ] + } + } + ], + "receiving": [ + { + "given": { + "vin": [ + { + "txid": "f4184fc596403b9d638783cf57adfe4c75c605f6356fbc91338530e9831e9e16", + "vout": 0, + "scriptSig": "", + "txinwitness": "0140c459b671370d12cfb5acee76da7e3ba7cc29b0b4653e3af8388591082660137d087fdc8e89a612cd5d15be0febe61fc7cdcf3161a26e599a4514aa5c3e86f47b", + "prevout": { + "scriptPubKey": { + "hex": "51205a1e61f898173040e20616d43e9f496fba90338a39faa1ed98fcbaeee4dd9be5" + } + } + }, + { + "txid": "a1075db55d416d3ca199f55b6084e2115b9345e16c5cf302fc80e9d5fbf5d48d", + "vout": 0, + "scriptSig": "463044021f24e010c6e475814740ba24c8cf9362c4db1276b7f46a7b1e63473159a80ec30221008198e8ece7b7f88e6c6cc6bb8c86f9f00b7458222a8c91addf6e1577bcf7697e2103e0ec4f64b3fa2e463ccfcf4e856e37d5e1e20275bc89ec1def9eb098eff1f85d", + "txinwitness": "", + "prevout": { + "scriptPubKey": { + "hex": "76a9148cbc7dfe44f1579bff3340bbef1eddeaeb1fc97788ac" + } + } + } + ], + "outputs": [ + "30523cca96b2a9ae3c98beb5e60f7d190ec5bc79b2d11a0b2d4d09a608c448f0" + ], + "key_material": { + "spend_priv_key": "9d6ad855ce3417ef84e836892e5a56392bfba05fa5d97ccea30e266f540e08b3", + "scan_priv_key": "0f694e068028a717f8af6b9411f9a133dd3565258714cc226594b34db90c1f2c" + }, + "labels": [] + }, + "expected": { + "addresses": [ + "sp1qqgste7k9hx0qftg6qmwlkqtwuy6cycyavzmzj85c6qdfhjdpdjtdgqjuexzk6murw56suy3e0rd2cgqvycxttddwsvgxe2usfpxumr70xc9pkqwv" + ], + "outputs": [ + { + "priv_key_tweak": "b40017865c79b1fcbed68896791be93186d08f47e416b289b8c063777e14e8df", + "pub_key": "30523cca96b2a9ae3c98beb5e60f7d190ec5bc79b2d11a0b2d4d09a608c448f0", + "signature": "d1edeea28cf1033bcb3d89376cabaaaa2886cbd8fda112b5c61cc90a4e7f1878bdd62180b07d1dfc8ffee1863c525a0c7b5bcd413183282cfda756cb65787266" + } + ] + } + } + ] + }, + { + "comment": "Single recipient: taproot input with odd y-value and non-taproot input", + "sending": [ + { + "given": { + "vin": [ + { + "txid": "f4184fc596403b9d638783cf57adfe4c75c605f6356fbc91338530e9831e9e16", + "vout": 0, + "scriptSig": "", + "txinwitness": "01400a4d0dca6293f40499394d7eefe14a1de11e0e3454f51de2e802592abf5ee549042a1b1a8fb2e149ee9dd3f086c1b69b2f182565ab6ecf599b1ec9ebadfda6c5", + "prevout": { + "scriptPubKey": { + "hex": "51208c8d23d4764feffcd5e72e380802540fa0f88e3d62ad5e0b47955f74d7b283c4" + } + }, + "private_key": "1d37787c2b7116ee983e9f9c13269df29091b391c04db94239e0d2bc2182c3bf" + }, + { + "txid": "a1075db55d416d3ca199f55b6084e2115b9345e16c5cf302fc80e9d5fbf5d48d", + "vout": 0, + "scriptSig": "463044021f24e010c6e475814740ba24c8cf9362c4db1276b7f46a7b1e63473159a80ec30221008198e8ece7b7f88e6c6cc6bb8c86f9f00b7458222a8c91addf6e1577bcf7697e2103e0ec4f64b3fa2e463ccfcf4e856e37d5e1e20275bc89ec1def9eb098eff1f85d", + "txinwitness": "", + "prevout": { + "scriptPubKey": { + "hex": "76a9148cbc7dfe44f1579bff3340bbef1eddeaeb1fc97788ac" + } + }, + "private_key": "8d4751f6e8a3586880fb66c19ae277969bd5aa06f61c4ee2f1e2486efdf666d3" + } + ], + "recipients": [ + "sp1qqgste7k9hx0qftg6qmwlkqtwuy6cycyavzmzj85c6qdfhjdpdjtdgqjuexzk6murw56suy3e0rd2cgqvycxttddwsvgxe2usfpxumr70xc9pkqwv" + ] + }, + "expected": { + "outputs": [ + [ + "359358f59ee9e9eec3f00bdf4882570fd5c182e451aa2650b788544aff012a3a" + ] + ] + } + } + ], + "receiving": [ + { + "given": { + "vin": [ + { + "txid": "f4184fc596403b9d638783cf57adfe4c75c605f6356fbc91338530e9831e9e16", + "vout": 0, + "scriptSig": "", + "txinwitness": "01400a4d0dca6293f40499394d7eefe14a1de11e0e3454f51de2e802592abf5ee549042a1b1a8fb2e149ee9dd3f086c1b69b2f182565ab6ecf599b1ec9ebadfda6c5", + "prevout": { + "scriptPubKey": { + "hex": "51208c8d23d4764feffcd5e72e380802540fa0f88e3d62ad5e0b47955f74d7b283c4" + } + } + }, + { + "txid": "a1075db55d416d3ca199f55b6084e2115b9345e16c5cf302fc80e9d5fbf5d48d", + "vout": 0, + "scriptSig": "463044021f24e010c6e475814740ba24c8cf9362c4db1276b7f46a7b1e63473159a80ec30221008198e8ece7b7f88e6c6cc6bb8c86f9f00b7458222a8c91addf6e1577bcf7697e2103e0ec4f64b3fa2e463ccfcf4e856e37d5e1e20275bc89ec1def9eb098eff1f85d", + "txinwitness": "", + "prevout": { + "scriptPubKey": { + "hex": "76a9148cbc7dfe44f1579bff3340bbef1eddeaeb1fc97788ac" + } + } + } + ], + "outputs": [ + "359358f59ee9e9eec3f00bdf4882570fd5c182e451aa2650b788544aff012a3a" + ], + "key_material": { + "spend_priv_key": "9d6ad855ce3417ef84e836892e5a56392bfba05fa5d97ccea30e266f540e08b3", + "scan_priv_key": "0f694e068028a717f8af6b9411f9a133dd3565258714cc226594b34db90c1f2c" + }, + "labels": [] + }, + "expected": { + "addresses": [ + "sp1qqgste7k9hx0qftg6qmwlkqtwuy6cycyavzmzj85c6qdfhjdpdjtdgqjuexzk6murw56suy3e0rd2cgqvycxttddwsvgxe2usfpxumr70xc9pkqwv" + ], + "outputs": [ + { + "priv_key_tweak": "a2f9dd05d1d398347c885d9c61a64d18a264de6d49cea4326bafc2791d627fa7", + "pub_key": "359358f59ee9e9eec3f00bdf4882570fd5c182e451aa2650b788544aff012a3a", + "signature": "96038ad233d8befe342573a6e54828d863471fb2afbad575cc65271a2a649480ea14912b6abbd3fbf92efc1928c036f6e3eef927105af4ec1dd57cb909f360b8" + } + ] + } + } + ] + }, + { + "comment": "Multiple outputs: multiple outputs, same recipient", + "sending": [ + { + "given": { + "vin": [ + { + "txid": "f4184fc596403b9d638783cf57adfe4c75c605f6356fbc91338530e9831e9e16", + "vout": 0, + "scriptSig": "483046022100ad79e6801dd9a8727f342f31c71c4912866f59dc6e7981878e92c5844a0ce929022100fb0d2393e813968648b9753b7e9871d90ab3d815ebf91820d704b19f4ed224d621025a1e61f898173040e20616d43e9f496fba90338a39faa1ed98fcbaeee4dd9be5", + "txinwitness": "", + "prevout": { + "scriptPubKey": { + "hex": "76a91419c2f3ae0ca3b642bd3e49598b8da89f50c1416188ac" + } + }, + "private_key": "eadc78165ff1f8ea94ad7cfdc54990738a4c53f6e0507b42154201b8e5dff3b1" + }, + { + "txid": "a1075db55d416d3ca199f55b6084e2115b9345e16c5cf302fc80e9d5fbf5d48d", + "vout": 0, + "scriptSig": "473045022100a8c61b2d470e393279d1ba54f254b7c237de299580b7fa01ffcc940442ecec4502201afba952f4e4661c40acde7acc0341589031ba103a307b886eb867b23b850b972103782eeb913431ca6e9b8c2fd80a5f72ed2024ef72a3c6fb10263c379937323338", + "txinwitness": "", + "prevout": { + "scriptPubKey": { + "hex": "76a9147cdd63cc408564188e8e472640e921c7c90e651d88ac" + } + }, + "private_key": "0378e95685b74565fa56751b84a32dfd18545d10d691641b8372e32164fad66a" + } + ], + "recipients": [ + "sp1qqgste7k9hx0qftg6qmwlkqtwuy6cycyavzmzj85c6qdfhjdpdjtdgqjuexzk6murw56suy3e0rd2cgqvycxttddwsvgxe2usfpxumr70xc9pkqwv", + "sp1qqgste7k9hx0qftg6qmwlkqtwuy6cycyavzmzj85c6qdfhjdpdjtdgqjuexzk6murw56suy3e0rd2cgqvycxttddwsvgxe2usfpxumr70xc9pkqwv" + ] + }, + "expected": { + "outputs": [ + [ + "e976a58fbd38aeb4e6093d4df02e9c1de0c4513ae0c588cef68cda5b2f8834ca", + "f207162b1a7abc51c42017bef055e9ec1efc3d3567cb720357e2b84325db33ac" + ] + ] + } + } + ], + "receiving": [ + { + "given": { + "vin": [ + { + "txid": "f4184fc596403b9d638783cf57adfe4c75c605f6356fbc91338530e9831e9e16", + "vout": 0, + "scriptSig": "483046022100ad79e6801dd9a8727f342f31c71c4912866f59dc6e7981878e92c5844a0ce929022100fb0d2393e813968648b9753b7e9871d90ab3d815ebf91820d704b19f4ed224d621025a1e61f898173040e20616d43e9f496fba90338a39faa1ed98fcbaeee4dd9be5", + "txinwitness": "", + "prevout": { + "scriptPubKey": { + "hex": "76a91419c2f3ae0ca3b642bd3e49598b8da89f50c1416188ac" + } + } + }, + { + "txid": "a1075db55d416d3ca199f55b6084e2115b9345e16c5cf302fc80e9d5fbf5d48d", + "vout": 0, + "scriptSig": "473045022100a8c61b2d470e393279d1ba54f254b7c237de299580b7fa01ffcc940442ecec4502201afba952f4e4661c40acde7acc0341589031ba103a307b886eb867b23b850b972103782eeb913431ca6e9b8c2fd80a5f72ed2024ef72a3c6fb10263c379937323338", + "txinwitness": "", + "prevout": { + "scriptPubKey": { + "hex": "76a9147cdd63cc408564188e8e472640e921c7c90e651d88ac" + } + } + } + ], + "outputs": [ + "e976a58fbd38aeb4e6093d4df02e9c1de0c4513ae0c588cef68cda5b2f8834ca", + "f207162b1a7abc51c42017bef055e9ec1efc3d3567cb720357e2b84325db33ac" + ], + "key_material": { + "spend_priv_key": "9d6ad855ce3417ef84e836892e5a56392bfba05fa5d97ccea30e266f540e08b3", + "scan_priv_key": "0f694e068028a717f8af6b9411f9a133dd3565258714cc226594b34db90c1f2c" + }, + "labels": [] + }, + "expected": { + "addresses": [ + "sp1qqgste7k9hx0qftg6qmwlkqtwuy6cycyavzmzj85c6qdfhjdpdjtdgqjuexzk6murw56suy3e0rd2cgqvycxttddwsvgxe2usfpxumr70xc9pkqwv" + ], + "outputs": [ + { + "priv_key_tweak": "d97e442d110c0bdd31161a7bb6e7862e038d02a09b1484dfbb463f2e0f7c9230", + "pub_key": "e976a58fbd38aeb4e6093d4df02e9c1de0c4513ae0c588cef68cda5b2f8834ca", + "signature": "29bd25d0f808d7fcd2aa6d5ed206053899198397506c301b218a9e47a3d7070af03e903ff718978d50d1b6b9af8cc0e313d84eda5d5b1e8e85e5516d630bbeb9" + }, + { + "priv_key_tweak": "33ce085c3c11eaad13694aae3c20301a6c83382ec89a7cde96c6799e2f88805a", + "pub_key": "f207162b1a7abc51c42017bef055e9ec1efc3d3567cb720357e2b84325db33ac", + "signature": "335667ca6cae7a26438f5cfdd73b3d48fa832fa9768521d7d5445f22c203ab0d74ed85088f27d29959ba627a4509996676f47df8ff284d292567b1beef0e3912" + } + ] + } + } + ] + }, + { + "comment": "Multiple outputs: multiple outputs, multiple recipients", + "sending": [ + { + "given": { + "vin": [ + { + "txid": "f4184fc596403b9d638783cf57adfe4c75c605f6356fbc91338530e9831e9e16", + "vout": 0, + "scriptSig": "483046022100ad79e6801dd9a8727f342f31c71c4912866f59dc6e7981878e92c5844a0ce929022100fb0d2393e813968648b9753b7e9871d90ab3d815ebf91820d704b19f4ed224d621025a1e61f898173040e20616d43e9f496fba90338a39faa1ed98fcbaeee4dd9be5", + "txinwitness": "", + "prevout": { + "scriptPubKey": { + "hex": "76a91419c2f3ae0ca3b642bd3e49598b8da89f50c1416188ac" + } + }, + "private_key": "eadc78165ff1f8ea94ad7cfdc54990738a4c53f6e0507b42154201b8e5dff3b1" + }, + { + "txid": "a1075db55d416d3ca199f55b6084e2115b9345e16c5cf302fc80e9d5fbf5d48d", + "vout": 0, + "scriptSig": "473045022100a8c61b2d470e393279d1ba54f254b7c237de299580b7fa01ffcc940442ecec4502201afba952f4e4661c40acde7acc0341589031ba103a307b886eb867b23b850b972103782eeb913431ca6e9b8c2fd80a5f72ed2024ef72a3c6fb10263c379937323338", + "txinwitness": "", + "prevout": { + "scriptPubKey": { + "hex": "76a9147cdd63cc408564188e8e472640e921c7c90e651d88ac" + } + }, + "private_key": "0378e95685b74565fa56751b84a32dfd18545d10d691641b8372e32164fad66a" + } + ], + "recipients": [ + "sp1qqgste7k9hx0qftg6qmwlkqtwuy6cycyavzmzj85c6qdfhjdpdjtdgqjuexzk6murw56suy3e0rd2cgqvycxttddwsvgxe2usfpxumr70xc9pkqwv", + "sp1qqgrz6j0lcqnc04vxccydl0kpsj4frfje0ktmgcl2t346hkw30226xqupawdf48k8882j0strrvcmgg2kdawz53a54dd376ngdhak364hzcmynqtn", + "sp1qqgrz6j0lcqnc04vxccydl0kpsj4frfje0ktmgcl2t346hkw30226xqupawdf48k8882j0strrvcmgg2kdawz53a54dd376ngdhak364hzcmynqtn" + ] + }, + "expected": { + "outputs": [ + [ + "2e847bb01d1b491da512ddd760b8509617ee38057003d6115d00ba562451323a", + "841792c33c9dc6193e76744134125d40add8f2f4a96475f28ba150be032d64e8", + "f207162b1a7abc51c42017bef055e9ec1efc3d3567cb720357e2b84325db33ac" + ] + ] + } + } + ], + "receiving": [ + { + "given": { + "vin": [ + { + "txid": "f4184fc596403b9d638783cf57adfe4c75c605f6356fbc91338530e9831e9e16", + "vout": 0, + "scriptSig": "483046022100ad79e6801dd9a8727f342f31c71c4912866f59dc6e7981878e92c5844a0ce929022100fb0d2393e813968648b9753b7e9871d90ab3d815ebf91820d704b19f4ed224d621025a1e61f898173040e20616d43e9f496fba90338a39faa1ed98fcbaeee4dd9be5", + "txinwitness": "", + "prevout": { + "scriptPubKey": { + "hex": "76a91419c2f3ae0ca3b642bd3e49598b8da89f50c1416188ac" + } + } + }, + { + "txid": "a1075db55d416d3ca199f55b6084e2115b9345e16c5cf302fc80e9d5fbf5d48d", + "vout": 0, + "scriptSig": "473045022100a8c61b2d470e393279d1ba54f254b7c237de299580b7fa01ffcc940442ecec4502201afba952f4e4661c40acde7acc0341589031ba103a307b886eb867b23b850b972103782eeb913431ca6e9b8c2fd80a5f72ed2024ef72a3c6fb10263c379937323338", + "txinwitness": "", + "prevout": { + "scriptPubKey": { + "hex": "76a9147cdd63cc408564188e8e472640e921c7c90e651d88ac" + } + } + } + ], + "outputs": [ + "2e847bb01d1b491da512ddd760b8509617ee38057003d6115d00ba562451323a", + "841792c33c9dc6193e76744134125d40add8f2f4a96475f28ba150be032d64e8", + "f207162b1a7abc51c42017bef055e9ec1efc3d3567cb720357e2b84325db33ac" + ], + "key_material": { + "spend_priv_key": "9902c3c56e84002a7cd410113a9ab21d142be7f53cf5200720bb01314c5eb920", + "scan_priv_key": "060b751d7892149006ed7b98606955a29fe284a1e900070c0971f5fb93dbf422" + }, + "labels": [] + }, + "expected": { + "addresses": [ + "sp1qqgrz6j0lcqnc04vxccydl0kpsj4frfje0ktmgcl2t346hkw30226xqupawdf48k8882j0strrvcmgg2kdawz53a54dd376ngdhak364hzcmynqtn" + ], + "outputs": [ + { + "priv_key_tweak": "72cd082cccb633bf85240a83494b32dc943a4d05647a6686d23ad4ca59c0ebe4", + "pub_key": "2e847bb01d1b491da512ddd760b8509617ee38057003d6115d00ba562451323a", + "signature": "38745f3d9f5eef0b1cfb17ca314efa8c521efab28a23aa20ec5e3abb561d42804d539906dce60c4ee7977966184e6f2cab1faa0e5377ceb7148ec5218b4e7878" + }, + { + "priv_key_tweak": "2f17ea873a0047fc01ba8010fef0969e76d0e4283f600d48f735098b1fee6eb9", + "pub_key": "841792c33c9dc6193e76744134125d40add8f2f4a96475f28ba150be032d64e8", + "signature": "c26f4e3cf371b90b840f48ea0e761b5ec31883ed55719f9ef06a90e282d85f565790ab780a3f491bc2668cc64e944dca849d1022a878cdadb8d168b8da4a6da3" + } + ] + } + } + ] + }, + { + "comment": "Receiving with labels: label with even parity", + "sending": [ + { + "given": { + "vin": [ + { + "txid": "f4184fc596403b9d638783cf57adfe4c75c605f6356fbc91338530e9831e9e16", + "vout": 0, + "scriptSig": "483046022100ad79e6801dd9a8727f342f31c71c4912866f59dc6e7981878e92c5844a0ce929022100fb0d2393e813968648b9753b7e9871d90ab3d815ebf91820d704b19f4ed224d621025a1e61f898173040e20616d43e9f496fba90338a39faa1ed98fcbaeee4dd9be5", + "txinwitness": "", + "prevout": { + "scriptPubKey": { + "hex": "76a91419c2f3ae0ca3b642bd3e49598b8da89f50c1416188ac" + } + }, + "private_key": "eadc78165ff1f8ea94ad7cfdc54990738a4c53f6e0507b42154201b8e5dff3b1" + }, + { + "txid": "a1075db55d416d3ca199f55b6084e2115b9345e16c5cf302fc80e9d5fbf5d48d", + "vout": 0, + "scriptSig": "473045022100a8c61b2d470e393279d1ba54f254b7c237de299580b7fa01ffcc940442ecec4502201afba952f4e4661c40acde7acc0341589031ba103a307b886eb867b23b850b972103782eeb913431ca6e9b8c2fd80a5f72ed2024ef72a3c6fb10263c379937323338", + "txinwitness": "", + "prevout": { + "scriptPubKey": { + "hex": "76a9147cdd63cc408564188e8e472640e921c7c90e651d88ac" + } + }, + "private_key": "0378e95685b74565fa56751b84a32dfd18545d10d691641b8372e32164fad66a" + } + ], + "recipients": [ + "sp1qqgste7k9hx0qftg6qmwlkqtwuy6cycyavzmzj85c6qdfhjdpdjtdgqjex54dmqmmv6rw353tsuqhs99ydvadxzrsy9nuvk74epvee55drs734pqq" + ] + }, + "expected": { + "outputs": [ + [ + "d014d4860f67d607d60b1af70e0ee236b99658b61bb769832acbbe87c374439a" + ] + ] + } + } + ], + "receiving": [ + { + "given": { + "vin": [ + { + "txid": "f4184fc596403b9d638783cf57adfe4c75c605f6356fbc91338530e9831e9e16", + "vout": 0, + "scriptSig": "483046022100ad79e6801dd9a8727f342f31c71c4912866f59dc6e7981878e92c5844a0ce929022100fb0d2393e813968648b9753b7e9871d90ab3d815ebf91820d704b19f4ed224d621025a1e61f898173040e20616d43e9f496fba90338a39faa1ed98fcbaeee4dd9be5", + "txinwitness": "", + "prevout": { + "scriptPubKey": { + "hex": "76a91419c2f3ae0ca3b642bd3e49598b8da89f50c1416188ac" + } + } + }, + { + "txid": "a1075db55d416d3ca199f55b6084e2115b9345e16c5cf302fc80e9d5fbf5d48d", + "vout": 0, + "scriptSig": "473045022100a8c61b2d470e393279d1ba54f254b7c237de299580b7fa01ffcc940442ecec4502201afba952f4e4661c40acde7acc0341589031ba103a307b886eb867b23b850b972103782eeb913431ca6e9b8c2fd80a5f72ed2024ef72a3c6fb10263c379937323338", + "txinwitness": "", + "prevout": { + "scriptPubKey": { + "hex": "76a9147cdd63cc408564188e8e472640e921c7c90e651d88ac" + } + } + } + ], + "outputs": [ + "d014d4860f67d607d60b1af70e0ee236b99658b61bb769832acbbe87c374439a" + ], + "key_material": { + "spend_priv_key": "9d6ad855ce3417ef84e836892e5a56392bfba05fa5d97ccea30e266f540e08b3", + "scan_priv_key": "0f694e068028a717f8af6b9411f9a133dd3565258714cc226594b34db90c1f2c" + }, + "labels": [ + 2, + 3, + 1001337 + ] + }, + "expected": { + "addresses": [ + "sp1qqgste7k9hx0qftg6qmwlkqtwuy6cycyavzmzj85c6qdfhjdpdjtdgqjuexzk6murw56suy3e0rd2cgqvycxttddwsvgxe2usfpxumr70xc9pkqwv", + "sp1qqgste7k9hx0qftg6qmwlkqtwuy6cycyavzmzj85c6qdfhjdpdjtdgqjex54dmqmmv6rw353tsuqhs99ydvadxzrsy9nuvk74epvee55drs734pqq", + "sp1qqgste7k9hx0qftg6qmwlkqtwuy6cycyavzmzj85c6qdfhjdpdjtdgqsg59z2rppn4qlkx0yz9sdltmjv3j8zgcqadjn4ug98m3t6plujsq9qvu5n", + "sp1qqgste7k9hx0qftg6qmwlkqtwuy6cycyavzmzj85c6qdfhjdpdjtdgq7c2zfthc6x3a5yecwc52nxa0kfd20xuz08zyrjpfw4l2j257yq6qgnkdh5" + ], + "outputs": [ + { + "priv_key_tweak": "51d4e9d0d482b5700109b4b2e16ff508269b03d800192a043d61dca4a0a72a52", + "pub_key": "d014d4860f67d607d60b1af70e0ee236b99658b61bb769832acbbe87c374439a", + "signature": "c30fa63bad6f0a317f39a773a5cbf0b0f8193c71dfebba05ee6ae4ed28e3775e6e04c3ea70a83703bb888122855dc894cab61692e7fd10c9b3494d479a60785e" + } + ] + } + } + ] + }, + { + "comment": "Receiving with labels: label with odd parity", + "sending": [ + { + "given": { + "vin": [ + { + "txid": "f4184fc596403b9d638783cf57adfe4c75c605f6356fbc91338530e9831e9e16", + "vout": 0, + "scriptSig": "483046022100ad79e6801dd9a8727f342f31c71c4912866f59dc6e7981878e92c5844a0ce929022100fb0d2393e813968648b9753b7e9871d90ab3d815ebf91820d704b19f4ed224d621025a1e61f898173040e20616d43e9f496fba90338a39faa1ed98fcbaeee4dd9be5", + "txinwitness": "", + "prevout": { + "scriptPubKey": { + "hex": "76a91419c2f3ae0ca3b642bd3e49598b8da89f50c1416188ac" + } + }, + "private_key": "eadc78165ff1f8ea94ad7cfdc54990738a4c53f6e0507b42154201b8e5dff3b1" + }, + { + "txid": "a1075db55d416d3ca199f55b6084e2115b9345e16c5cf302fc80e9d5fbf5d48d", + "vout": 0, + "scriptSig": "473045022100a8c61b2d470e393279d1ba54f254b7c237de299580b7fa01ffcc940442ecec4502201afba952f4e4661c40acde7acc0341589031ba103a307b886eb867b23b850b972103782eeb913431ca6e9b8c2fd80a5f72ed2024ef72a3c6fb10263c379937323338", + "txinwitness": "", + "prevout": { + "scriptPubKey": { + "hex": "76a9147cdd63cc408564188e8e472640e921c7c90e651d88ac" + } + }, + "private_key": "0378e95685b74565fa56751b84a32dfd18545d10d691641b8372e32164fad66a" + } + ], + "recipients": [ + "sp1qqgste7k9hx0qftg6qmwlkqtwuy6cycyavzmzj85c6qdfhjdpdjtdgqsg59z2rppn4qlkx0yz9sdltmjv3j8zgcqadjn4ug98m3t6plujsq9qvu5n" + ] + }, + "expected": { + "outputs": [ + [ + "67626aebb3c4307cf0f6c39ca23247598fabf675ab783292eb2f81ae75ad1f8c" + ] + ] + } + } + ], + "receiving": [ + { + "given": { + "vin": [ + { + "txid": "f4184fc596403b9d638783cf57adfe4c75c605f6356fbc91338530e9831e9e16", + "vout": 0, + "scriptSig": "483046022100ad79e6801dd9a8727f342f31c71c4912866f59dc6e7981878e92c5844a0ce929022100fb0d2393e813968648b9753b7e9871d90ab3d815ebf91820d704b19f4ed224d621025a1e61f898173040e20616d43e9f496fba90338a39faa1ed98fcbaeee4dd9be5", + "txinwitness": "", + "prevout": { + "scriptPubKey": { + "hex": "76a91419c2f3ae0ca3b642bd3e49598b8da89f50c1416188ac" + } + } + }, + { + "txid": "a1075db55d416d3ca199f55b6084e2115b9345e16c5cf302fc80e9d5fbf5d48d", + "vout": 0, + "scriptSig": "473045022100a8c61b2d470e393279d1ba54f254b7c237de299580b7fa01ffcc940442ecec4502201afba952f4e4661c40acde7acc0341589031ba103a307b886eb867b23b850b972103782eeb913431ca6e9b8c2fd80a5f72ed2024ef72a3c6fb10263c379937323338", + "txinwitness": "", + "prevout": { + "scriptPubKey": { + "hex": "76a9147cdd63cc408564188e8e472640e921c7c90e651d88ac" + } + } + } + ], + "outputs": [ + "67626aebb3c4307cf0f6c39ca23247598fabf675ab783292eb2f81ae75ad1f8c" + ], + "key_material": { + "spend_priv_key": "9d6ad855ce3417ef84e836892e5a56392bfba05fa5d97ccea30e266f540e08b3", + "scan_priv_key": "0f694e068028a717f8af6b9411f9a133dd3565258714cc226594b34db90c1f2c" + }, + "labels": [ + 2, + 3, + 1001337 + ] + }, + "expected": { + "addresses": [ + "sp1qqgste7k9hx0qftg6qmwlkqtwuy6cycyavzmzj85c6qdfhjdpdjtdgqjuexzk6murw56suy3e0rd2cgqvycxttddwsvgxe2usfpxumr70xc9pkqwv", + "sp1qqgste7k9hx0qftg6qmwlkqtwuy6cycyavzmzj85c6qdfhjdpdjtdgqjex54dmqmmv6rw353tsuqhs99ydvadxzrsy9nuvk74epvee55drs734pqq", + "sp1qqgste7k9hx0qftg6qmwlkqtwuy6cycyavzmzj85c6qdfhjdpdjtdgqsg59z2rppn4qlkx0yz9sdltmjv3j8zgcqadjn4ug98m3t6plujsq9qvu5n", + "sp1qqgste7k9hx0qftg6qmwlkqtwuy6cycyavzmzj85c6qdfhjdpdjtdgq7c2zfthc6x3a5yecwc52nxa0kfd20xuz08zyrjpfw4l2j257yq6qgnkdh5" + ], + "outputs": [ + { + "priv_key_tweak": "6024ae214876356b8d917716e7707d267ae16a0fdb07de2a786b74a7bbcddead", + "pub_key": "67626aebb3c4307cf0f6c39ca23247598fabf675ab783292eb2f81ae75ad1f8c", + "signature": "a86d554d0d6b7aa0907155f7e0b47f0182752472fffaeddd68da90e99b9402f166fd9b33039c302c7115098d971c1399e67c19e9e4de180b10ea0b9d6f0db832" + } + ] + } + } + ] + }, + { + "comment": "Receiving with labels: large label integer", + "sending": [ + { + "given": { + "vin": [ + { + "txid": "f4184fc596403b9d638783cf57adfe4c75c605f6356fbc91338530e9831e9e16", + "vout": 0, + "scriptSig": "483046022100ad79e6801dd9a8727f342f31c71c4912866f59dc6e7981878e92c5844a0ce929022100fb0d2393e813968648b9753b7e9871d90ab3d815ebf91820d704b19f4ed224d621025a1e61f898173040e20616d43e9f496fba90338a39faa1ed98fcbaeee4dd9be5", + "txinwitness": "", + "prevout": { + "scriptPubKey": { + "hex": "76a91419c2f3ae0ca3b642bd3e49598b8da89f50c1416188ac" + } + }, + "private_key": "eadc78165ff1f8ea94ad7cfdc54990738a4c53f6e0507b42154201b8e5dff3b1" + }, + { + "txid": "a1075db55d416d3ca199f55b6084e2115b9345e16c5cf302fc80e9d5fbf5d48d", + "vout": 0, + "scriptSig": "473045022100a8c61b2d470e393279d1ba54f254b7c237de299580b7fa01ffcc940442ecec4502201afba952f4e4661c40acde7acc0341589031ba103a307b886eb867b23b850b972103782eeb913431ca6e9b8c2fd80a5f72ed2024ef72a3c6fb10263c379937323338", + "txinwitness": "", + "prevout": { + "scriptPubKey": { + "hex": "76a9147cdd63cc408564188e8e472640e921c7c90e651d88ac" + } + }, + "private_key": "0378e95685b74565fa56751b84a32dfd18545d10d691641b8372e32164fad66a" + } + ], + "recipients": [ + "sp1qqgste7k9hx0qftg6qmwlkqtwuy6cycyavzmzj85c6qdfhjdpdjtdgq7c2zfthc6x3a5yecwc52nxa0kfd20xuz08zyrjpfw4l2j257yq6qgnkdh5" + ] + }, + "expected": { + "outputs": [ + [ + "7efa60ce78ac343df8a013a2027c6c5ef29f9502edcbd769d2c21717fecc5951" + ] + ] + } + } + ], + "receiving": [ + { + "given": { + "vin": [ + { + "txid": "f4184fc596403b9d638783cf57adfe4c75c605f6356fbc91338530e9831e9e16", + "vout": 0, + "scriptSig": "483046022100ad79e6801dd9a8727f342f31c71c4912866f59dc6e7981878e92c5844a0ce929022100fb0d2393e813968648b9753b7e9871d90ab3d815ebf91820d704b19f4ed224d621025a1e61f898173040e20616d43e9f496fba90338a39faa1ed98fcbaeee4dd9be5", + "txinwitness": "", + "prevout": { + "scriptPubKey": { + "hex": "76a91419c2f3ae0ca3b642bd3e49598b8da89f50c1416188ac" + } + } + }, + { + "txid": "a1075db55d416d3ca199f55b6084e2115b9345e16c5cf302fc80e9d5fbf5d48d", + "vout": 0, + "scriptSig": "473045022100a8c61b2d470e393279d1ba54f254b7c237de299580b7fa01ffcc940442ecec4502201afba952f4e4661c40acde7acc0341589031ba103a307b886eb867b23b850b972103782eeb913431ca6e9b8c2fd80a5f72ed2024ef72a3c6fb10263c379937323338", + "txinwitness": "", + "prevout": { + "scriptPubKey": { + "hex": "76a9147cdd63cc408564188e8e472640e921c7c90e651d88ac" + } + } + } + ], + "outputs": [ + "7efa60ce78ac343df8a013a2027c6c5ef29f9502edcbd769d2c21717fecc5951" + ], + "key_material": { + "spend_priv_key": "9d6ad855ce3417ef84e836892e5a56392bfba05fa5d97ccea30e266f540e08b3", + "scan_priv_key": "0f694e068028a717f8af6b9411f9a133dd3565258714cc226594b34db90c1f2c" + }, + "labels": [ + 2, + 3, + 1001337 + ] + }, + "expected": { + "addresses": [ + "sp1qqgste7k9hx0qftg6qmwlkqtwuy6cycyavzmzj85c6qdfhjdpdjtdgqjuexzk6murw56suy3e0rd2cgqvycxttddwsvgxe2usfpxumr70xc9pkqwv", + "sp1qqgste7k9hx0qftg6qmwlkqtwuy6cycyavzmzj85c6qdfhjdpdjtdgqjex54dmqmmv6rw353tsuqhs99ydvadxzrsy9nuvk74epvee55drs734pqq", + "sp1qqgste7k9hx0qftg6qmwlkqtwuy6cycyavzmzj85c6qdfhjdpdjtdgqsg59z2rppn4qlkx0yz9sdltmjv3j8zgcqadjn4ug98m3t6plujsq9qvu5n", + "sp1qqgste7k9hx0qftg6qmwlkqtwuy6cycyavzmzj85c6qdfhjdpdjtdgq7c2zfthc6x3a5yecwc52nxa0kfd20xuz08zyrjpfw4l2j257yq6qgnkdh5" + ], + "outputs": [ + { + "priv_key_tweak": "e336b92330c33030285ce42e4115ad92d5197913c88e06b9072b4a9b47c664a2", + "pub_key": "7efa60ce78ac343df8a013a2027c6c5ef29f9502edcbd769d2c21717fecc5951", + "signature": "c9e80dd3bdd25ca2d352ce77510f1aed37ba3509dc8cc0677f2d7c2dd04090707950ce9dd6c83d2a428063063aff5c04f1744e334f661f2fc01b4ef80b50f739" + } + ] + } + } + ] + }, + { + "comment": "Multiple outputs with labels: un-labeled and labeled address; same recipient", + "sending": [ + { + "given": { + "vin": [ + { + "txid": "f4184fc596403b9d638783cf57adfe4c75c605f6356fbc91338530e9831e9e16", + "vout": 0, + "scriptSig": "483046022100ad79e6801dd9a8727f342f31c71c4912866f59dc6e7981878e92c5844a0ce929022100fb0d2393e813968648b9753b7e9871d90ab3d815ebf91820d704b19f4ed224d621025a1e61f898173040e20616d43e9f496fba90338a39faa1ed98fcbaeee4dd9be5", + "txinwitness": "", + "prevout": { + "scriptPubKey": { + "hex": "76a91419c2f3ae0ca3b642bd3e49598b8da89f50c1416188ac" + } + }, + "private_key": "eadc78165ff1f8ea94ad7cfdc54990738a4c53f6e0507b42154201b8e5dff3b1" + }, + { + "txid": "a1075db55d416d3ca199f55b6084e2115b9345e16c5cf302fc80e9d5fbf5d48d", + "vout": 0, + "scriptSig": "473045022100a8c61b2d470e393279d1ba54f254b7c237de299580b7fa01ffcc940442ecec4502201afba952f4e4661c40acde7acc0341589031ba103a307b886eb867b23b850b972103782eeb913431ca6e9b8c2fd80a5f72ed2024ef72a3c6fb10263c379937323338", + "txinwitness": "", + "prevout": { + "scriptPubKey": { + "hex": "76a9147cdd63cc408564188e8e472640e921c7c90e651d88ac" + } + }, + "private_key": "0378e95685b74565fa56751b84a32dfd18545d10d691641b8372e32164fad66a" + } + ], + "recipients": [ + "sp1qqgste7k9hx0qftg6qmwlkqtwuy6cycyavzmzj85c6qdfhjdpdjtdgqaxww2fnhrx05cghth75n0qcj59e3e2anscr0q9wyknjxtxycg07y3pevyj", + "sp1qqgste7k9hx0qftg6qmwlkqtwuy6cycyavzmzj85c6qdfhjdpdjtdgqjuexzk6murw56suy3e0rd2cgqvycxttddwsvgxe2usfpxumr70xc9pkqwv" + ] + }, + "expected": { + "outputs": [ + [ + "39f42624d5c32a77fda80ff0acee269afec601d3791803e80252ae04e4ffcf4c", + "f207162b1a7abc51c42017bef055e9ec1efc3d3567cb720357e2b84325db33ac" + ], + [ + "83dc944e61603137294829aed56c74c9b087d80f2c021b98a7fae5799000696c", + "e976a58fbd38aeb4e6093d4df02e9c1de0c4513ae0c588cef68cda5b2f8834ca" + ] + ] + } + } + ], + "receiving": [ + { + "given": { + "vin": [ + { + "txid": "f4184fc596403b9d638783cf57adfe4c75c605f6356fbc91338530e9831e9e16", + "vout": 0, + "scriptSig": "483046022100ad79e6801dd9a8727f342f31c71c4912866f59dc6e7981878e92c5844a0ce929022100fb0d2393e813968648b9753b7e9871d90ab3d815ebf91820d704b19f4ed224d621025a1e61f898173040e20616d43e9f496fba90338a39faa1ed98fcbaeee4dd9be5", + "txinwitness": "", + "prevout": { + "scriptPubKey": { + "hex": "76a91419c2f3ae0ca3b642bd3e49598b8da89f50c1416188ac" + } + } + }, + { + "txid": "a1075db55d416d3ca199f55b6084e2115b9345e16c5cf302fc80e9d5fbf5d48d", + "vout": 0, + "scriptSig": "473045022100a8c61b2d470e393279d1ba54f254b7c237de299580b7fa01ffcc940442ecec4502201afba952f4e4661c40acde7acc0341589031ba103a307b886eb867b23b850b972103782eeb913431ca6e9b8c2fd80a5f72ed2024ef72a3c6fb10263c379937323338", + "txinwitness": "", + "prevout": { + "scriptPubKey": { + "hex": "76a9147cdd63cc408564188e8e472640e921c7c90e651d88ac" + } + } + } + ], + "outputs": [ + "39f42624d5c32a77fda80ff0acee269afec601d3791803e80252ae04e4ffcf4c", + "f207162b1a7abc51c42017bef055e9ec1efc3d3567cb720357e2b84325db33ac" + ], + "key_material": { + "spend_priv_key": "9d6ad855ce3417ef84e836892e5a56392bfba05fa5d97ccea30e266f540e08b3", + "scan_priv_key": "0f694e068028a717f8af6b9411f9a133dd3565258714cc226594b34db90c1f2c" + }, + "labels": [ + 1 + ] + }, + "expected": { + "addresses": [ + "sp1qqgste7k9hx0qftg6qmwlkqtwuy6cycyavzmzj85c6qdfhjdpdjtdgqjuexzk6murw56suy3e0rd2cgqvycxttddwsvgxe2usfpxumr70xc9pkqwv", + "sp1qqgste7k9hx0qftg6qmwlkqtwuy6cycyavzmzj85c6qdfhjdpdjtdgqaxww2fnhrx05cghth75n0qcj59e3e2anscr0q9wyknjxtxycg07y3pevyj" + ], + "outputs": [ + { + "priv_key_tweak": "43100f89f1a6bf10081c92b473ffc57ceac7dbed600b6aba9bb3976f17dbb914", + "pub_key": "39f42624d5c32a77fda80ff0acee269afec601d3791803e80252ae04e4ffcf4c", + "signature": "15c92509b67a6c211ebb4a51b7528d0666e6720de2343b2e92cfb97942ca14693c1f1fdc8451acfdb2644039f8f5c76114807fdc3d3a002d8a46afab6756bd75" + }, + { + "priv_key_tweak": "33ce085c3c11eaad13694aae3c20301a6c83382ec89a7cde96c6799e2f88805a", + "pub_key": "f207162b1a7abc51c42017bef055e9ec1efc3d3567cb720357e2b84325db33ac", + "signature": "335667ca6cae7a26438f5cfdd73b3d48fa832fa9768521d7d5445f22c203ab0d74ed85088f27d29959ba627a4509996676f47df8ff284d292567b1beef0e3912" + } + ] + } + } + ] + }, + { + "comment": "Multiple outputs with labels: multiple outputs for labeled address; same recipient", + "sending": [ + { + "given": { + "vin": [ + { + "txid": "f4184fc596403b9d638783cf57adfe4c75c605f6356fbc91338530e9831e9e16", + "vout": 0, + "scriptSig": "483046022100ad79e6801dd9a8727f342f31c71c4912866f59dc6e7981878e92c5844a0ce929022100fb0d2393e813968648b9753b7e9871d90ab3d815ebf91820d704b19f4ed224d621025a1e61f898173040e20616d43e9f496fba90338a39faa1ed98fcbaeee4dd9be5", + "txinwitness": "", + "prevout": { + "scriptPubKey": { + "hex": "76a91419c2f3ae0ca3b642bd3e49598b8da89f50c1416188ac" + } + }, + "private_key": "eadc78165ff1f8ea94ad7cfdc54990738a4c53f6e0507b42154201b8e5dff3b1" + }, + { + "txid": "a1075db55d416d3ca199f55b6084e2115b9345e16c5cf302fc80e9d5fbf5d48d", + "vout": 0, + "scriptSig": "473045022100a8c61b2d470e393279d1ba54f254b7c237de299580b7fa01ffcc940442ecec4502201afba952f4e4661c40acde7acc0341589031ba103a307b886eb867b23b850b972103782eeb913431ca6e9b8c2fd80a5f72ed2024ef72a3c6fb10263c379937323338", + "txinwitness": "", + "prevout": { + "scriptPubKey": { + "hex": "76a9147cdd63cc408564188e8e472640e921c7c90e651d88ac" + } + }, + "private_key": "0378e95685b74565fa56751b84a32dfd18545d10d691641b8372e32164fad66a" + } + ], + "recipients": [ + "sp1qqgste7k9hx0qftg6qmwlkqtwuy6cycyavzmzj85c6qdfhjdpdjtdgqaxww2fnhrx05cghth75n0qcj59e3e2anscr0q9wyknjxtxycg07y3pevyj", + "sp1qqgste7k9hx0qftg6qmwlkqtwuy6cycyavzmzj85c6qdfhjdpdjtdgqaxww2fnhrx05cghth75n0qcj59e3e2anscr0q9wyknjxtxycg07y3pevyj" + ] + }, + "expected": { + "outputs": [ + [ + "39f42624d5c32a77fda80ff0acee269afec601d3791803e80252ae04e4ffcf4c", + "83dc944e61603137294829aed56c74c9b087d80f2c021b98a7fae5799000696c" + ] + ] + } + } + ], + "receiving": [ + { + "given": { + "vin": [ + { + "txid": "f4184fc596403b9d638783cf57adfe4c75c605f6356fbc91338530e9831e9e16", + "vout": 0, + "scriptSig": "483046022100ad79e6801dd9a8727f342f31c71c4912866f59dc6e7981878e92c5844a0ce929022100fb0d2393e813968648b9753b7e9871d90ab3d815ebf91820d704b19f4ed224d621025a1e61f898173040e20616d43e9f496fba90338a39faa1ed98fcbaeee4dd9be5", + "txinwitness": "", + "prevout": { + "scriptPubKey": { + "hex": "76a91419c2f3ae0ca3b642bd3e49598b8da89f50c1416188ac" + } + } + }, + { + "txid": "a1075db55d416d3ca199f55b6084e2115b9345e16c5cf302fc80e9d5fbf5d48d", + "vout": 0, + "scriptSig": "473045022100a8c61b2d470e393279d1ba54f254b7c237de299580b7fa01ffcc940442ecec4502201afba952f4e4661c40acde7acc0341589031ba103a307b886eb867b23b850b972103782eeb913431ca6e9b8c2fd80a5f72ed2024ef72a3c6fb10263c379937323338", + "txinwitness": "", + "prevout": { + "scriptPubKey": { + "hex": "76a9147cdd63cc408564188e8e472640e921c7c90e651d88ac" + } + } + } + ], + "outputs": [ + "39f42624d5c32a77fda80ff0acee269afec601d3791803e80252ae04e4ffcf4c", + "83dc944e61603137294829aed56c74c9b087d80f2c021b98a7fae5799000696c" + ], + "key_material": { + "spend_priv_key": "9d6ad855ce3417ef84e836892e5a56392bfba05fa5d97ccea30e266f540e08b3", + "scan_priv_key": "0f694e068028a717f8af6b9411f9a133dd3565258714cc226594b34db90c1f2c" + }, + "labels": [ + 1 + ] + }, + "expected": { + "addresses": [ + "sp1qqgste7k9hx0qftg6qmwlkqtwuy6cycyavzmzj85c6qdfhjdpdjtdgqjuexzk6murw56suy3e0rd2cgqvycxttddwsvgxe2usfpxumr70xc9pkqwv", + "sp1qqgste7k9hx0qftg6qmwlkqtwuy6cycyavzmzj85c6qdfhjdpdjtdgqaxww2fnhrx05cghth75n0qcj59e3e2anscr0q9wyknjxtxycg07y3pevyj" + ], + "outputs": [ + { + "priv_key_tweak": "43100f89f1a6bf10081c92b473ffc57ceac7dbed600b6aba9bb3976f17dbb914", + "pub_key": "39f42624d5c32a77fda80ff0acee269afec601d3791803e80252ae04e4ffcf4c", + "signature": "15c92509b67a6c211ebb4a51b7528d0666e6720de2343b2e92cfb97942ca14693c1f1fdc8451acfdb2644039f8f5c76114807fdc3d3a002d8a46afab6756bd75" + }, + { + "priv_key_tweak": "9d5fd3b91cac9ddfea6fc2e6f9386f680e6cee623cda02f53706306c081de87f", + "pub_key": "83dc944e61603137294829aed56c74c9b087d80f2c021b98a7fae5799000696c", + "signature": "db0dfacc98b6a6fcc67cc4631f080b1ca38c60d8c397f2f19843f8f95ec91594b24e47c5bd39480a861c1209f7e3145c440371f9191fb96e324690101eac8e8e" + } + ] + } + } + ] + }, + { + "comment": "Multiple outputs with labels: un-labeled, labeled, and multiple outputs for labeled address; same recipients", + "sending": [ + { + "given": { + "vin": [ + { + "txid": "f4184fc596403b9d638783cf57adfe4c75c605f6356fbc91338530e9831e9e16", + "vout": 0, + "scriptSig": "483046022100ad79e6801dd9a8727f342f31c71c4912866f59dc6e7981878e92c5844a0ce929022100fb0d2393e813968648b9753b7e9871d90ab3d815ebf91820d704b19f4ed224d621025a1e61f898173040e20616d43e9f496fba90338a39faa1ed98fcbaeee4dd9be5", + "txinwitness": "", + "prevout": { + "scriptPubKey": { + "hex": "76a91419c2f3ae0ca3b642bd3e49598b8da89f50c1416188ac" + } + }, + "private_key": "eadc78165ff1f8ea94ad7cfdc54990738a4c53f6e0507b42154201b8e5dff3b1" + }, + { + "txid": "a1075db55d416d3ca199f55b6084e2115b9345e16c5cf302fc80e9d5fbf5d48d", + "vout": 0, + "scriptSig": "473045022100a8c61b2d470e393279d1ba54f254b7c237de299580b7fa01ffcc940442ecec4502201afba952f4e4661c40acde7acc0341589031ba103a307b886eb867b23b850b972103782eeb913431ca6e9b8c2fd80a5f72ed2024ef72a3c6fb10263c379937323338", + "txinwitness": "", + "prevout": { + "scriptPubKey": { + "hex": "76a9147cdd63cc408564188e8e472640e921c7c90e651d88ac" + } + }, + "private_key": "0378e95685b74565fa56751b84a32dfd18545d10d691641b8372e32164fad66a" + } + ], + "recipients": [ + "sp1qqgste7k9hx0qftg6qmwlkqtwuy6cycyavzmzj85c6qdfhjdpdjtdgqjuexzk6murw56suy3e0rd2cgqvycxttddwsvgxe2usfpxumr70xc9pkqwv", + "sp1qqgste7k9hx0qftg6qmwlkqtwuy6cycyavzmzj85c6qdfhjdpdjtdgqaxww2fnhrx05cghth75n0qcj59e3e2anscr0q9wyknjxtxycg07y3pevyj", + "sp1qqgste7k9hx0qftg6qmwlkqtwuy6cycyavzmzj85c6qdfhjdpdjtdgqjyh2ju7hd5gj57jg5r9lev3pckk4n2shtzaq34467erzzdfajfggty6aa5", + "sp1qqgste7k9hx0qftg6qmwlkqtwuy6cycyavzmzj85c6qdfhjdpdjtdgqjyh2ju7hd5gj57jg5r9lev3pckk4n2shtzaq34467erzzdfajfggty6aa5" + ] + }, + "expected": { + "outputs": [ + [ + "006a02c308ccdbf3ac49f0638f6de128f875db5a213095cf112b3b77722472ae", + "39f42624d5c32a77fda80ff0acee269afec601d3791803e80252ae04e4ffcf4c", + "ae1a780c04237bd577283c3ddb2e499767c3214160d5a6b0767e6b8c278bd701", + "ca64abe1e0f737823fb9a94f597eed418fb2df77b1317e26b881a14bb594faaa" + ], + [ + "006a02c308ccdbf3ac49f0638f6de128f875db5a213095cf112b3b77722472ae", + "3edf1ff6657c6e69568811bd726a7a7f480493aa42161acfe8dd4f44521f99ed", + "7ee1543ed5d123ffa66fbebc128c020173eb490d5fa2ba306e0c9573a77db8f3", + "ca64abe1e0f737823fb9a94f597eed418fb2df77b1317e26b881a14bb594faaa" + ], + [ + "006a02c308ccdbf3ac49f0638f6de128f875db5a213095cf112b3b77722472ae", + "7ee1543ed5d123ffa66fbebc128c020173eb490d5fa2ba306e0c9573a77db8f3", + "83dc944e61603137294829aed56c74c9b087d80f2c021b98a7fae5799000696c", + "ae1a780c04237bd577283c3ddb2e499767c3214160d5a6b0767e6b8c278bd701" + ], + [ + "39f42624d5c32a77fda80ff0acee269afec601d3791803e80252ae04e4ffcf4c", + "3c54444944d176437644378c23efb999ab6ab1cacdfe1dc1537b607e3df330e2", + "ca64abe1e0f737823fb9a94f597eed418fb2df77b1317e26b881a14bb594faaa", + "f4569fc5f69c10f0082cfbb8e072e6266ec55f69fba8cffca4cbb4c144b7e59b" + ], + [ + "39f42624d5c32a77fda80ff0acee269afec601d3791803e80252ae04e4ffcf4c", + "ae1a780c04237bd577283c3ddb2e499767c3214160d5a6b0767e6b8c278bd701", + "f207162b1a7abc51c42017bef055e9ec1efc3d3567cb720357e2b84325db33ac", + "f4569fc5f69c10f0082cfbb8e072e6266ec55f69fba8cffca4cbb4c144b7e59b" + ], + [ + "3c54444944d176437644378c23efb999ab6ab1cacdfe1dc1537b607e3df330e2", + "602e10e6944107c9b48bd885b493676578c935723287e0ab2f8b7f136862568e", + "7ee1543ed5d123ffa66fbebc128c020173eb490d5fa2ba306e0c9573a77db8f3", + "ca64abe1e0f737823fb9a94f597eed418fb2df77b1317e26b881a14bb594faaa" + ], + [ + "3c54444944d176437644378c23efb999ab6ab1cacdfe1dc1537b607e3df330e2", + "7ee1543ed5d123ffa66fbebc128c020173eb490d5fa2ba306e0c9573a77db8f3", + "83dc944e61603137294829aed56c74c9b087d80f2c021b98a7fae5799000696c", + "f4569fc5f69c10f0082cfbb8e072e6266ec55f69fba8cffca4cbb4c144b7e59b" + ], + [ + "3edf1ff6657c6e69568811bd726a7a7f480493aa42161acfe8dd4f44521f99ed", + "7ee1543ed5d123ffa66fbebc128c020173eb490d5fa2ba306e0c9573a77db8f3", + "f207162b1a7abc51c42017bef055e9ec1efc3d3567cb720357e2b84325db33ac", + "f4569fc5f69c10f0082cfbb8e072e6266ec55f69fba8cffca4cbb4c144b7e59b" + ], + [ + "3edf1ff6657c6e69568811bd726a7a7f480493aa42161acfe8dd4f44521f99ed", + "ca64abe1e0f737823fb9a94f597eed418fb2df77b1317e26b881a14bb594faaa", + "e976a58fbd38aeb4e6093d4df02e9c1de0c4513ae0c588cef68cda5b2f8834ca", + "f4569fc5f69c10f0082cfbb8e072e6266ec55f69fba8cffca4cbb4c144b7e59b" + ], + [ + "602e10e6944107c9b48bd885b493676578c935723287e0ab2f8b7f136862568e", + "7ee1543ed5d123ffa66fbebc128c020173eb490d5fa2ba306e0c9573a77db8f3", + "ae1a780c04237bd577283c3ddb2e499767c3214160d5a6b0767e6b8c278bd701", + "f207162b1a7abc51c42017bef055e9ec1efc3d3567cb720357e2b84325db33ac" + ], + [ + "602e10e6944107c9b48bd885b493676578c935723287e0ab2f8b7f136862568e", + "ae1a780c04237bd577283c3ddb2e499767c3214160d5a6b0767e6b8c278bd701", + "ca64abe1e0f737823fb9a94f597eed418fb2df77b1317e26b881a14bb594faaa", + "e976a58fbd38aeb4e6093d4df02e9c1de0c4513ae0c588cef68cda5b2f8834ca" + ], + [ + "83dc944e61603137294829aed56c74c9b087d80f2c021b98a7fae5799000696c", + "ae1a780c04237bd577283c3ddb2e499767c3214160d5a6b0767e6b8c278bd701", + "e976a58fbd38aeb4e6093d4df02e9c1de0c4513ae0c588cef68cda5b2f8834ca", + "f4569fc5f69c10f0082cfbb8e072e6266ec55f69fba8cffca4cbb4c144b7e59b" + ] + ] + } + } + ], + "receiving": [ + { + "given": { + "vin": [ + { + "txid": "f4184fc596403b9d638783cf57adfe4c75c605f6356fbc91338530e9831e9e16", + "vout": 0, + "scriptSig": "483046022100ad79e6801dd9a8727f342f31c71c4912866f59dc6e7981878e92c5844a0ce929022100fb0d2393e813968648b9753b7e9871d90ab3d815ebf91820d704b19f4ed224d621025a1e61f898173040e20616d43e9f496fba90338a39faa1ed98fcbaeee4dd9be5", + "txinwitness": "", + "prevout": { + "scriptPubKey": { + "hex": "76a91419c2f3ae0ca3b642bd3e49598b8da89f50c1416188ac" + } + } + }, + { + "txid": "a1075db55d416d3ca199f55b6084e2115b9345e16c5cf302fc80e9d5fbf5d48d", + "vout": 0, + "scriptSig": "473045022100a8c61b2d470e393279d1ba54f254b7c237de299580b7fa01ffcc940442ecec4502201afba952f4e4661c40acde7acc0341589031ba103a307b886eb867b23b850b972103782eeb913431ca6e9b8c2fd80a5f72ed2024ef72a3c6fb10263c379937323338", + "txinwitness": "", + "prevout": { + "scriptPubKey": { + "hex": "76a9147cdd63cc408564188e8e472640e921c7c90e651d88ac" + } + } + } + ], + "outputs": [ + "006a02c308ccdbf3ac49f0638f6de128f875db5a213095cf112b3b77722472ae", + "39f42624d5c32a77fda80ff0acee269afec601d3791803e80252ae04e4ffcf4c", + "ae1a780c04237bd577283c3ddb2e499767c3214160d5a6b0767e6b8c278bd701", + "ca64abe1e0f737823fb9a94f597eed418fb2df77b1317e26b881a14bb594faaa" + ], + "key_material": { + "spend_priv_key": "9d6ad855ce3417ef84e836892e5a56392bfba05fa5d97ccea30e266f540e08b3", + "scan_priv_key": "0f694e068028a717f8af6b9411f9a133dd3565258714cc226594b34db90c1f2c" + }, + "labels": [ + 1, + 1337 + ] + }, + "expected": { + "addresses": [ + "sp1qqgste7k9hx0qftg6qmwlkqtwuy6cycyavzmzj85c6qdfhjdpdjtdgqjuexzk6murw56suy3e0rd2cgqvycxttddwsvgxe2usfpxumr70xc9pkqwv", + "sp1qqgste7k9hx0qftg6qmwlkqtwuy6cycyavzmzj85c6qdfhjdpdjtdgqaxww2fnhrx05cghth75n0qcj59e3e2anscr0q9wyknjxtxycg07y3pevyj", + "sp1qqgste7k9hx0qftg6qmwlkqtwuy6cycyavzmzj85c6qdfhjdpdjtdgqjyh2ju7hd5gj57jg5r9lev3pckk4n2shtzaq34467erzzdfajfggty6aa5" + ], + "outputs": [ + { + "priv_key_tweak": "4e3352fbe0505c25e718d96007c259ef08db34f8c844e4ff742d9855ff03805a", + "pub_key": "006a02c308ccdbf3ac49f0638f6de128f875db5a213095cf112b3b77722472ae", + "signature": "6eeae1ea9eb826e3d0e812f65937100e0836ea188c04f36fabc4981eda29de8d3d3529390a0a8b3d830f7bca4f5eae5994b9788ddaf05ad259ffe26d86144b4b" + }, + { + "priv_key_tweak": "43100f89f1a6bf10081c92b473ffc57ceac7dbed600b6aba9bb3976f17dbb914", + "pub_key": "39f42624d5c32a77fda80ff0acee269afec601d3791803e80252ae04e4ffcf4c", + "signature": "15c92509b67a6c211ebb4a51b7528d0666e6720de2343b2e92cfb97942ca14693c1f1fdc8451acfdb2644039f8f5c76114807fdc3d3a002d8a46afab6756bd75" + }, + { + "priv_key_tweak": "bf709f98d4418f8a67e738154ae48818dad44689cd37fbc070891a396dd1c633", + "pub_key": "ae1a780c04237bd577283c3ddb2e499767c3214160d5a6b0767e6b8c278bd701", + "signature": "42a19fd8a63dde1824966a95d65a28203e631e49bf96ca5dae1b390e7a0ace2cc8709c9b0c5715047032f57f536a3c80273cbecf4c05be0b5456c183fa122c06" + }, + { + "priv_key_tweak": "736f05e4e3072c3b8656bedef2e9bf54cbcaa2b6fe5320d3e86f5b96874dda71", + "pub_key": "ca64abe1e0f737823fb9a94f597eed418fb2df77b1317e26b881a14bb594faaa", + "signature": "2e61bb3d79418ecf55f68847cf121bfc12d397b39d1da8643246b2f0a9b96c3daa4bfe9651beb5c9ce20e1f29282c4566400a4b45ee6657ec3b18fdc554da0b4" + } + ] + } + } + ] + }, + { + "comment": "Single recipient: use silent payments for sender change", + "sending": [ + { + "given": { + "vin": [ + { + "txid": "f4184fc596403b9d638783cf57adfe4c75c605f6356fbc91338530e9831e9e16", + "vout": 0, + "scriptSig": "483046022100ad79e6801dd9a8727f342f31c71c4912866f59dc6e7981878e92c5844a0ce929022100fb0d2393e813968648b9753b7e9871d90ab3d815ebf91820d704b19f4ed224d621025a1e61f898173040e20616d43e9f496fba90338a39faa1ed98fcbaeee4dd9be5", + "txinwitness": "", + "prevout": { + "scriptPubKey": { + "hex": "76a91419c2f3ae0ca3b642bd3e49598b8da89f50c1416188ac" + } + }, + "private_key": "eadc78165ff1f8ea94ad7cfdc54990738a4c53f6e0507b42154201b8e5dff3b1" + }, + { + "txid": "a1075db55d416d3ca199f55b6084e2115b9345e16c5cf302fc80e9d5fbf5d48d", + "vout": 0, + "scriptSig": "473045022100a8c61b2d470e393279d1ba54f254b7c237de299580b7fa01ffcc940442ecec4502201afba952f4e4661c40acde7acc0341589031ba103a307b886eb867b23b850b972103782eeb913431ca6e9b8c2fd80a5f72ed2024ef72a3c6fb10263c379937323338", + "txinwitness": "", + "prevout": { + "scriptPubKey": { + "hex": "76a9147cdd63cc408564188e8e472640e921c7c90e651d88ac" + } + }, + "private_key": "0378e95685b74565fa56751b84a32dfd18545d10d691641b8372e32164fad66a" + } + ], + "recipients": [ + "sp1qqgste7k9hx0qftg6qmwlkqtwuy6cycyavzmzj85c6qdfhjdpdjtdgqjuexzk6murw56suy3e0rd2cgqvycxttddwsvgxe2usfpxumr70xc9pkqwv", + "sp1qqw6vczcfpdh5nf5y2ky99kmqae0tr30hgdfg88parz50cp80wd2wqqlv6saelkk5snl4wfutyxrchpzzwm8rjp3z6q7apna59z9huq4x754e5atr" + ] + }, + "expected": { + "outputs": [ + [ + "be368e28979d950245d742891ae6064020ba548c1e2e65a639a8bb0675d95cff", + "f207162b1a7abc51c42017bef055e9ec1efc3d3567cb720357e2b84325db33ac" + ] + ] + } + } + ], + "receiving": [ + { + "given": { + "vin": [ + { + "txid": "f4184fc596403b9d638783cf57adfe4c75c605f6356fbc91338530e9831e9e16", + "vout": 0, + "scriptSig": "483046022100ad79e6801dd9a8727f342f31c71c4912866f59dc6e7981878e92c5844a0ce929022100fb0d2393e813968648b9753b7e9871d90ab3d815ebf91820d704b19f4ed224d621025a1e61f898173040e20616d43e9f496fba90338a39faa1ed98fcbaeee4dd9be5", + "txinwitness": "", + "prevout": { + "scriptPubKey": { + "hex": "76a91419c2f3ae0ca3b642bd3e49598b8da89f50c1416188ac" + } + } + }, + { + "txid": "a1075db55d416d3ca199f55b6084e2115b9345e16c5cf302fc80e9d5fbf5d48d", + "vout": 0, + "scriptSig": "473045022100a8c61b2d470e393279d1ba54f254b7c237de299580b7fa01ffcc940442ecec4502201afba952f4e4661c40acde7acc0341589031ba103a307b886eb867b23b850b972103782eeb913431ca6e9b8c2fd80a5f72ed2024ef72a3c6fb10263c379937323338", + "txinwitness": "", + "prevout": { + "scriptPubKey": { + "hex": "76a9147cdd63cc408564188e8e472640e921c7c90e651d88ac" + } + } + } + ], + "outputs": [ + "be368e28979d950245d742891ae6064020ba548c1e2e65a639a8bb0675d95cff", + "f207162b1a7abc51c42017bef055e9ec1efc3d3567cb720357e2b84325db33ac" + ], + "key_material": { + "spend_priv_key": "b8f87388cbb41934c50daca018901b00070a5ff6cc25a7e9e716a9d5b9e4d664", + "scan_priv_key": "11b7a82e06ca2648d5fded2366478078ec4fc9dc1d8ff487518226f229d768fd" + }, + "labels": [ + 0 + ] + }, + "expected": { + "addresses": [ + "sp1qqw6vczcfpdh5nf5y2ky99kmqae0tr30hgdfg88parz50cp80wd2wqqauj52ymtc4xdkmx3tgyhrsemg2g3303xk2gtzfy8h8ejet8fz8jcw23zua", + "sp1qqw6vczcfpdh5nf5y2ky99kmqae0tr30hgdfg88parz50cp80wd2wqqlv6saelkk5snl4wfutyxrchpzzwm8rjp3z6q7apna59z9huq4x754e5atr" + ], + "outputs": [ + { + "priv_key_tweak": "80cd767ed20bd0bb7d8ea5e803f8c381293a62e8a073cf46fb0081da46e64e1f", + "pub_key": "be368e28979d950245d742891ae6064020ba548c1e2e65a639a8bb0675d95cff", + "signature": "7fbd5074cf1377273155eefafc7c330cb61b31da252f22206ac27530d2b2567040d9af7808342ed4a09598c26d8307446e4ed77079e6a2e61fea736e44da5f5a" + } + ] + } + }, + { + "given": { + "vin": [ + { + "txid": "f4184fc596403b9d638783cf57adfe4c75c605f6356fbc91338530e9831e9e16", + "vout": 0, + "scriptSig": "483046022100ad79e6801dd9a8727f342f31c71c4912866f59dc6e7981878e92c5844a0ce929022100fb0d2393e813968648b9753b7e9871d90ab3d815ebf91820d704b19f4ed224d621025a1e61f898173040e20616d43e9f496fba90338a39faa1ed98fcbaeee4dd9be5", + "txinwitness": "", + "prevout": { + "scriptPubKey": { + "hex": "76a91419c2f3ae0ca3b642bd3e49598b8da89f50c1416188ac" + } + } + }, + { + "txid": "a1075db55d416d3ca199f55b6084e2115b9345e16c5cf302fc80e9d5fbf5d48d", + "vout": 0, + "scriptSig": "473045022100a8c61b2d470e393279d1ba54f254b7c237de299580b7fa01ffcc940442ecec4502201afba952f4e4661c40acde7acc0341589031ba103a307b886eb867b23b850b972103782eeb913431ca6e9b8c2fd80a5f72ed2024ef72a3c6fb10263c379937323338", + "txinwitness": "", + "prevout": { + "scriptPubKey": { + "hex": "76a9147cdd63cc408564188e8e472640e921c7c90e651d88ac" + } + } + } + ], + "outputs": [ + "be368e28979d950245d742891ae6064020ba548c1e2e65a639a8bb0675d95cff", + "f207162b1a7abc51c42017bef055e9ec1efc3d3567cb720357e2b84325db33ac" + ], + "key_material": { + "spend_priv_key": "9d6ad855ce3417ef84e836892e5a56392bfba05fa5d97ccea30e266f540e08b3", + "scan_priv_key": "0f694e068028a717f8af6b9411f9a133dd3565258714cc226594b34db90c1f2c" + }, + "labels": [] + }, + "expected": { + "addresses": [ + "sp1qqgste7k9hx0qftg6qmwlkqtwuy6cycyavzmzj85c6qdfhjdpdjtdgqjuexzk6murw56suy3e0rd2cgqvycxttddwsvgxe2usfpxumr70xc9pkqwv" + ], + "outputs": [ + { + "priv_key_tweak": "33ce085c3c11eaad13694aae3c20301a6c83382ec89a7cde96c6799e2f88805a", + "pub_key": "f207162b1a7abc51c42017bef055e9ec1efc3d3567cb720357e2b84325db33ac", + "signature": "335667ca6cae7a26438f5cfdd73b3d48fa832fa9768521d7d5445f22c203ab0d74ed85088f27d29959ba627a4509996676f47df8ff284d292567b1beef0e3912" + } + ] + } + } + ] + }, + { + "comment": "Single recipient: taproot input with NUMS point", + "sending": [ + { + "given": { + "vin": [ + { + "txid": "f4184fc596403b9d638783cf57adfe4c75c605f6356fbc91338530e9831e9e16", + "vout": 0, + "scriptSig": "", + "txinwitness": "0440c459b671370d12cfb5acee76da7e3ba7cc29b0b4653e3af8388591082660137d087fdc8e89a612cd5d15be0febe61fc7cdcf3161a26e599a4514aa5c3e86f47b22205a1e61f898173040e20616d43e9f496fba90338a39faa1ed98fcbaeee4dd9be5ac21c150929b74c1a04954b78b4b6035e97a5e078a5a0f28ec96d547bfee9ace803ac00150", + "prevout": { + "scriptPubKey": { + "hex": "5120da6f0595ecb302bbe73e2f221f05ab10f336b06817d36fd28fc6691725ddaa85" + } + }, + "private_key": "eadc78165ff1f8ea94ad7cfdc54990738a4c53f6e0507b42154201b8e5dff3b1" + }, + { + "txid": "a1075db55d416d3ca199f55b6084e2115b9345e16c5cf302fc80e9d5fbf5d48d", + "vout": 0, + "scriptSig": "", + "txinwitness": "0140bd1e708f92dbeaf24a6b8dd22e59c6274355424d62baea976b449e220fd75b13578e262ab11b7aa58e037f0c6b0519b66803b7d9decaa1906dedebfb531c56c1", + "prevout": { + "scriptPubKey": { + "hex": "5120782eeb913431ca6e9b8c2fd80a5f72ed2024ef72a3c6fb10263c379937323338" + } + }, + "private_key": "fc8716a97a48ba9a05a98ae47b5cd201a25a7fd5d8b73c203c5f7b6b6b3b6ad7" + }, + { + "txid": "a1075db55d416d3ca199f55b6084e2115b9345e16c5cf302fc80e9d5fbf5d48d", + "vout": 1, + "scriptSig": "", + "txinwitness": "0340268d31a9276f6380107d5321cafa6d9e8e5ea39204318fdc8206b31507c891c3bbcea3c99e2208d73bd127a8e8c5f1e45a54f1bd217205414ddb566ab7eda0092220e0ec4f64b3fa2e463ccfcf4e856e37d5e1e20275bc89ec1def9eb098eff1f85dac21c150929b74c1a04954b78b4b6035e97a5e078a5a0f28ec96d547bfee9ace803ac0", + "prevout": { + "scriptPubKey": { + "hex": "51200a3c9365ceb131f89b0a4feb6896ebd67bb15a98c31eaa3da143bb955a0f3fcb" + } + }, + "private_key": "8d4751f6e8a3586880fb66c19ae277969bd5aa06f61c4ee2f1e2486efdf666d3" + } + ], + "recipients": [ + "sp1qqgste7k9hx0qftg6qmwlkqtwuy6cycyavzmzj85c6qdfhjdpdjtdgqjuexzk6murw56suy3e0rd2cgqvycxttddwsvgxe2usfpxumr70xc9pkqwv" + ] + }, + "expected": { + "outputs": [ + [ + "79e79897c52935bfd97fc6e076a6431a0c7543ca8c31e0fc3cf719bb572c842d" + ] + ] + } + } + ], + "receiving": [ + { + "given": { + "vin": [ + { + "txid": "f4184fc596403b9d638783cf57adfe4c75c605f6356fbc91338530e9831e9e16", + "vout": 0, + "scriptSig": "", + "txinwitness": "0440c459b671370d12cfb5acee76da7e3ba7cc29b0b4653e3af8388591082660137d087fdc8e89a612cd5d15be0febe61fc7cdcf3161a26e599a4514aa5c3e86f47b22205a1e61f898173040e20616d43e9f496fba90338a39faa1ed98fcbaeee4dd9be5ac21c150929b74c1a04954b78b4b6035e97a5e078a5a0f28ec96d547bfee9ace803ac00150", + "prevout": { + "scriptPubKey": { + "hex": "5120da6f0595ecb302bbe73e2f221f05ab10f336b06817d36fd28fc6691725ddaa85" + } + } + }, + { + "txid": "a1075db55d416d3ca199f55b6084e2115b9345e16c5cf302fc80e9d5fbf5d48d", + "vout": 0, + "scriptSig": "", + "txinwitness": "0140bd1e708f92dbeaf24a6b8dd22e59c6274355424d62baea976b449e220fd75b13578e262ab11b7aa58e037f0c6b0519b66803b7d9decaa1906dedebfb531c56c1", + "prevout": { + "scriptPubKey": { + "hex": "5120782eeb913431ca6e9b8c2fd80a5f72ed2024ef72a3c6fb10263c379937323338" + } + } + }, + { + "txid": "a1075db55d416d3ca199f55b6084e2115b9345e16c5cf302fc80e9d5fbf5d48d", + "vout": 1, + "scriptSig": "", + "txinwitness": "0340268d31a9276f6380107d5321cafa6d9e8e5ea39204318fdc8206b31507c891c3bbcea3c99e2208d73bd127a8e8c5f1e45a54f1bd217205414ddb566ab7eda0092220e0ec4f64b3fa2e463ccfcf4e856e37d5e1e20275bc89ec1def9eb098eff1f85dac21c150929b74c1a04954b78b4b6035e97a5e078a5a0f28ec96d547bfee9ace803ac0", + "prevout": { + "scriptPubKey": { + "hex": "51200a3c9365ceb131f89b0a4feb6896ebd67bb15a98c31eaa3da143bb955a0f3fcb" + } + } + } + ], + "outputs": [ + "79e79897c52935bfd97fc6e076a6431a0c7543ca8c31e0fc3cf719bb572c842d" + ], + "key_material": { + "spend_priv_key": "9d6ad855ce3417ef84e836892e5a56392bfba05fa5d97ccea30e266f540e08b3", + "scan_priv_key": "0f694e068028a717f8af6b9411f9a133dd3565258714cc226594b34db90c1f2c" + }, + "labels": [] + }, + "expected": { + "addresses": [ + "sp1qqgste7k9hx0qftg6qmwlkqtwuy6cycyavzmzj85c6qdfhjdpdjtdgqjuexzk6murw56suy3e0rd2cgqvycxttddwsvgxe2usfpxumr70xc9pkqwv" + ], + "outputs": [ + { + "priv_key_tweak": "3ddec3232609d348d6b8b53123b4f40f6d4f5398ca586f087b0416ec3b851496", + "pub_key": "79e79897c52935bfd97fc6e076a6431a0c7543ca8c31e0fc3cf719bb572c842d", + "signature": "d7d06e3afb68363031e4eb18035c46ceae41bdbebe7888a4754bc9848c596436869aeaecff0527649a1f458b71c9ceecec10b535c09d01d720229aa228547706" + } + ] + } + } + ] + }, + { + "comment": "Pubkey extraction from malleated p2pkh", + "sending": [ + { + "given": { + "vin": [ + { + "txid": "f4184fc596403b9d638783cf57adfe4c75c605f6356fbc91338530e9831e9e16", + "vout": 0, + "scriptSig": "483046022100ad79e6801dd9a8727f342f31c71c4912866f59dc6e7981878e92c5844a0ce929022100fb0d2393e813968648b9753b7e9871d90ab3d815ebf91820d704b19f4ed224d621025a1e61f898173040e20616d43e9f496fba90338a39faa1ed98fcbaeee4dd9be5", + "txinwitness": "", + "prevout": { + "scriptPubKey": { + "hex": "76a91419c2f3ae0ca3b642bd3e49598b8da89f50c1416188ac" + } + }, + "private_key": "eadc78165ff1f8ea94ad7cfdc54990738a4c53f6e0507b42154201b8e5dff3b1" + }, + { + "txid": "f4184fc596403b9d638783cf57adfe4c75c605f6356fbc91338530e9831e9e16", + "vout": 1, + "scriptSig": "0075473045022100a8c61b2d470e393279d1ba54f254b7c237de299580b7fa01ffcc940442ecec4502201afba952f4e4661c40acde7acc0341589031ba103a307b886eb867b23b850b972103782eeb913431ca6e9b8c2fd80a5f72ed2024ef72a3c6fb10263c379937323338", + "txinwitness": "", + "prevout": { + "scriptPubKey": { + "hex": "76a9147cdd63cc408564188e8e472640e921c7c90e651d88ac" + } + }, + "private_key": "0378e95685b74565fa56751b84a32dfd18545d10d691641b8372e32164fad66a" + }, + { + "txid": "f4184fc596403b9d638783cf57adfe4c75c605f6356fbc91338530e9831e9e16", + "vout": 2, + "scriptSig": "5163473045022100e7d26e77290b37128f5215ade25b9b908ce87cc9a4d498908b5bb8fd6daa1b8d022002568c3a8226f4f0436510283052bfb780b76f3fe4aa60c4c5eb118e43b187372102e0ec4f64b3fa2e463ccfcf4e856e37d5e1e20275bc89ec1def9eb098eff1f85d67483046022100c0d3c851d3bd562ae93d56bcefd735ea57c027af46145a4d5e9cac113bfeb0c2022100ee5b2239af199fa9b7aa1d98da83a29d0a2cf1e4f29e2f37134ce386d51c544c2102ad0f26ddc7b3fcc340155963b3051b85289c1869612ecb290184ac952e2864ec68", + "txinwitness": "", + "prevout": { + "scriptPubKey": { + "hex": "76a914c82c5ec473cbc6c86e5ef410e36f9495adcf979988ac" + } + }, + "private_key": "72b8ae09175ca7977f04993e651d88681ed932dfb92c5158cdf0161dd23fda6e" + } + ], + "recipients": [ + "sp1qqgste7k9hx0qftg6qmwlkqtwuy6cycyavzmzj85c6qdfhjdpdjtdgqjuexzk6murw56suy3e0rd2cgqvycxttddwsvgxe2usfpxumr70xc9pkqwv" + ] + }, + "expected": { + "outputs": [ + [ + "4612cdbf845c66c7511d70aab4d9aed11e49e48cdb8d799d787101cdd0d53e4f" + ] + ] + } + } + ], + "receiving": [ + { + "given": { + "vin": [ + { + "txid": "f4184fc596403b9d638783cf57adfe4c75c605f6356fbc91338530e9831e9e16", + "vout": 0, + "scriptSig": "483046022100ad79e6801dd9a8727f342f31c71c4912866f59dc6e7981878e92c5844a0ce929022100fb0d2393e813968648b9753b7e9871d90ab3d815ebf91820d704b19f4ed224d621025a1e61f898173040e20616d43e9f496fba90338a39faa1ed98fcbaeee4dd9be5", + "txinwitness": "", + "prevout": { + "scriptPubKey": { + "hex": "76a91419c2f3ae0ca3b642bd3e49598b8da89f50c1416188ac" + } + } + }, + { + "txid": "f4184fc596403b9d638783cf57adfe4c75c605f6356fbc91338530e9831e9e16", + "vout": 1, + "scriptSig": "0075473045022100a8c61b2d470e393279d1ba54f254b7c237de299580b7fa01ffcc940442ecec4502201afba952f4e4661c40acde7acc0341589031ba103a307b886eb867b23b850b972103782eeb913431ca6e9b8c2fd80a5f72ed2024ef72a3c6fb10263c379937323338", + "txinwitness": "", + "prevout": { + "scriptPubKey": { + "hex": "76a9147cdd63cc408564188e8e472640e921c7c90e651d88ac" + } + } + }, + { + "txid": "f4184fc596403b9d638783cf57adfe4c75c605f6356fbc91338530e9831e9e16", + "vout": 2, + "scriptSig": "5163473045022100e7d26e77290b37128f5215ade25b9b908ce87cc9a4d498908b5bb8fd6daa1b8d022002568c3a8226f4f0436510283052bfb780b76f3fe4aa60c4c5eb118e43b187372102e0ec4f64b3fa2e463ccfcf4e856e37d5e1e20275bc89ec1def9eb098eff1f85d67483046022100c0d3c851d3bd562ae93d56bcefd735ea57c027af46145a4d5e9cac113bfeb0c2022100ee5b2239af199fa9b7aa1d98da83a29d0a2cf1e4f29e2f37134ce386d51c544c2102ad0f26ddc7b3fcc340155963b3051b85289c1869612ecb290184ac952e2864ec68", + "txinwitness": "", + "prevout": { + "scriptPubKey": { + "hex": "76a914c82c5ec473cbc6c86e5ef410e36f9495adcf979988ac" + } + } + } + ], + "outputs": [ + "4612cdbf845c66c7511d70aab4d9aed11e49e48cdb8d799d787101cdd0d53e4f" + ], + "key_material": { + "spend_priv_key": "9d6ad855ce3417ef84e836892e5a56392bfba05fa5d97ccea30e266f540e08b3", + "scan_priv_key": "0f694e068028a717f8af6b9411f9a133dd3565258714cc226594b34db90c1f2c" + }, + "labels": [] + }, + "expected": { + "addresses": [ + "sp1qqgste7k9hx0qftg6qmwlkqtwuy6cycyavzmzj85c6qdfhjdpdjtdgqjuexzk6murw56suy3e0rd2cgqvycxttddwsvgxe2usfpxumr70xc9pkqwv" + ], + "outputs": [ + { + "priv_key_tweak": "10bde9781def20d7701e7603ef1b1e5e71c67bae7154818814e3c81ef5b1a3d3", + "pub_key": "4612cdbf845c66c7511d70aab4d9aed11e49e48cdb8d799d787101cdd0d53e4f", + "signature": "6137969f810e9e8ef6c9755010e808f5dd1aed705882e44d7f0ae64eb0c509ec8b62a0671bee0d5914ac27d2c463443e28e999d82dc3d3a4919f093872d947bb" + } + ] + } + } + ] + }, + { + "comment": "P2PKH and P2WPKH Uncompressed Keys are skipped", + "sending": [ + { + "given": { + "vin": [ + { + "txid": "a1075db55d416d3ca199f55b6084e2115b9345e16c5cf302fc80e9d5fbf5d48d", + "vout": 0, + "scriptSig": "483046022100ad79e6801dd9a8727f342f31c71c4912866f59dc6e7981878e92c5844a0ce929022100fb0d2393e813968648b9753b7e9871d90ab3d815ebf91820d704b19f4ed224d621025a1e61f898173040e20616d43e9f496fba90338a39faa1ed98fcbaeee4dd9be5", + "txinwitness": "", + "prevout": { + "scriptPubKey": { + "hex": "76a91419c2f3ae0ca3b642bd3e49598b8da89f50c1416188ac" + } + }, + "private_key": "eadc78165ff1f8ea94ad7cfdc54990738a4c53f6e0507b42154201b8e5dff3b1" + }, + { + "txid": "f4184fc596403b9d638783cf57adfe4c75c605f6356fbc91338530e9831e9e16", + "vout": 0, + "scriptSig": "473045022100a8c61b2d470e393279d1ba54f254b7c237de299580b7fa01ffcc940442ecec4502201afba952f4e4661c40acde7acc0341589031ba103a307b886eb867b23b850b974104782eeb913431ca6e9b8c2fd80a5f72ed2024ef72a3c6fb10263c3799373233387c5343bf58e23269e903335b958a12182f9849297321e8d710e49a8727129cab", + "txinwitness": "", + "prevout": { + "scriptPubKey": { + "hex": "76a9144b92ac4ac6fe6212393894addda332f2e47a315688ac" + } + }, + "private_key": "0378e95685b74565fa56751b84a32dfd18545d10d691641b8372e32164fad66a" + }, + { + "txid": "a1075db55d416d3ca199f55b6084e2115b9345e16c5cf302fc80e9d5fbf5d48d", + "vout": 1, + "scriptSig": "", + "txinwitness": "02473045022100e7d26e77290b37128f5215ade25b9b908ce87cc9a4d498908b5bb8fd6daa1b8d022002568c3a8226f4f0436510283052bfb780b76f3fe4aa60c4c5eb118e43b187374104e0ec4f64b3fa2e463ccfcf4e856e37d5e1e20275bc89ec1def9eb098eff1f85d6fe8190e189be57d0d5bcd17dbcbcd04c9b4a1c5f605b10d5c90abfcc0d12884", + "prevout": { + "scriptPubKey": { + "hex": "00140423f731a07491364e8dce98b7c00bda63336950" + } + }, + "private_key": "72b8ae09175ca7977f04993e651d88681ed932dfb92c5158cdf0161dd23fda6e" + } + ], + "recipients": [ + "sp1qqgste7k9hx0qftg6qmwlkqtwuy6cycyavzmzj85c6qdfhjdpdjtdgqjuexzk6murw56suy3e0rd2cgqvycxttddwsvgxe2usfpxumr70xc9pkqwv" + ] + }, + "expected": { + "outputs": [ + [ + "67fee277da9e8542b5d2e6f32d660a9bbd3f0e107c2d53638ab1d869088882d6" + ] + ] + } + } + ], + "receiving": [ + { + "given": { + "vin": [ + { + "txid": "a1075db55d416d3ca199f55b6084e2115b9345e16c5cf302fc80e9d5fbf5d48d", + "vout": 0, + "scriptSig": "483046022100ad79e6801dd9a8727f342f31c71c4912866f59dc6e7981878e92c5844a0ce929022100fb0d2393e813968648b9753b7e9871d90ab3d815ebf91820d704b19f4ed224d621025a1e61f898173040e20616d43e9f496fba90338a39faa1ed98fcbaeee4dd9be5", + "txinwitness": "", + "prevout": { + "scriptPubKey": { + "hex": "76a91419c2f3ae0ca3b642bd3e49598b8da89f50c1416188ac" + } + } + }, + { + "txid": "f4184fc596403b9d638783cf57adfe4c75c605f6356fbc91338530e9831e9e16", + "vout": 0, + "scriptSig": "473045022100a8c61b2d470e393279d1ba54f254b7c237de299580b7fa01ffcc940442ecec4502201afba952f4e4661c40acde7acc0341589031ba103a307b886eb867b23b850b974104782eeb913431ca6e9b8c2fd80a5f72ed2024ef72a3c6fb10263c3799373233387c5343bf58e23269e903335b958a12182f9849297321e8d710e49a8727129cab", + "txinwitness": "", + "prevout": { + "scriptPubKey": { + "hex": "76a9144b92ac4ac6fe6212393894addda332f2e47a315688ac" + } + } + }, + { + "txid": "a1075db55d416d3ca199f55b6084e2115b9345e16c5cf302fc80e9d5fbf5d48d", + "vout": 1, + "scriptSig": "", + "txinwitness": "02473045022100e7d26e77290b37128f5215ade25b9b908ce87cc9a4d498908b5bb8fd6daa1b8d022002568c3a8226f4f0436510283052bfb780b76f3fe4aa60c4c5eb118e43b187374104e0ec4f64b3fa2e463ccfcf4e856e37d5e1e20275bc89ec1def9eb098eff1f85d6fe8190e189be57d0d5bcd17dbcbcd04c9b4a1c5f605b10d5c90abfcc0d12884", + "prevout": { + "scriptPubKey": { + "hex": "00140423f731a07491364e8dce98b7c00bda63336950" + } + } + } + ], + "outputs": [ + "67fee277da9e8542b5d2e6f32d660a9bbd3f0e107c2d53638ab1d869088882d6" + ], + "key_material": { + "spend_priv_key": "9d6ad855ce3417ef84e836892e5a56392bfba05fa5d97ccea30e266f540e08b3", + "scan_priv_key": "0f694e068028a717f8af6b9411f9a133dd3565258714cc226594b34db90c1f2c" + }, + "labels": [] + }, + "expected": { + "addresses": [ + "sp1qqgste7k9hx0qftg6qmwlkqtwuy6cycyavzmzj85c6qdfhjdpdjtdgqjuexzk6murw56suy3e0rd2cgqvycxttddwsvgxe2usfpxumr70xc9pkqwv" + ], + "outputs": [ + { + "priv_key_tweak": "688fa3aeb97d2a46ae87b03591921c2eaf4b505eb0ddca2733c94701e01060cf", + "pub_key": "67fee277da9e8542b5d2e6f32d660a9bbd3f0e107c2d53638ab1d869088882d6", + "signature": "72e7ad573ac23255d4651d5b0326a200496588acb7a4894b22092236d5eda6a0a9a4d8429b022c2219081fefce5b33795cae488d10f5ea9438849ed8353624f2" + } + ] + } + } + ] + }, + { + "comment": "Skip invalid P2SH inputs", + "sending": [ + { + "given": { + "vin": [ + { + "txid": "f4184fc596403b9d638783cf57adfe4c75c605f6356fbc91338530e9831e9e16", + "vout": 0, + "scriptSig": "16001419c2f3ae0ca3b642bd3e49598b8da89f50c14161", + "txinwitness": "02483046022100ad79e6801dd9a8727f342f31c71c4912866f59dc6e7981878e92c5844a0ce929022100fb0d2393e813968648b9753b7e9871d90ab3d815ebf91820d704b19f4ed224d621025a1e61f898173040e20616d43e9f496fba90338a39faa1ed98fcbaeee4dd9be5", + "prevout": { + "scriptPubKey": { + "hex": "a9148629db5007d5fcfbdbb466637af09daf9125969387" + } + }, + "private_key": "eadc78165ff1f8ea94ad7cfdc54990738a4c53f6e0507b42154201b8e5dff3b1" + }, + { + "txid": "f4184fc596403b9d638783cf57adfe4c75c605f6356fbc91338530e9831e9e16", + "vout": 1, + "scriptSig": "1600144b92ac4ac6fe6212393894addda332f2e47a3156", + "txinwitness": "02473045022100a8c61b2d470e393279d1ba54f254b7c237de299580b7fa01ffcc940442ecec4502201afba952f4e4661c40acde7acc0341589031ba103a307b886eb867b23b850b974104782eeb913431ca6e9b8c2fd80a5f72ed2024ef72a3c6fb10263c3799373233387c5343bf58e23269e903335b958a12182f9849297321e8d710e49a8727129cab", + "prevout": { + "scriptPubKey": { + "hex": "a9146c9bf136fbb7305fd99d771a95127fcf87dedd0d87" + } + }, + "private_key": "0378e95685b74565fa56751b84a32dfd18545d10d691641b8372e32164fad66a" + }, + { + "txid": "f4184fc596403b9d638783cf57adfe4c75c605f6356fbc91338530e9831e9e16", + "vout": 2, + "scriptSig": "00493046022100ad79e6801dd9a8727f342f31c71c4912866f59dc6e7981878e92c5844a0ce929022100fb0d2393e813968648b9753b7e9871d90ab3d815ebf91820d704b19f4ed224d601483045022100a8c61b2d470e393279d1ba54f254b7c237de299580b7fa01ffcc940442ecec4502201afba952f4e4661c40acde7acc0341589031ba103a307b886eb867b23b850b97014c695221025a1e61f898173040e20616d43e9f496fba90338a39faa1ed98fcbaeee4dd9be52103782eeb913431ca6e9b8c2fd80a5f72ed2024ef72a3c6fb10263c3799373233382102e0ec4f64b3fa2e463ccfcf4e856e37d5e1e20275bc89ec1def9eb098eff1f85d53ae", + "txinwitness": "", + "prevout": { + "scriptPubKey": { + "hex": "a9141044ddc6cea09e4ac40fbec2ba34ad62de6db25b87" + } + }, + "private_key": "eadc78165ff1f8ea94ad7cfdc54990738a4c53f6e0507b42154201b8e5dff3b1" + } + ], + "recipients": [ + "sp1qqgste7k9hx0qftg6qmwlkqtwuy6cycyavzmzj85c6qdfhjdpdjtdgqjuexzk6murw56suy3e0rd2cgqvycxttddwsvgxe2usfpxumr70xc9pkqwv" + ] + }, + "expected": { + "outputs": [ + [ + "67fee277da9e8542b5d2e6f32d660a9bbd3f0e107c2d53638ab1d869088882d6" + ] + ] + } + } + ], + "receiving": [ + { + "given": { + "vin": [ + { + "txid": "f4184fc596403b9d638783cf57adfe4c75c605f6356fbc91338530e9831e9e16", + "vout": 0, + "scriptSig": "16001419c2f3ae0ca3b642bd3e49598b8da89f50c14161", + "txinwitness": "02483046022100ad79e6801dd9a8727f342f31c71c4912866f59dc6e7981878e92c5844a0ce929022100fb0d2393e813968648b9753b7e9871d90ab3d815ebf91820d704b19f4ed224d621025a1e61f898173040e20616d43e9f496fba90338a39faa1ed98fcbaeee4dd9be5", + "prevout": { + "scriptPubKey": { + "hex": "a9148629db5007d5fcfbdbb466637af09daf9125969387" + } + } + }, + { + "txid": "f4184fc596403b9d638783cf57adfe4c75c605f6356fbc91338530e9831e9e16", + "vout": 1, + "scriptSig": "1600144b92ac4ac6fe6212393894addda332f2e47a3156", + "txinwitness": "02473045022100a8c61b2d470e393279d1ba54f254b7c237de299580b7fa01ffcc940442ecec4502201afba952f4e4661c40acde7acc0341589031ba103a307b886eb867b23b850b974104782eeb913431ca6e9b8c2fd80a5f72ed2024ef72a3c6fb10263c3799373233387c5343bf58e23269e903335b958a12182f9849297321e8d710e49a8727129cab", + "prevout": { + "scriptPubKey": { + "hex": "a9146c9bf136fbb7305fd99d771a95127fcf87dedd0d87" + } + } + }, + { + "txid": "f4184fc596403b9d638783cf57adfe4c75c605f6356fbc91338530e9831e9e16", + "vout": 2, + "scriptSig": "00493046022100ad79e6801dd9a8727f342f31c71c4912866f59dc6e7981878e92c5844a0ce929022100fb0d2393e813968648b9753b7e9871d90ab3d815ebf91820d704b19f4ed224d601483045022100a8c61b2d470e393279d1ba54f254b7c237de299580b7fa01ffcc940442ecec4502201afba952f4e4661c40acde7acc0341589031ba103a307b886eb867b23b850b97014c695221025a1e61f898173040e20616d43e9f496fba90338a39faa1ed98fcbaeee4dd9be52103782eeb913431ca6e9b8c2fd80a5f72ed2024ef72a3c6fb10263c3799373233382102e0ec4f64b3fa2e463ccfcf4e856e37d5e1e20275bc89ec1def9eb098eff1f85d53ae", + "txinwitness": "", + "prevout": { + "scriptPubKey": { + "hex": "a9141044ddc6cea09e4ac40fbec2ba34ad62de6db25b87" + } + } + } + ], + "outputs": [ + "67fee277da9e8542b5d2e6f32d660a9bbd3f0e107c2d53638ab1d869088882d6" + ], + "key_material": { + "spend_priv_key": "9d6ad855ce3417ef84e836892e5a56392bfba05fa5d97ccea30e266f540e08b3", + "scan_priv_key": "0f694e068028a717f8af6b9411f9a133dd3565258714cc226594b34db90c1f2c" + }, + "labels": [] + }, + "expected": { + "addresses": [ + "sp1qqgste7k9hx0qftg6qmwlkqtwuy6cycyavzmzj85c6qdfhjdpdjtdgqjuexzk6murw56suy3e0rd2cgqvycxttddwsvgxe2usfpxumr70xc9pkqwv" + ], + "outputs": [ + { + "priv_key_tweak": "688fa3aeb97d2a46ae87b03591921c2eaf4b505eb0ddca2733c94701e01060cf", + "pub_key": "67fee277da9e8542b5d2e6f32d660a9bbd3f0e107c2d53638ab1d869088882d6", + "signature": "72e7ad573ac23255d4651d5b0326a200496588acb7a4894b22092236d5eda6a0a9a4d8429b022c2219081fefce5b33795cae488d10f5ea9438849ed8353624f2" + } + ] + } + } + ] + }, + { + "comment": "Recipient ignores unrelated outputs", + "sending": [ + { + "given": { + "vin": [ + { + "txid": "f4184fc596403b9d638783cf57adfe4c75c605f6356fbc91338530e9831e9e16", + "vout": 0, + "scriptSig": "", + "txinwitness": "0140c459b671370d12cfb5acee76da7e3ba7cc29b0b4653e3af8388591082660137d087fdc8e89a612cd5d15be0febe61fc7cdcf3161a26e599a4514aa5c3e86f47b", + "prevout": { + "scriptPubKey": { + "hex": "51205a1e61f898173040e20616d43e9f496fba90338a39faa1ed98fcbaeee4dd9be5" + } + }, + "private_key": "eadc78165ff1f8ea94ad7cfdc54990738a4c53f6e0507b42154201b8e5dff3b1" + }, + { + "txid": "a1075db55d416d3ca199f55b6084e2115b9345e16c5cf302fc80e9d5fbf5d48d", + "vout": 0, + "scriptSig": "473045022100a8c61b2d470e393279d1ba54f254b7c237de299580b7fa01ffcc940442ecec4502201afba952f4e4661c40acde7acc0341589031ba103a307b886eb867b23b850b972103782eeb913431ca6e9b8c2fd80a5f72ed2024ef72a3c6fb10263c379937323338", + "txinwitness": "", + "prevout": { + "scriptPubKey": { + "hex": "76a9147cdd63cc408564188e8e472640e921c7c90e651d88ac" + } + }, + "private_key": "0378e95685b74565fa56751b84a32dfd18545d10d691641b8372e32164fad66a" + } + ], + "recipients": [ + "sp1qqgrz6j0lcqnc04vxccydl0kpsj4frfje0ktmgcl2t346hkw30226xqupawdf48k8882j0strrvcmgg2kdawz53a54dd376ngdhak364hzcmynqtn" + ] + }, + "expected": { + "outputs": [ + [ + "841792c33c9dc6193e76744134125d40add8f2f4a96475f28ba150be032d64e8" + ] + ] + } + } + ], + "receiving": [ + { + "given": { + "vin": [ + { + "txid": "f4184fc596403b9d638783cf57adfe4c75c605f6356fbc91338530e9831e9e16", + "vout": 0, + "scriptSig": "", + "txinwitness": "0140c459b671370d12cfb5acee76da7e3ba7cc29b0b4653e3af8388591082660137d087fdc8e89a612cd5d15be0febe61fc7cdcf3161a26e599a4514aa5c3e86f47b", + "prevout": { + "scriptPubKey": { + "hex": "51205a1e61f898173040e20616d43e9f496fba90338a39faa1ed98fcbaeee4dd9be5" + } + } + }, + { + "txid": "a1075db55d416d3ca199f55b6084e2115b9345e16c5cf302fc80e9d5fbf5d48d", + "vout": 0, + "scriptSig": "473045022100a8c61b2d470e393279d1ba54f254b7c237de299580b7fa01ffcc940442ecec4502201afba952f4e4661c40acde7acc0341589031ba103a307b886eb867b23b850b972103782eeb913431ca6e9b8c2fd80a5f72ed2024ef72a3c6fb10263c379937323338", + "txinwitness": "", + "prevout": { + "scriptPubKey": { + "hex": "76a9147cdd63cc408564188e8e472640e921c7c90e651d88ac" + } + } + } + ], + "outputs": [ + "841792c33c9dc6193e76744134125d40add8f2f4a96475f28ba150be032d64e8", + "782eeb913431ca6e9b8c2fd80a5f72ed2024ef72a3c6fb10263c379937323338" + ], + "key_material": { + "spend_priv_key": "9d6ad855ce3417ef84e836892e5a56392bfba05fa5d97ccea30e266f540e08b3", + "scan_priv_key": "0f694e068028a717f8af6b9411f9a133dd3565258714cc226594b34db90c1f2c" + }, + "labels": [] + }, + "expected": { + "addresses": [ + "sp1qqgste7k9hx0qftg6qmwlkqtwuy6cycyavzmzj85c6qdfhjdpdjtdgqjuexzk6murw56suy3e0rd2cgqvycxttddwsvgxe2usfpxumr70xc9pkqwv" + ], + "outputs": [] + } + } + ] + }, + { + "comment": "No valid inputs, sender generates no outputs", + "sending": [ + { + "given": { + "vin": [ + { + "txid": "f4184fc596403b9d638783cf57adfe4c75c605f6356fbc91338530e9831e9e16", + "vout": 0, + "scriptSig": "483046022100ad79e6801dd9a8727f342f31c71c4912866f59dc6e7981878e92c5844a0ce929022100fb0d2393e813968648b9753b7e9871d90ab3d815ebf91820d704b19f4ed224d641045a1e61f898173040e20616d43e9f496fba90338a39faa1ed98fcbaeee4dd9be5c61836c9b1688ba431f7ea3039742251f62f0dca3da1bee58a47fa9b456c2d52", + "txinwitness": "", + "prevout": { + "scriptPubKey": { + "hex": "76a914460e8b41545d2dbe7e0671f0f573e2232814260a88ac" + } + }, + "private_key": "eadc78165ff1f8ea94ad7cfdc54990738a4c53f6e0507b42154201b8e5dff3b1" + }, + { + "txid": "a1075db55d416d3ca199f55b6084e2115b9345e16c5cf302fc80e9d5fbf5d48d", + "vout": 0, + "scriptSig": "473045022100a8c61b2d470e393279d1ba54f254b7c237de299580b7fa01ffcc940442ecec4502201afba952f4e4661c40acde7acc0341589031ba103a307b886eb867b23b850b974104782eeb913431ca6e9b8c2fd80a5f72ed2024ef72a3c6fb10263c3799373233387c5343bf58e23269e903335b958a12182f9849297321e8d710e49a8727129cab", + "txinwitness": "", + "prevout": { + "scriptPubKey": { + "hex": "76a9144b92ac4ac6fe6212393894addda332f2e47a315688ac" + } + }, + "private_key": "0378e95685b74565fa56751b84a32dfd18545d10d691641b8372e32164fad66a" + } + ], + "recipients": [ + "sp1qqgste7k9hx0qftg6qmwlkqtwuy6cycyavzmzj85c6qdfhjdpdjtdgqjuexzk6murw56suy3e0rd2cgqvycxttddwsvgxe2usfpxumr70xc9pkqwv" + ] + }, + "expected": { + "outputs": [ + [] + ] + } + } + ], + "receiving": [ + { + "given": { + "vin": [ + { + "txid": "f4184fc596403b9d638783cf57adfe4c75c605f6356fbc91338530e9831e9e16", + "vout": 0, + "scriptSig": "483046022100ad79e6801dd9a8727f342f31c71c4912866f59dc6e7981878e92c5844a0ce929022100fb0d2393e813968648b9753b7e9871d90ab3d815ebf91820d704b19f4ed224d641045a1e61f898173040e20616d43e9f496fba90338a39faa1ed98fcbaeee4dd9be5c61836c9b1688ba431f7ea3039742251f62f0dca3da1bee58a47fa9b456c2d52", + "txinwitness": "", + "prevout": { + "scriptPubKey": { + "hex": "76a914460e8b41545d2dbe7e0671f0f573e2232814260a88ac" + } + } + }, + { + "txid": "a1075db55d416d3ca199f55b6084e2115b9345e16c5cf302fc80e9d5fbf5d48d", + "vout": 0, + "scriptSig": "473045022100a8c61b2d470e393279d1ba54f254b7c237de299580b7fa01ffcc940442ecec4502201afba952f4e4661c40acde7acc0341589031ba103a307b886eb867b23b850b974104782eeb913431ca6e9b8c2fd80a5f72ed2024ef72a3c6fb10263c3799373233387c5343bf58e23269e903335b958a12182f9849297321e8d710e49a8727129cab", + "txinwitness": "", + "prevout": { + "scriptPubKey": { + "hex": "76a9144b92ac4ac6fe6212393894addda332f2e47a315688ac" + } + } + } + ], + "outputs": [ + "782eeb913431ca6e9b8c2fd80a5f72ed2024ef72a3c6fb10263c379937323338", + "e0ec4f64b3fa2e463ccfcf4e856e37d5e1e20275bc89ec1def9eb098eff1f85d" + ], + "key_material": { + "spend_priv_key": "9d6ad855ce3417ef84e836892e5a56392bfba05fa5d97ccea30e266f540e08b3", + "scan_priv_key": "0f694e068028a717f8af6b9411f9a133dd3565258714cc226594b34db90c1f2c" + }, + "labels": [] + }, + "expected": { + "addresses": [ + "sp1qqgste7k9hx0qftg6qmwlkqtwuy6cycyavzmzj85c6qdfhjdpdjtdgqjuexzk6murw56suy3e0rd2cgqvycxttddwsvgxe2usfpxumr70xc9pkqwv" + ], + "outputs": [] + } + } + ] + } +] \ No newline at end of file From c2b27a0ce5e13ec5e68d658a7c815e8a045fd8d6 Mon Sep 17 00:00:00 2001 From: josibake Date: Mon, 19 Feb 2024 15:45:14 +0100 Subject: [PATCH 245/454] Update README --- README.mediawiki | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/README.mediawiki b/README.mediawiki index 0ce7b8e81f..5e077853fc 100644 --- a/README.mediawiki +++ b/README.mediawiki @@ -1107,6 +1107,13 @@ Those proposing changes should consider that ultimately consent may rest with th | Informational | Draft |- +| [[bip-0352.mediawiki|352]] +| Applications +| Silent Payments +| josibake, Ruben Somsen +| Standard +| Draft +|- | [[bip-0370.mediawiki|370]] | Applications | PSBT Version 2 From 0ccf42c869b77730b71b69dec4abc299d393a060 Mon Sep 17 00:00:00 2001 From: josie Date: Wed, 8 May 2024 17:36:46 +0200 Subject: [PATCH 246/454] Apply suggestions from code review Punctuation and wording improvements. Co-authored-by: Mark "Murch" Erhardt --- bip-0352.mediawiki | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/bip-0352.mediawiki b/bip-0352.mediawiki index 8f41bca299..9232d31960 100644 --- a/bip-0352.mediawiki +++ b/bip-0352.mediawiki @@ -23,9 +23,9 @@ This BIP is licensed under the BSD 2-clause license. === Motivation === -Using a new address for each Bitcoin transaction is a crucial aspect of maintaining privacy. This often requires a secure interaction between sender and receiver so that the receiver can hand out a fresh address, a batch of fresh addresses, or a method for the sender to generate addresses on-demand, such as an xpub. +Using a new address for each Bitcoin transaction is a crucial aspect of maintaining privacy. This often requires a secure interaction between sender and receiver, so that the receiver can hand out a fresh address, a batch of fresh addresses, or a method for the sender to generate addresses on-demand, such as an xpub. -However, interaction is often infeasible and in many cases undesirable. To solve for this, various protocols have been proposed which use a static payment address and notifications sent via the blockchain'''Why not use out-of-band notifications''' Out of band notifications (e.g. using something other than the Bitcoin blockchain) have been proposed as a way of addressing the privacy and cost concerns of using the Bitcoin blockchain as a messaging layer. This, however, simply moves the privacy and cost concerns somewhere else and increases the risk of losing money due to a notification not being reliably delivered, or even censored, and makes this notification data critical for backup to recover funds.. These protocols eliminate the need for interaction, but at the expense of increased costs for one-time payments and a noticeable footprint in the blockchain, potentially revealing metadata about the sender and receiver. Notification schemes also allow the receiver to link all payments from the same sender, compromising sender privacy. +However, interaction is often infeasible and in many cases undesirable. To solve for this, various protocols have been proposed which use a static payment address and notifications sent via the blockchain'''Why not use out-of-band notifications''' Out-of-band notifications (e.g. using something other than the Bitcoin blockchain) have been proposed as a way of addressing the privacy and cost concerns of using the Bitcoin blockchain as a messaging layer. This, however, simply moves the privacy and cost concerns somewhere else and increases the risk of losing money due to a notification not being reliably delivered, or even censored, and makes this notification data critical for backup to recover funds.. These protocols eliminate the need for interaction, but at the expense of increased costs for one-time payments and a noticeable footprint in the blockchain, potentially revealing metadata about the sender and receiver. Notification schemes also allow the receiver to link all payments from the same sender, compromising sender privacy. This proposal aims to address the limitations of these current approaches by presenting a solution that eliminates the need for interaction, eliminates the need for notifications, and protects both sender and receiver privacy. These benefits come at the cost of requiring wallets to scan the blockchain in order to detect payments. This added requirement is generally feasible for full nodes but poses a challenge for light clients. While it is possible today to implement a privacy-preserving light client at the cost of increased bandwidth, light client support is considered an area of open research (see [[#appendix-a-light-client-support|Appendix A: Light Client Support]]). @@ -140,7 +140,7 @@ For everything not defined above, we use the notation from [https://github.com/b === Versions === -This document defines version 0 (''sp1q''). Version is communicated through the address in the same way as Segwit addresses. Future upgrades to silent payments will require a new version. As much as possible, future upgrades should support receiving from older wallets (e.g. a silent payments v0 wallet can send to both v0 and v1 addresses). Any changes that break compatibility with older silent payment versions should be a new BIP. +This document defines version 0 (''sp1q''). Version is communicated through the address in the same way as bech32 addresses (see [[https://github.com/bitcoin/bips/blob/master/bip-0173.mediawiki#bech32 BIP173]]. Future upgrades to silent payments will require a new version. As much as possible, future upgrades should support receiving from older wallets (e.g. a silent payments v0 wallet can send to both v0 and v1 addresses). Any changes that break compatibility with older silent payment versions should be a new BIP. Future silent payments versions will use the following scheme: @@ -200,7 +200,7 @@ A silent payment address is constructed in the following manner: ** The human-readable part "sp" for mainnet, "tsp" for testnets (e.g. signet, testnet) ** The data-part values: *** The character "q", to represent a silent payment address of version 0 -*** The 66 byte concatenation of the receiver's public keys, ''serP(Bscan) || serP(Bm)'' +*** The 66-byte concatenation of the receiver's public keys, ''serP(Bscan) || serP(Bm)'' Note: [https://github.com/bitcoin/bips/blob/master/bip-0173.mediawiki BIP173] imposes a 90 character limit for Bech32 segwit addresses and limits versions to 0 through 16, whereas a silent payment address requires ''at least'' 117 characters ''' Why do silent payment addresses need at least 117 characters?''' A silent payment address is a bech32m encoding comprised of the following parts: @@ -212,7 +212,7 @@ Note: [https://github.com/bitcoin/bips/blob/master/bip-0173.mediawiki BIP173] im * checksum [6 characters] -For a silent payments v0 address, this results in a 117 character address when using a 3 character HRP. Future versions of silent payment addresses may add to the payload, which is why a 1023 character limit is suggested. and allows versions up to 31. Additionally, since higher versions may add to the data field, it is recommended implementations use a limit of 1023 characters (see [https://github.com/bitcoin/bips/blob/master/bip-0173.mediawiki#checksum-design BIP173: Checksum design] for more details). +For a silent payments v0 address, this results in a 117-character address when using a 3-character HRP. Future versions of silent payment addresses may add to the payload, which is why a 1023-character limit is suggested. and allows versions up to 31. Additionally, since higher versions may add to the data field, it is recommended implementations use a limit of 1023 characters (see [https://github.com/bitcoin/bips/blob/master/bip-0173.mediawiki#checksum-design BIP173: Checksum design] for more details). === Inputs For Shared Secret Derivation === From ef108e0e7751847bb837702ef62098231eb3da18 Mon Sep 17 00:00:00 2001 From: josibake Date: Wed, 8 May 2024 18:04:05 +0200 Subject: [PATCH 247/454] Add post-history --- bip-0352.mediawiki | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/bip-0352.mediawiki b/bip-0352.mediawiki index 9232d31960..94c16a15eb 100644 --- a/bip-0352.mediawiki +++ b/bip-0352.mediawiki @@ -9,6 +9,10 @@ Type: Standards Track Created: 2023-03-09 License: BSD-2-Clause + Post-History: 2022-03-13: https://gist.github.com/RubenSomsen/c43b79517e7cb701ebf77eec6dbb46b8 [gist] Original proposal + 2022-03-28: https://gnusha.org/pi/bitcoindev/CAPv7TjbXm953U2h+-12MfJ24YqOM5Kcq77_xFTjVK+R2nf-nYg@mail.gmail.com/ [bitcoin-dev] Silent Payments – Non-interactive private payments with no on-chain overhead + 2022-10-11: https://gnusha.org/pi/bitcoindev/P_21MLHGJicZ-hkbC4DGu86c5BtNKiH8spY4TOw5FJsfimdi_6VyHzU_y-s1mZsOcC2FA3EW_6w6W5qfV9dRK_7AvTAxDlwVfU-yhWZPEuo=@protonmail.com/ [bitcoin-dev] Silent Payment v4 (coinjoin support added) + 2023-08-04: https://gnusha.org/pi/bitcoindev/ZM03twumu88V2NFH@petertodd.org/ [bitcoin-dev] BIP-352 Silent Payments addresses should have an expiration time
== Introduction == From 9929215dcf47235bc8a54b8549c2f32f2987463c Mon Sep 17 00:00:00 2001 From: josibake Date: Wed, 8 May 2024 18:05:51 +0200 Subject: [PATCH 248/454] Change status to Proposed --- README.mediawiki | 4 ++-- bip-0352.mediawiki | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/README.mediawiki b/README.mediawiki index 5e077853fc..fdd27ac499 100644 --- a/README.mediawiki +++ b/README.mediawiki @@ -1106,13 +1106,13 @@ Those proposing changes should consider that ultimately consent may rest with th | Alfred Hodler, Clark Moody | Informational | Draft -|- +|- style="background-color: #ffffcf" | [[bip-0352.mediawiki|352]] | Applications | Silent Payments | josibake, Ruben Somsen | Standard -| Draft +| Proposed |- | [[bip-0370.mediawiki|370]] | Applications diff --git a/bip-0352.mediawiki b/bip-0352.mediawiki index 94c16a15eb..31d6443212 100644 --- a/bip-0352.mediawiki +++ b/bip-0352.mediawiki @@ -5,7 +5,7 @@ Author: josibake Ruben Somsen Comments-URI: https://github.com/bitcoin/bips/wiki/Comments:BIP-0352 - Status: Draft + Status: Proposed Type: Standards Track Created: 2023-03-09 License: BSD-2-Clause From 17e1d168e818c56bd0ecd634e51abbfd1df3b750 Mon Sep 17 00:00:00 2001 From: josibake Date: Wed, 8 May 2024 18:07:20 +0200 Subject: [PATCH 249/454] Minor fixups - Fix link - Add explanation for scalar multiplication - Spelling error in test section --- bip-0352.mediawiki | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/bip-0352.mediawiki b/bip-0352.mediawiki index 31d6443212..8a4da9dd68 100644 --- a/bip-0352.mediawiki +++ b/bip-0352.mediawiki @@ -54,7 +54,7 @@ We aim to present a protocol which satisfies the following properties: == Overview == -We first present an informal overview of the protocol. In what follows, uppercase letters represent public keys, lowercase letters represent private keys, ''||'' refers to byte concatenation, ''G'' represents the generator point for secp256k1, and ''n'' represents the curve order for secp256k1. Each section of the overview is incomplete on its own and is meant to build on the previous section in order to introduce and briefly explain each aspect of the protocol. For the full protocol specification, see [[#specification|Specification]]. +We first present an informal overview of the protocol. In what follows, uppercase letters represent public keys, lowercase letters represent private keys, ''||'' refers to byte concatenation, ''·'' refers to elliptic curve scalar multiplication, ''G'' represents the generator point for secp256k1, and ''n'' represents the curve order for secp256k1. Each section of the overview is incomplete on its own and is meant to build on the previous section in order to introduce and briefly explain each aspect of the protocol. For the full protocol specification, see [[#specification|Specification]]. ''' Simple case ''' @@ -144,7 +144,7 @@ For everything not defined above, we use the notation from [https://github.com/b === Versions === -This document defines version 0 (''sp1q''). Version is communicated through the address in the same way as bech32 addresses (see [[https://github.com/bitcoin/bips/blob/master/bip-0173.mediawiki#bech32 BIP173]]. Future upgrades to silent payments will require a new version. As much as possible, future upgrades should support receiving from older wallets (e.g. a silent payments v0 wallet can send to both v0 and v1 addresses). Any changes that break compatibility with older silent payment versions should be a new BIP. +This document defines version 0 (''sp1q''). Version is communicated through the address in the same way as bech32 addresses (see [https://github.com/bitcoin/bips/blob/master/bip-0173.mediawiki#bech32 BIP173]. Future upgrades to silent payments will require a new version. As much as possible, future upgrades should support receiving from older wallets (e.g. a silent payments v0 wallet can send to both v0 and v1 addresses). Any changes that break compatibility with older silent payment versions should be a new BIP. Future silent payments versions will use the following scheme: @@ -395,7 +395,7 @@ A [[bip-0352/send_and_receive_test_vectors.json|collection of test vectors in JS }, "expected": { "outputs": [], - "n_outouts": , + "n_outputs": , }, } From 3b77bc07fdda2c95f924d5760f8a0018c7195d4c Mon Sep 17 00:00:00 2001 From: Tim Ruffing Date: Thu, 9 May 2024 10:12:42 +0200 Subject: [PATCH 250/454] BIP324: Remove obsolete test vector file --- bip-0324/xswiftec_test_vectors.csv | 33 ------------------------------ 1 file changed, 33 deletions(-) delete mode 100644 bip-0324/xswiftec_test_vectors.csv diff --git a/bip-0324/xswiftec_test_vectors.csv b/bip-0324/xswiftec_test_vectors.csv deleted file mode 100644 index 985235fb6b..0000000000 --- a/bip-0324/xswiftec_test_vectors.csv +++ /dev/null @@ -1,33 +0,0 @@ -u,x,case0_t,case1_t,case2_t,case3_t,case4_t,case5_t,case6_t,case7_t -08da7c45cb204377e7e42249cda5713fa865116ddbb4cb5a1949b2e5b438a6ab,e087b707dabf2796b03b2fb4f976c3f2f5abb36110d00ef656432117f2c93f0a,,,,,,,, -0a6361b3a802f55cd5ae06101c88a1e216320fe11cc0cfe1d791eed08a1200fd,a0223bc98997647daf4d520129bdb66e4937a00d1533af1fa29645fb96fb5bb5,60a3ed14bd9df0bfb89ada9372a7b5790b123a66bf130f5788237e8cd5225de4,9c4ee4629f10220fda49532d0c859a539dec5148eefc78bf48d93d2828027a9c,fc5e72f042fd1792cbf88728a374a2cc1e03e1f9ec8813fa3692e497cfa7d5e6,cb39fac005f26dc0a383ea64cb9b3b0b26767f20232cae4486f32904df4f04e3,9f5c12eb42620f404765256c8d584a86f4edc59940ecf0a877dc81722add9e4b,63b11b9d60efddf025b6acd2f37a65ac6213aeb711038740b726c2d6d7fd8193,03a18d0fbd02e86d340778d75c8b5d33e1fc1e061377ec05c96d1b6730582649,34c6053ffa0d923f5c7c159b3464c4f4d98980dfdcd351bb790cd6fa20b0f74c -102b51b9765a56a3e899f7cf0ee38e5251f9c503b357b330a49183eb7b155604,102b51b9765a56a3e899f7cf0ee38e5251f9c503b357b330a49183eb7b155604,bdb5bd58ca96eae36147a6c55bc2bef2cee55a757ee193cb619edc8d3590f90a,bda953c1da02059350e740b83f59149628e0be50c24ac8dc6908a2225931b4a0,,,424a42a73569151c9eb8593aa43d410d311aa58a811e6c349e612371ca6f0325,4256ac3e25fdfa6caf18bf47c0a6eb69d71f41af3db5372396f75ddca6ce478f,, -2921a11f25dadaa24aa79a548e4e81508c2e5e56af2d833d65e2bcce448ce2f5,3a70c472406b83d9f1c4398b8ecef786499bc44a3b30c34ac30f2d8a418bffa3,b9c76c21d3fabb948fa0326bf9e999068e9eed56ee4e76cb81558aa26969c56c,ef7dd84338732a0cac3a8995f3bacf9b2896582b8d3317ed508e5d9a5a3447af,,,463893de2c05446b705fcd94061666f9716112a911b189347eaa755c969636c3,108227bcc78cd5f353c5766a0c453064d769a7d472cce812af71a264a5cbb480,, -33b67cb5385ceddad93d0ee960679041613bed34b8b4a5e6362fe7539ba2d3ce,0105c74958a165e016502eeb87835195505d89714c95272b6fa88fe6c60b33ac,,,069e1b3b155c6da989b9b6a8735bba3c5c1049dcf01fe4474772244db89cf9ca,c77b10bca540e95ee66c1f57ab6297787849a89b2b883116e700593e3c0fe66d,,,f961e4c4eaa39256764649578ca445c3a3efb6230fe01bb8b88ddbb147630265,3884ef435abf16a11993e0a8549d688787b65764d477cee918ffa6c0c3f015c2 -3a898eecdae167231275338e9a79153cbe53f7bf99943eeb72ee64e57bb58699,41ffd7362aaa7b90fe03936deeebe9afafd9c18967122d8f972db2c050d4f07b,60abf7ed2a7ffd3d2ac242a782331ea663d55ca157af994e5e964e9c79a0db40,3c3c39dc37753ab9160dfbc2e0596c3a5114784690caa1836e12036814453da3,adcd3f100de60723f127278998c591fbf081af8e0a77f2a9090bed67d8aa2aa3,,9f540812d58002c2d53dbd587dcce1599c2aa35ea85066b1a169b162865f20ef,c3c3c623c88ac546e9f2043d1fa693c5aeeb87b96f355e7c91edfc96ebbabe8c,5232c0eff219f8dc0ed8d876673a6e040f7e5071f5880d56f6f412972755d18c, -46e04d129d7b45d054469ce34e24069a1426b3e34f1b68a3d1bff1e070aee192,c6ce9611bd908c16eba5c599e5219de2d18d82c96aafb0180b23ee315513618f,,,,,,,, -47dc540c94ceb704a23875c11273e16bb0b8a87aed84de911f2133568115f254,13964717dbc998964d7c19ec3d9981fe1d4a9a80845552a98fb9352898532844,,,,,,,, -4cab73ce2a7e6220975001c8a354143267a3c1ce8bf7692313e654481e616a93,9114cf2edd3b53dbb6581290a5cca532db38b4e9ceeacc9b0437a0e49bf97211,903b600ed648d4ddc48f0f628829c8992c88fab44b692413fb8b3d783854f9a2,2952afe39557606d08c311345788a5071413580917207c86ea7cb829cf2f2c6d,05f414320d0c4004cff10f798c3fda6c4fc335b5a2db940993b3d78147a25c18,48e2531c7e3ec99f807210d6c5330114b4f04d7345535ca5a6e6abf478bdb723,6fc49ff129b72b223b70f09d77d63766d377054bb496dbec0474c286c7ab028d,d6ad501c6aa89f92f73ceecba8775af8ebeca7f6e8df8379158347d530d0cfc2,fa0bebcdf2f3bffb300ef08673c02593b03cca4a5d246bf66c4c287db85da017,b71dace381c136607f8def293accfeeb4b0fb28cbaaca35a5919540a8742450c -5aeca385d8b781825b07bbec7c858b7170426c88088935850bc13dd6402368a5,a5135c7a27487e7da4f84413837a748e8fbd9377f776ca7af43ec228bfdc938a,8da4f71fb2700758f623d73c24ac91747da43f2302fce16c8d438a769c63495f,6b8f345fc0a25a76455541ddbf2791ff4b943c98b16db2b6eb6cea94a6b19afb,,,725b08e04d8ff8a709dc28c3db536e8b825bc0dcfd031e9372bc7588639cb2d0,9470cba03f5da589baaabe2240d86e00b46bc3674e924d491493156a594e6134,, -707bf0b938f307b5c222e670598b865d5e1f8a8003df82c7abbf7c9f8fa4d720,8f840f46c70cf84a3ddd198fa67479a2a1e0757ffc207d385440835f705b250f,,,eab90fb459bace62d3ce8fbd69c9f1039f0627d0e93e2f42bffd87889cb236a4,157c26578b226c66daf8edfa56f7560f1131f41d1685175e6d76cc95b4f89f10,,,1546f04ba645319d2c31704296360efc60f9d82f16c1d0bd40027876634dc58b,ea83d9a874dd939925071205a908a9f0eece0be2e97ae8a1928933694b075d1f -766caa663e1025b9accd7ededd24fbc8193180e028eedae2f41d6bb0b1d36468,22825ee826f8b76c27220e43c79c884a8518bc20f4978cc15f83f9c48346a314,,,8fe95c178da66d1dd249ea6a4dc614a6d46d79c83cbc4beafee518090263e48a,7b044cb756eb207226db302ba05e164781c2f5161dccd72607282cb9ad86a282,,,7016a3e8725992e22db61595b239eb592b928637c343b415011ae7f5fd9c17a5,84fbb348a914df8dd924cfd45fa1e9b87e3d0ae9e23328d9f8d7d345527959ad -78a23af8da46b1b37e8767921a2d3f528fdc8eca37cea8aea775fd2b283d3776,73d5f35d96f3ce1ef5802ead8edc10787700c593b5e0ddcc3bfb2720b9d36de3,8465ad20bd0f2b4a2d37106769af46288a109bc10b527c3b033c930c0e4b1025,1b7f03bd2c915bb736622aec85601bcabec89268c98945e19a0de4126ed62524,,,7b9a52df42f0d4b5d2c8ef989650b9d775ef643ef4ad83c4fcc36cf2f1b4ec0a,e480fc42d36ea448c99dd5137a9fe43541376d973676ba1e65f21bec9129d70b,, -78b4be1f9eeef9da65c393e4385f67edd142709b400ca7d900bd952e0c3cf727,089329e17a58a91e71ffe6ddd851e8a352e85a29fcc289b34a3bfdeaf958fe91,,,6008d703955b38da0166bd975ad3535af3b701b2efdf653fc5e7e6eb6afff0a3,,,,9ff728fc6aa4c725fe994268a52caca50c48fe4d10209ac03a18191395000b8c, -7a2a7c0a81d1bd595dff09b918f8ecb5b5e8493654a4f83496956ed8eb017674,85d583f57e2e42a6a200f646e707134a4a17b6c9ab5b07cb696a912614fe85bb,,,,,,,, -913da1f8df6f8fd47593840d533ba0458cc9873996bf310460abb495b34c232a,a7803f8e02b70718443a06db502c67925640e936b3fa46dd2ed6b8f7c80fa329,67d916ba2cc154464d87ff4e0cfe3bb816b22a961831c2daf62597a8b0681e87,a4b84520f8853e5482ee7689732ed7dd7da59945d26edeee0bf5f55d3507192f,,,9826e945d33eabb9b27800b1f301c447e94dd569e7ce3d2509da68564f97dda8,5b47badf077ac1ab7d1189768cd12822825a66ba2d912111f40a0aa1caf8e300,, -96a296d224f285c67bee93c30f8a309157f0daa35dc5b87e410b78630a09cfc7,7684ab3b1a43e20a97a7b5520e5b5347841a7d95984fd76b2478a2b710f1a2ce,,,,,,,, -99be5efb88ca2013bd8e4eb035fd42d5245468fe9afa70d8ba9c1c419a48c4e8,08ee83ae5c7af0c9b2341e595fe347537272d94f2fe9f10b9a8f913279fc6230,,,,,,,, -9b4fb24edd6d1d8830e272398263cdbf026b97392cc35387b991dc0248a628f9,80e81d40a50b53712a8dac5f468b0903c05219544a56af70aa152ebf17887701,,,6e94af5a32ac100c5230f1e119c538742b7051934b02f3850522cff26bd32d97,e9bd309fbf041342311be3d5bab0b9d16c9f80c6640eb47e311d3178c2adc75d,,,916b50a5cd53eff3adcf0e1ee63ac78bd48fae6cb4fd0c7afadd300c942cce98,1642cf6040fbecbdcee41c2a454f462e93607f399bf14b81cee2ce863d5234d2 -9def996cb1ea87e596b6cadccca3839a352e99d9ce07e635cdb239f38ca294f8,294850a665ab014a0e75eb4b52ee66dd8a8d2b5e453074e58afacb5e019ee90a,b1a29367b95e1996f7e393fb389e7ace812d4135f6ddcdcd77467fc000dfca8c,a340aabc95b4000e3043ba6139178c450046c985fbf09676c440bc6430ddaa5b,4c4cd400d0be335dd651370c5565c2b742a298016212a8605187b3c0751a811e,d90fa208bbb5f3f6e16c5a42b419188ec1951c1eb358f04741b7b48df9e55f79,4e5d6c9846a1e669081c6c04c76185317ed2beca0922323288b9803eff2031a3,5cbf55436a4bfff1cfbc459ec6e873baffb9367a040f69893bbf439acf2251d4,b3b32bff2f41cca229aec8f3aa9a3d48bd5d67fe9ded579fae784c3e8ae57b11,26f05df7444a0c091e93a5bd4be6e7713e6ae3e14ca70fb8be484b71061a9cb6 -a2c4aed1cf757cd9a509734a267ffc7b1166b55f4c8f9c3e3550c56e743328fc,a2c4aed1cf757cd9a509734a267ffc7b1166b55f4c8f9c3e3550c56e743328fc,,,,,,,, -a8e437abf9c0e74dc6d51eabf2d261a00e785c7e21efeac1f322b610273ba066,5a64cce4be767964e7dba23e78e30149326c539353b647e0d5d7cc361943b13b,,,6f73bdd6b748790b5f788935ca02aee3b9e560c4ba6caf47d716fbde1dd6e92c,b1ff705694188e672f58c6a05eeecc379dd1b60fd3cb9f19fcb02b1d9cab4bc5,,,908c422948b786f4a08776ca35fd511c461a9f3b459350b828e90420e2291303,4e008fa96be77198d0a7395fa11133c8622e49f02c3460e6034fd4e16354b06a -bf60e4349cace6bce0d552e8d783428db66d0d649bd9e430a3627e2ee14ac839,409f1bcb635319431f2aad17287cbd724992f29b64261bcf5c9d81d01eb533f6,,,,,,,, -c0ba8a33ac67f44abff5984dfbb6f56c46b880ac2b86e1f23e7fa9c402c53ae7,4767c4cab0d08133980a8e66c3f93a055c8ae62f89a92f8dcfa47607cee0bc57,4c21052f5ffccadb4f707aa1cba828ef384d7861af1690c59d638dfee9f368e7,dbcc8fe22896478161452d44688a6b138050a4d0964470c175a521dcecc5519a,,,b3defad0a0033524b08f855e3457d710c7b2879e50e96f3a629c7200160c9348,2433701dd769b87e9ebad2bb977594ec7faf5b2f69bb8f3e8a5ade22133aaa95,, -cbe2268747c9c8072c7f9926f2288f270637dc55bb9d14d3368361d5e47d25be,0e4e25736b614910c4984843e606b1e229def08bfd672ab61e2707cde8248c6d,,,c30567184201fac8e1cb9e776d921e17d28cdb7333223abd1c8f860a16393df1,,,,3cfa98e7bdfe05371e346188926de1e82d73248cccddc542e37079f4e9c6be3e, -ceb827ad3d3884fd4d50ae6099d6d50c09a21e72ebd309708e8b69d93df19e55,a6a0c8c94462f16f1b92502c3d5f9d1618f12ffa756227d5b19b01b9373cd940,,,,,,,, -d57e9d4f5842134f140032eaf38b5333638e8c4b145fcf86a23d48d3e9acc0f8,2a8162b0a7bdecb0ebffcd150c74accc9c7173b4eba030795dc2b72b16533b37,349a9a592d2c56e5378ae869d646043fc09ffb8fe5fd9debd83a11274da08892,9875f58028cc991cafab9fb1183b350bc1d8d5ce5723813cc2b8434ed1a2100f,,,cb6565a6d2d3a91ac875179629b9fbc03f6004701a02621427c5eed7b25f739d,678a0a7fd73366e35054604ee7c4caf43e272a31a8dc7ec33d47bcb02e5dec20,, -d94e7f1e9bb1f8a9b90996ba12c461b84956f0e7f230145cc594c2f80b067aa0,b4f4632803cff65c013a566748cd3386d58cd3a28f5b4721056cbe9d278a67a4,,,fad51eda7d418ee2785df9f3788ac9152576312177fc0fd83c65036750581620,749259382784be63f86cc927a5defa6aa8cecb98e38d68f6b7a7e958303c94ad,,,052ae12582be711d87a2060c877536eada89cede8803f027c39afc97afa7e60f,8b6da6c7d87b419c079336d85a210595573134671c729709485816a6cfc36782 -e545d395bb3fd971f91bf9a2b6722831df704efae6c1aa9da0989ed0970b77bb,760486143a1d512da5219d3e5febc7c5c9990d21ca7a501ed23f86c91ddee4cf,,,090892960a84c69967fe5a5d014d3ca19173e4cb72a908586fbce9d1e531a265,42a47f65d00ff2004faa98865ee8ed4f8a9a5ddc9f75042d728de335664bb546,,,f6f76d69f57b39669801a5a2feb2c35e6e8c1b348d56f7a79043162d1ace59ca,bd5b809a2ff00dffb0556779a11712b07565a223608afbd28d721cc999b446e9 -e9f86cefcfd61558fe75da7d4ea48a6c82d93191c6d49579aab49f99e543dcad,5db7371325a7bb83b030691b2d87cd9f199f43d91e302568391ac48181b7cea6,,,,,,,, -eec4121f2a07b61aba16414812aa9afc39ab0a136360a5ace2240dc19b0464eb,0b623c5296c13218a1eb24e79d00b04bf15788f6c2f7ec100a4a16f1473124a2,,,,,,,, -f566cc6fccc657365c0197accf3a7d6f80f85209ff666ff774f4dcbc524aa842,0a9933903339a8c9a3fe685330c582907f07adf6009990088b0b2342adb553ed,3ab8dc4ecbc0441c685436ac0d76f16393769c353be6092bd6ec4ce094106bd8,3bd189b4ef3d1baa5610f2b14cb4a2b377eb171511e6f36ef6a05a2c7c52e368,1594764c6296402aadd123675d81f3505d35f2a52c52881568eadb7b675b53f0,c64fbf71138e66de8ce0abdf3b6f51d151ca8e1037ab5b979e62b2faa15be81c,c54723b1343fbbe397abc953f2890e9c6c8963cac419f6d42913b31e6bef9057,c42e764b10c2e455a9ef0d4eb34b5d4c8814e8eaee190c91095fa5d283ad18c7,ea6b89b39d69bfd5522edc98a27e0cafa2ca0d5ad3ad77ea9715248398a4a83f,39b0408eec719921731f5420c490ae2eae3571efc854a468619d4d045ea41413 From 99435fa0b5160f90242ed1cbe852fe17cf291cfb Mon Sep 17 00:00:00 2001 From: "@RandyMcMillan" Date: Fri, 10 May 2024 09:39:56 -0400 Subject: [PATCH 251/454] bip-0388.mediawiki:proof of registration --- bip-0388.mediawiki | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/bip-0388.mediawiki b/bip-0388.mediawiki index 4efc588106..511e27c275 100644 --- a/bip-0388.mediawiki +++ b/bip-0388.mediawiki @@ -85,7 +85,7 @@ Once a policy is registered, the hardware signing device can perform the typical * showing addresses on the secure screen; * sign transactions spending from a wallet, while correctly identifying change addresses and computing the transaction fees. -Before any of the actions mentioned above, the hardware signing device will retrieve the policy from its permanent storage if stateful; if stateless it will validate the _proof of registration_ before using the wallet policy provided by the client. +Before any of the actions mentioned above, the hardware signing device will retrieve the policy from its permanent storage if stateful; if stateless it will validate the '''proof of registration''' before using the wallet policy provided by the client. Once the previously registered policy is correctly identified and approved by the user (for example by showing its name), and as long as the policy registration was executed securely, hardware signing devices can provide a user experience similar to the usual one for single-signature transactions. From 3865057e2d5412e9fc7686447c5b377d8e3603ba Mon Sep 17 00:00:00 2001 From: Salvatore Ingala <6681844+bigspider@users.noreply.github.com> Date: Sat, 11 May 2024 12:17:54 +0200 Subject: [PATCH 252/454] Improve formatting --- bip-0388.mediawiki | 26 +++++++++++++------------- 1 file changed, 13 insertions(+), 13 deletions(-) diff --git a/bip-0388.mediawiki b/bip-0388.mediawiki index 511e27c275..7805145549 100644 --- a/bip-0388.mediawiki +++ b/bip-0388.mediawiki @@ -78,14 +78,14 @@ Before a new policy is used for the first time, the user will register a wallet # After inspecting the policy and comparing it with a trusted source (for example a printed backup), the user approves the policy. # If stateful, the hardware signing device persists the policy in its permanent memory; if stateless, it returns a "proof of registration". -The proof of registration will allow the hardware signer to verify that a certain policy was indeed previously approved by the user, and is therefore safe to use without repeating the expensive user verification procedure. The details of how to create a proof of registration are out of scope for this document; using a Message Authentication Code on a hash committing to the wallet policy, its name and any additional metadata is an effective solution if correctly executed. +The '''proof of registration''' will allow the hardware signer to verify that a certain policy was indeed previously approved by the user, and is therefore safe to use without repeating the expensive user verification procedure. The details of how to create a proof of registration are out of scope for this document; using a Message Authentication Code on a hash committing to the wallet policy, its name and any additional metadata is an effective solution if correctly executed. Once a policy is registered, the hardware signing device can perform the typical operations securely: * generating receive and change addresses; * showing addresses on the secure screen; * sign transactions spending from a wallet, while correctly identifying change addresses and computing the transaction fees. -Before any of the actions mentioned above, the hardware signing device will retrieve the policy from its permanent storage if stateful; if stateless it will validate the '''proof of registration''' before using the wallet policy provided by the client. +Before any of the actions mentioned above, the hardware signing device will retrieve the policy from its permanent storage if stateful; if stateless it will validate the proof of registration before using the wallet policy provided by the client. Once the previously registered policy is correctly identified and approved by the user (for example by showing its name), and as long as the policy registration was executed securely, hardware signing devices can provide a user experience similar to the usual one for single-signature transactions. @@ -140,7 +140,7 @@ A ''wallet descriptor template'' is a SCRIPT expression. The /** in the placeholder template represents commonly used paths for receive/change addresses, and is equivalent to <0;1>/*. -Note that while [[bip-0389.mediawiki|BIP-389]] allows multipath `/` expressions with an arbitrary number of options, this specification restricts it to exactly 2 choices (with the typical meaning of receive/change addresses). +Note that while [[bip-0389.mediawiki|BIP-389]] allows multipath / expressions with an arbitrary number of options, this specification restricts it to exactly 2 choices (with the typical meaning of receive/change addresses). The placeholder @i for some number ''i'' represents the ''i''-th key in the vector of key information items (which must be of size at least ''i + 1'', or the wallet policy is invalid). @@ -197,7 +197,7 @@ In order to allow supporting legacy derivation schemes (for example, using simpl However, care needs to be taken in view of the following considerations: -* Allowing derivation schemes with a different length or cardinality in the same wallet policy would make it difficult to guarantee that there are no repeated pubkeys for every possible address generated by the policy. For example, `@0/<0;1>/*` and `@1/*` would generate the same pubkeys if the second public key in the key information vector is one of the first two unhardened children of the first public key. This could cause malleability with potential security implications (for example, in policies containing miniscript). +* Allowing derivation schemes with a different length or cardinality in the same wallet policy would make it difficult to guarantee that there are no repeated pubkeys for every possible address generated by the policy. For example, @0/<0;1>/* and @1/* would generate the same pubkeys if the second public key in the key information vector is one of the first two unhardened children of the first public key. This could cause malleability with potential security implications (for example, in policies containing miniscript). * Allowing naked pubkeys with no /* suffix (for example a descriptor template like wsh(multi(2,@0,@1/<0;1>/*))) would cause a pubkey to be repeated in every output generated from the policy, which would result in a total loss of privacy. == Examples == @@ -226,42 +226,42 @@ Some miniscript policies in wsh: [[bip-0044.mediawiki|BIP-44]], first account Descriptor template: pkh(@0/**) Keys info: ["[6738736c/44'/0'/0']xpub6Br37sWxruYfT8ASpCjVHKGwgdnYFEn98DwiN76i2oyY6fgH1LAPmmDcF46xjxJr22gw4jmVjTE2E3URMnRPEPYyo1zoPSUba563ESMXCeb"] - Descriptor:pkh([6738736c/44'/0'/0']xpub6Br37sWxruYfT8ASpCjVHKGwgdnYFEn98DwiN76i2oyY6fgH1LAPmmDcF46xjxJr22gw4jmVjTE2E3URMnRPEPYyo1zoPSUba563ESMXCeb) + Descriptor: pkh([6738736c/44'/0'/0']xpub6Br37sWxruYfT8ASpCjVHKGwgdnYFEn98DwiN76i2oyY6fgH1LAPmmDcF46xjxJr22gw4jmVjTE2E3URMnRPEPYyo1zoPSUba563ESMXCeb)
[[bip-0049.mediawiki|BIP-49]], second account Descriptor template: sh(wpkh(@0/**)) Keys info: ["[6738736c/49'/0'/1']xpub6Bex1CHWGXNNwGVKHLqNC7kcV348FxkCxpZXyCWp1k27kin8sRPayjZUKDjyQeZzGUdyeAj2emoW5zStFFUAHRgd5w8iVVbLgZ7PmjAKAm9"] - Descriptor:sh(wpkh([6738736c/49'/0'/1']xpub6Bex1CHWGXNNwGVKHLqNC7kcV348FxkCxpZXyCWp1k27kin8sRPayjZUKDjyQeZzGUdyeAj2emoW5zStFFUAHRgd5w8iVVbLgZ7PmjAKAm9)) + Descriptor: sh(wpkh([6738736c/49'/0'/1']xpub6Bex1CHWGXNNwGVKHLqNC7kcV348FxkCxpZXyCWp1k27kin8sRPayjZUKDjyQeZzGUdyeAj2emoW5zStFFUAHRgd5w8iVVbLgZ7PmjAKAm9))
[[bip-0084.mediawiki|BIP-84]], third account Descriptor template: wpkh(@0/**) Keys info: ["[6738736c/84'/0'/2']xpub6CRQzb8u9dmMcq5XAwwRn9gcoYCjndJkhKgD11WKzbVGd932UmrExWFxCAvRnDN3ez6ZujLmMvmLBaSWdfWVn75L83Qxu1qSX4fJNrJg2Gt"] - Descriptor:wpkh([6738736c/84'/0'/2']xpub6CRQzb8u9dmMcq5XAwwRn9gcoYCjndJkhKgD11WKzbVGd932UmrExWFxCAvRnDN3ez6ZujLmMvmLBaSWdfWVn75L83Qxu1qSX4fJNrJg2Gt) + Descriptor: wpkh([6738736c/84'/0'/2']xpub6CRQzb8u9dmMcq5XAwwRn9gcoYCjndJkhKgD11WKzbVGd932UmrExWFxCAvRnDN3ez6ZujLmMvmLBaSWdfWVn75L83Qxu1qSX4fJNrJg2Gt)
[[bip-0086.mediawiki|BIP-86]], first account Descriptor template: tr(@0/**) Keys info: ["[6738736c/86'/0'/0']xpub6CryUDWPS28eR2cDyojB8G354izmx294BdjeSvH469Ty3o2E6Tq5VjBJCn8rWBgesvTJnyXNAJ3QpLFGuNwqFXNt3gn612raffLWfdHNkYL"] - Descriptor:tr([6738736c/86'/0'/0']xpub6CryUDWPS28eR2cDyojB8G354izmx294BdjeSvH469Ty3o2E6Tq5VjBJCn8rWBgesvTJnyXNAJ3QpLFGuNwqFXNt3gn612raffLWfdHNkYL) + Descriptor: tr([6738736c/86'/0'/0']xpub6CryUDWPS28eR2cDyojB8G354izmx294BdjeSvH469Ty3o2E6Tq5VjBJCn8rWBgesvTJnyXNAJ3QpLFGuNwqFXNt3gn612raffLWfdHNkYL)
[[bip-0048.mediawiki|BIP-48]] P2WSH multisig Descriptor template: wsh(sortedmulti(2,@0/**,@1/**)) Keys info: ["[6738736c/48'/0'/0'/2']xpub6FC1fXFP1GXLX5TKtcjHGT4q89SDRehkQLtbKJ2PzWcvbBHtyDsJPLtpLtkGqYNYZdVVAjRQ5kug9CsapegmmeRutpP7PW4u4wVF9JfkDhw", "[b2b1f0cf/48'/0'/0'/2']xpub6EWhjpPa6FqrcaPBuGBZRJVjzGJ1ZsMygRF26RwN932Vfkn1gyCiTbECVitBjRCkexEvetLdiqzTcYimmzYxyR1BZ79KNevgt61PDcukmC7"] - Descriptor:wsh(sortedmulti(2,[6738736c/48'/0'/0'/2']xpub6FC1fXFP1GXLX5TKtcjHGT4q89SDRehkQLtbKJ2PzWcvbBHtyDsJPLtpLtkGqYNYZdVVAjRQ5kug9CsapegmmeRutpP7PW4u4wVF9JfkDhw,[b2b1f0cf/48'/0'/0'/2']xpub6EWhjpPa6FqrcaPBuGBZRJVjzGJ1ZsMygRF26RwN932Vfkn1gyCiTbECVitBjRCkexEvetLdiqzTcYimmzYxyR1BZ79KNevgt61PDcukmC7)) + Descriptor: wsh(sortedmulti(2,[6738736c/48'/0'/0'/2']xpub6FC1fXFP1GXLX5TKtcjHGT4q89SDRehkQLtbKJ2PzWcvbBHtyDsJPLtpLtkGqYNYZdVVAjRQ5kug9CsapegmmeRutpP7PW4u4wVF9JfkDhw,[b2b1f0cf/48'/0'/0'/2']xpub6EWhjpPa6FqrcaPBuGBZRJVjzGJ1ZsMygRF26RwN932Vfkn1gyCiTbECVitBjRCkexEvetLdiqzTcYimmzYxyR1BZ79KNevgt61PDcukmC7))
Miniscript: A 3-of-3 that becomes a 2-of-3 after 90 days Descriptor template: wsh(thresh(3,pk(@0/**),s:pk(@1/**),s:pk(@2/**),sln:older(12960))) Keys info: ["[6738736c/48'/0'/0'/100']xpub6FC1fXFP1GXQpyRFfSE1vzzySqs3Vg63bzimYLeqtNUYbzA87kMNTcuy9ubr7MmavGRjW2FRYHP4WGKjwutbf1ghgkUW9H7e3ceaPLRcVwa", "[b2b1f0cf/44'/0'/0'/100']xpub6EYajCJHe2CK53RLVXrN14uWoEttZgrRSaRztujsXg7yRhGtHmLBt9ot9Pd5ugfwWEu6eWyJYKSshyvZFKDXiNbBcoK42KRZbxwjRQpm5Js", "[a666a867/44'/0'/0'/100']xpub6Dgsze3ujLi1EiHoCtHFMS9VLS1UheVqxrHGfP7sBJ2DBfChEUHV4MDwmxAXR2ayeytpwm3zJEU3H3pjCR6q6U5sP2p2qzAD71x9z5QShK2"] - Descriptor:wsh(thresh(3,pk([6738736c/48'/0'/0'/100']xpub6FC1fXFP1GXQpyRFfSE1vzzySqs3Vg63bzimYLeqtNUYbzA87kMNTcuy9ubr7MmavGRjW2FRYHP4WGKjwutbf1ghgkUW9H7e3ceaPLRcVwa/<0,1>/*),s:pk([b2b1f0cf/44'/0'/0'/100']xpub6EYajCJHe2CK53RLVXrN14uWoEttZgrRSaRztujsXg7yRhGtHmLBt9ot9Pd5ugfwWEu6eWyJYKSshyvZFKDXiNbBcoK42KRZbxwjRQpm5Js/<0,1>/*),s:pk([a666a867/44'/0'/0'/100']xpub6Dgsze3ujLi1EiHoCtHFMS9VLS1UheVqxrHGfP7sBJ2DBfChEUHV4MDwmxAXR2ayeytpwm3zJEU3H3pjCR6q6U5sP2p2qzAD71x9z5QShK2/<0,1>/*),sln:older(12960))) + Descriptor: wsh(thresh(3,pk([6738736c/48'/0'/0'/100']xpub6FC1fXFP1GXQpyRFfSE1vzzySqs3Vg63bzimYLeqtNUYbzA87kMNTcuy9ubr7MmavGRjW2FRYHP4WGKjwutbf1ghgkUW9H7e3ceaPLRcVwa/<0,1>/*),s:pk([b2b1f0cf/44'/0'/0'/100']xpub6EYajCJHe2CK53RLVXrN14uWoEttZgrRSaRztujsXg7yRhGtHmLBt9ot9Pd5ugfwWEu6eWyJYKSshyvZFKDXiNbBcoK42KRZbxwjRQpm5Js/<0,1>/*),s:pk([a666a867/44'/0'/0'/100']xpub6Dgsze3ujLi1EiHoCtHFMS9VLS1UheVqxrHGfP7sBJ2DBfChEUHV4MDwmxAXR2ayeytpwm3zJEU3H3pjCR6q6U5sP2p2qzAD71x9z5QShK2/<0,1>/*),sln:older(12960)))
Miniscript: A singlesig wallet with automatic inheritance to a timelocked 2-of-3 multisig Descriptor template: wsh(or_d(pk(@0/**),and_v(v:multi(2,@1/**,@2/**,@3/**),older(65535)))) Keys info: ["[6738736c/48'/0'/0'/100']xpub6FC1fXFP1GXQpyRFfSE1vzzySqs3Vg63bzimYLeqtNUYbzA87kMNTcuy9ubr7MmavGRjW2FRYHP4WGKjwutbf1ghgkUW9H7e3ceaPLRcVwa", "[b2b1f0cf/44'/0'/0'/100']xpub6EYajCJHe2CK53RLVXrN14uWoEttZgrRSaRztujsXg7yRhGtHmLBt9ot9Pd5ugfwWEu6eWyJYKSshyvZFKDXiNbBcoK42KRZbxwjRQpm5Js", "[a666a867/44'/0'/0'/100']xpub6Dgsze3ujLi1EiHoCtHFMS9VLS1UheVqxrHGfP7sBJ2DBfChEUHV4MDwmxAXR2ayeytpwm3zJEU3H3pjCR6q6U5sP2p2qzAD71x9z5QShK2", "[bb641298/44'/0'/0'/100']xpub6Dz8PHFmXkYkykQ83ySkruky567XtJb9N69uXScJZqweYiQn6FyieajdiyjCvWzRZ2GoLHMRE1cwDfuJZ6461YvNRGVBJNnLA35cZrQKSRJ"] - Descriptor:wsh(or_d(pk([6738736c/48'/0'/0'/100']xpub6FC1fXFP1GXQpyRFfSE1vzzySqs3Vg63bzimYLeqtNUYbzA87kMNTcuy9ubr7MmavGRjW2FRYHP4WGKjwutbf1ghgkUW9H7e3ceaPLRcVwa),and_v(v:multi(2,[b2b1f0cf/44'/0'/0'/100']xpub6EYajCJHe2CK53RLVXrN14uWoEttZgrRSaRztujsXg7yRhGtHmLBt9ot9Pd5ugfwWEu6eWyJYKSshyvZFKDXiNbBcoK42KRZbxwjRQpm5Js,[a666a867/44'/0'/0'/100']xpub6Dgsze3ujLi1EiHoCtHFMS9VLS1UheVqxrHGfP7sBJ2DBfChEUHV4MDwmxAXR2ayeytpwm3zJEU3H3pjCR6q6U5sP2p2qzAD71x9z5QShK2,[bb641298/44'/0'/0'/100']xpub6Dz8PHFmXkYkykQ83ySkruky567XtJb9N69uXScJZqweYiQn6FyieajdiyjCvWzRZ2GoLHMRE1cwDfuJZ6461YvNRGVBJNnLA35cZrQKSRJ),older(65535)))) + Descriptor: wsh(or_d(pk([6738736c/48'/0'/0'/100']xpub6FC1fXFP1GXQpyRFfSE1vzzySqs3Vg63bzimYLeqtNUYbzA87kMNTcuy9ubr7MmavGRjW2FRYHP4WGKjwutbf1ghgkUW9H7e3ceaPLRcVwa),and_v(v:multi(2,[b2b1f0cf/44'/0'/0'/100']xpub6EYajCJHe2CK53RLVXrN14uWoEttZgrRSaRztujsXg7yRhGtHmLBt9ot9Pd5ugfwWEu6eWyJYKSshyvZFKDXiNbBcoK42KRZbxwjRQpm5Js,[a666a867/44'/0'/0'/100']xpub6Dgsze3ujLi1EiHoCtHFMS9VLS1UheVqxrHGfP7sBJ2DBfChEUHV4MDwmxAXR2ayeytpwm3zJEU3H3pjCR6q6U5sP2p2qzAD71x9z5QShK2,[bb641298/44'/0'/0'/100']xpub6Dz8PHFmXkYkykQ83ySkruky567XtJb9N69uXScJZqweYiQn6FyieajdiyjCvWzRZ2GoLHMRE1cwDfuJZ6461YvNRGVBJNnLA35cZrQKSRJ),older(65535))))
Taproot wallet policy with sortedmulti_a and a miniscript leaf Descriptor template: tr(@0/**,{sortedmulti_a(1,@0/<2;3>/*,@1/**),or_b(pk(@2/**),s:pk(@3/**))}) Keys info: ["[6738736c/48'/0'/0'/100']xpub6FC1fXFP1GXQpyRFfSE1vzzySqs3Vg63bzimYLeqtNUYbzA87kMNTcuy9ubr7MmavGRjW2FRYHP4WGKjwutbf1ghgkUW9H7e3ceaPLRcVwa", "xpub6Fc2TRaCWNgfT49nRGG2G78d1dPnjhW66gEXi7oYZML7qEFN8e21b2DLDipTZZnfV6V7ivrMkvh4VbnHY2ChHTS9qM3XVLJiAgcfagYQk6K", "xpub6GxHB9kRdFfTqYka8tgtX9Gh3Td3A9XS8uakUGVcJ9NGZ1uLrGZrRVr67DjpMNCHprZmVmceFTY4X4wWfksy8nVwPiNvzJ5pjLxzPtpnfEM", "xpub6GjFUVVYewLj5no5uoNKCWuyWhQ1rKGvV8DgXBG9Uc6DvAKxt2dhrj1EZFrTNB5qxAoBkVW3wF8uCS3q1ri9fueAa6y7heFTcf27Q4gyeh6"] - Descriptor:tr([6738736c/48'/0'/0'/100']xpub6FC1fXFP1GXQpyRFfSE1vzzySqs3Vg63bzimYLeqtNUYbzA87kMNTcuy9ubr7MmavGRjW2FRYHP4WGKjwutbf1ghgkUW9H7e3ceaPLRcVwa/<0;1>/*,{sortedmulti_a(1,xpub6FC1fXFP1GXQpyRFfSE1vzzySqs3Vg63bzimYLeqtNUYbzA87kMNTcuy9ubr7MmavGRjW2FRYHP4WGKjwutbf1ghgkUW9H7e3ceaPLRcVwa/<2;3>/*,xpub6Fc2TRaCWNgfT49nRGG2G78d1dPnjhW66gEXi7oYZML7qEFN8e21b2DLDipTZZnfV6V7ivrMkvh4VbnHY2ChHTS9qM3XVLJiAgcfagYQk6K/<0;1>/*),or_b(pk(xpub6GxHB9kRdFfTqYka8tgtX9Gh3Td3A9XS8uakUGVcJ9NGZ1uLrGZrRVr67DjpMNCHprZmVmceFTY4X4wWfksy8nVwPiNvzJ5pjLxzPtpnfEM/<0;1>/*),s:pk(xpub6GjFUVVYewLj5no5uoNKCWuyWhQ1rKGvV8DgXBG9Uc6DvAKxt2dhrj1EZFrTNB5qxAoBkVW3wF8uCS3q1ri9fueAa6y7heFTcf27Q4gyeh6/<0;1>/*))}) + Descriptor: tr([6738736c/48'/0'/0'/100']xpub6FC1fXFP1GXQpyRFfSE1vzzySqs3Vg63bzimYLeqtNUYbzA87kMNTcuy9ubr7MmavGRjW2FRYHP4WGKjwutbf1ghgkUW9H7e3ceaPLRcVwa/<0;1>/*,{sortedmulti_a(1,xpub6FC1fXFP1GXQpyRFfSE1vzzySqs3Vg63bzimYLeqtNUYbzA87kMNTcuy9ubr7MmavGRjW2FRYHP4WGKjwutbf1ghgkUW9H7e3ceaPLRcVwa/<2;3>/*,xpub6Fc2TRaCWNgfT49nRGG2G78d1dPnjhW66gEXi7oYZML7qEFN8e21b2DLDipTZZnfV6V7ivrMkvh4VbnHY2ChHTS9qM3XVLJiAgcfagYQk6K/<0;1>/*),or_b(pk(xpub6GxHB9kRdFfTqYka8tgtX9Gh3Td3A9XS8uakUGVcJ9NGZ1uLrGZrRVr67DjpMNCHprZmVmceFTY4X4wWfksy8nVwPiNvzJ5pjLxzPtpnfEM/<0;1>/*),s:pk(xpub6GjFUVVYewLj5no5uoNKCWuyWhQ1rKGvV8DgXBG9Uc6DvAKxt2dhrj1EZFrTNB5qxAoBkVW3wF8uCS3q1ri9fueAa6y7heFTcf27Q4gyeh6/<0;1>/*))})
=== Invalid policies === @@ -281,7 +281,7 @@ Remark: some of the examples of invalid descriptor templates may be valid via op == Backwards Compatibility == -The @ character used for key placeholders is not part of the syntax of output script descriptors, therefore any valid descriptor with at least one `KEY` expression is not a valid descriptor template. Vice versa, any descriptor template with at least one key placeholder is not a valid output script descriptor. +The @ character used for key placeholders is not part of the syntax of output script descriptors, therefore any valid descriptor with at least one KEY expression is not a valid descriptor template. Vice versa, any descriptor template with at least one key placeholder is not a valid output script descriptor. Adoption of wallet policies in software and hardware wallets is opt-in. Conversion from wallet policies to the corresponding descriptors is programmatically extremely easy, and conversion from descriptors to wallet policies (when respecting the required patterns) can be automated. See the reference implementation below for some examples of conversion. From 1d7f12d36ab303ad750ca78404e3105822a56fcf Mon Sep 17 00:00:00 2001 From: Salvatore Ingala <6681844+bigspider@users.noreply.github.com> Date: Sun, 12 May 2024 11:43:24 +0200 Subject: [PATCH 253/454] Update BIP-388 status to 'Proposed' --- README.mediawiki | 4 ++-- bip-0388.mediawiki | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/README.mediawiki b/README.mediawiki index fdd27ac499..710e128e61 100644 --- a/README.mediawiki +++ b/README.mediawiki @@ -1190,13 +1190,13 @@ Those proposing changes should consider that ultimately consent may rest with th | Pieter Wuille, Ava Chow | Informational | Draft -|- +|- style="background-color: #ffffcf" | [[bip-0388.mediawiki|388]] | Applications | Wallet Policies for Descriptor Wallets | Salvatore Ingala | Standard -| Draft +| Proposed |- | [[bip-0389.mediawiki|389]] | Applications diff --git a/bip-0388.mediawiki b/bip-0388.mediawiki index 7805145549..a797643b2d 100644 --- a/bip-0388.mediawiki +++ b/bip-0388.mediawiki @@ -5,7 +5,7 @@ Author: Salvatore Ingala Comments-Summary: No comments yet. Comments-URI: https://github.com/bitcoin/bips/wiki/Comments:BIP-0388 - Status: Draft + Status: Proposed Type: Standards Track Created: 2022-11-16 License: BSD-2-Clause From e7fef46177e092b2122abad86d5bd02797a7c98b Mon Sep 17 00:00:00 2001 From: Jon Atack Date: Sun, 12 May 2024 10:56:34 -0600 Subject: [PATCH 254/454] bip-0388: fix 3 links --- bip-0388.mediawiki | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/bip-0388.mediawiki b/bip-0388.mediawiki index 511e27c275..93f84bc87b 100644 --- a/bip-0388.mediawiki +++ b/bip-0388.mediawiki @@ -65,7 +65,7 @@ We set two fundamental design goals: * Minimize the amount of information that is shown on screen - so that the user can actually validate it. * Minimize the number of times the user has to validate such information. -Designing a secure protocol for the coordination of a descriptor wallet among distant parties is also a challenging problem that is out of scope in this document. See [[bip-00129.mediawiki|BIP-129 (Bitcoin Secure Multisig Setup)]] for an approach designed for multisignature wallets. Regardless of the approach, the ability for the user to carefully verify all the details of the spending policies using the hardware signer's screen is a prerequisite for security in adversarial environments. +Designing a secure protocol for the coordination of a descriptor wallet among distant parties is also a challenging problem that is out of scope in this document. See [[bip-0129.mediawiki|BIP-129 (Bitcoin Secure Multisig Setup)]] for an approach designed for multisignature wallets. Regardless of the approach, the ability for the user to carefully verify all the details of the spending policies using the hardware signer's screen is a prerequisite for security in adversarial environments. === Policy registration as a solution === @@ -136,7 +136,7 @@ A ''wallet descriptor template'' is a SCRIPT expression. * ''always'' followed by either: ** the string /**, or ** a string of the form //*, for two distinct decimal numbers NUM representing unhardened derivations, or -** any of the additional, implementation-specific valid derivation path patterns (see [[#Optional_derivation_paths|Optional derivation paths]] below). +** any of the additional, implementation-specific valid derivation path patterns (see [[#optional-derivation-paths|Optional derivation paths]] below). The /** in the placeholder template represents commonly used paths for receive/change addresses, and is equivalent to <0;1>/*. @@ -294,7 +294,7 @@ Wallet policies are implemented in * the [https://github.com/digitalbitbox/bitbox02-firmware BitBox02 firmware] since version v9.15.0; * [https://github.com/Blockstream/Jade Blockstream Jade] since version v1.0.24, via [https://github.com/ElementsProject/libwally-core libwally-core] v1.0.0. -For development and testing purposes, we provide a [[bip-wallet-policies/wallet_policies.py|Python 3.7 reference implementation]] of simple classes to handle wallet policies, and the conversion to/from output script descriptors. +For development and testing purposes, we provide a [[bip-0388/wallet_policies.py|Python 3.7 reference implementation]] of simple classes to handle wallet policies, and the conversion to/from output script descriptors. The reference implementation is for demonstration purposes only and not to be used in production environments. ==Footnotes== From 4c689f7cf9f38c939416b2cda5ceea31c275b08c Mon Sep 17 00:00:00 2001 From: Jon Atack Date: Sun, 12 May 2024 10:57:45 -0600 Subject: [PATCH 255/454] bip-0388: make reference implementation executable --- bip-0388/wallet_policies.py | 2 ++ 1 file changed, 2 insertions(+) mode change 100644 => 100755 bip-0388/wallet_policies.py diff --git a/bip-0388/wallet_policies.py b/bip-0388/wallet_policies.py old mode 100644 new mode 100755 index 42f615a2b8..4cd5031087 --- a/bip-0388/wallet_policies.py +++ b/bip-0388/wallet_policies.py @@ -1,3 +1,5 @@ +#!/usr/bin/env python3 + from typing import Iterable, List, Mapping, Tuple, Generator From f4693dc0fd10163b0a9ed3ee74d4415e1ca4602c Mon Sep 17 00:00:00 2001 From: Jon Atack Date: Sun, 12 May 2024 11:22:34 -0600 Subject: [PATCH 256/454] bip352: fix link to coredev discussion --- bip-0352.mediawiki | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/bip-0352.mediawiki b/bip-0352.mediawiki index 8a4da9dd68..0eff355eea 100644 --- a/bip-0352.mediawiki +++ b/bip-0352.mediawiki @@ -486,7 +486,7 @@ Wallet designers can choose which tradeoffs they find appropriate. For example, == Acknowledgements == -This document is the result of many discussions and contains contributions by a number of people. The authors wish to thank all those who provided valuable feedback and reviews, including the participants of the [https://gist.github.com/RubenSomsen/21c477c90c942acf45f8e8f5c1ad4fae BIP47 Prague discussion], the [https://github.com/josibake/silent-payments-workshop Advancing Bitcoin silent payments Workshop], and [https://btctranscripts.com/bitcoin-core-dev-tech/2023-04-26-silent-payments/ coredev]. The authors would like to also thank [https://github.com/w0xlt w0xlt] for writing the initial implementation of silent payments. +This document is the result of many discussions and contains contributions by a number of people. The authors wish to thank all those who provided valuable feedback and reviews, including the participants of the [https://gist.github.com/RubenSomsen/21c477c90c942acf45f8e8f5c1ad4fae BIP47 Prague discussion], the [https://github.com/josibake/silent-payments-workshop Advancing Bitcoin silent payments Workshop], and [https://btctranscripts.com/bitcoin-core-dev-tech/2023-04/2023-04-26-silent-payments/ coredev]. The authors would like to also thank [https://github.com/w0xlt w0xlt] for writing the initial implementation of silent payments. == Rationale and References == From 2157872faa749e02e54d3a47ba9d17ebbefa5c21 Mon Sep 17 00:00:00 2001 From: Afanti <127061691+threewebcode@users.noreply.github.com> Date: Mon, 13 May 2024 10:25:31 +0800 Subject: [PATCH 257/454] bip-0114: fix typo --- bip-0114.mediawiki | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/bip-0114.mediawiki b/bip-0114.mediawiki index 410e84ccfd..5b0713747e 100644 --- a/bip-0114.mediawiki +++ b/bip-0114.mediawiki @@ -111,7 +111,7 @@ The advantages of the current proposal are: * If different parties in a contract do not want to expose their scripts to each other, they may provide only H(Subscript) and keep the Subscript private until redemption. * If they are willing to share the actual scripts, they may combine them into one Subscript for each branch, saving some nOpCount and a few bytes of witness space. -The are some disadvantages, but only when the redemption condition is very complicated: +There are some disadvantages, but only when the redemption condition is very complicated: * It may require more branches than a general MAST design (as shown in the previous example) and take more witness space in redemption * Creation and storage of the MAST structure may take more time and space. However, such additional costs affect only the related parties in the contract but not any other Bitcoin users. From 508e3a6a40a6e73c73cbfa8a33aa18a2bc7b9d91 Mon Sep 17 00:00:00 2001 From: siv2r Date: Sat, 11 May 2024 16:55:52 +0530 Subject: [PATCH 258/454] Fix the four test vectors - first two vectors of verify_fail_test - first two vectors of verify_error_test --- bip-0327.mediawiki | 2 ++ bip-0327/vectors/sign_verify_vectors.json | 8 ++++---- 2 files changed, 6 insertions(+), 4 deletions(-) diff --git a/bip-0327.mediawiki b/bip-0327.mediawiki index 07b40f53e7..5f29f83827 100644 --- a/bip-0327.mediawiki +++ b/bip-0327.mediawiki @@ -785,6 +785,8 @@ An exception to this rule is MAJOR version zero (0.y.z) which is fo The MINOR version is incremented whenever the inputs or the output of an algorithm changes in a backward-compatible way or new backward-compatible functionality is added. The PATCH version is incremented for other changes that are noteworthy (bug fixes, test vectors, important clarifications, etc.). +* '''1.0.1''' (2024-05-14): +** Fix minor issue in ''PartialSigVerify'' vectors. * '''1.0.0''' (2023-03-26): ** Number 327 was assigned to this BIP. * '''1.0.0-rc.4''' (2023-03-02): diff --git a/bip-0327/vectors/sign_verify_vectors.json b/bip-0327/vectors/sign_verify_vectors.json index b467640ce3..f71c8dd9d9 100644 --- a/bip-0327/vectors/sign_verify_vectors.json +++ b/bip-0327/vectors/sign_verify_vectors.json @@ -157,7 +157,7 @@ ], "verify_fail_test_cases": [ { - "sig": "97AC833ADCB1AFA42EBF9E0725616F3C9A0D5B614F6FE283CEAAA37A8FFAF406", + "sig": "FED54434AD4CFE953FC527DC6A5E5BE8F6234907B7C187559557CE87A0541C46", "key_indices": [0, 1, 2], "nonce_indices": [0, 1, 2], "msg_index": 0, @@ -165,7 +165,7 @@ "comment": "Wrong signature (which is equal to the negation of valid signature)" }, { - "sig": "68537CC5234E505BD14061F8DA9E90C220A181855FD8BDB7F127BB12403B4D3B", + "sig": "012ABBCB52B3016AC03AD82395A1A415C48B93DEF78718E62A7A90052FE224FB", "key_indices": [0, 1, 2], "nonce_indices": [0, 1, 2], "msg_index": 0, @@ -183,7 +183,7 @@ ], "verify_error_test_cases": [ { - "sig": "68537CC5234E505BD14061F8DA9E90C220A181855FD8BDB7F127BB12403B4D3B", + "sig": "012ABBCB52B3016AC03AD82395A1A415C48B93DEF78718E62A7A90052FE224FB", "key_indices": [0, 1, 2], "nonce_indices": [4, 1, 2], "msg_index": 0, @@ -196,7 +196,7 @@ "comment": "Invalid pubnonce" }, { - "sig": "68537CC5234E505BD14061F8DA9E90C220A181855FD8BDB7F127BB12403B4D3B", + "sig": "012ABBCB52B3016AC03AD82395A1A415C48B93DEF78718E62A7A90052FE224FB", "key_indices": [3, 1, 2], "nonce_indices": [0, 1, 2], "msg_index": 0, From 2f311cc629c872cca75279f8b3550eb60e2699d7 Mon Sep 17 00:00:00 2001 From: Chris Hyunhum Cho Date: Wed, 15 May 2024 11:51:28 +0900 Subject: [PATCH 259/454] bip-0322: add another valid sig vector not to confuse --- bip-0322.mediawiki | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/bip-0322.mediawiki b/bip-0322.mediawiki index 911d3c80f9..81ef896d3b 100644 --- a/bip-0322.mediawiki +++ b/bip-0322.mediawiki @@ -174,8 +174,8 @@ Given below parameters: Produce signatures: -* Message = "" (empty string): AkcwRAIgM2gBAQqvZX15ZiysmKmQpDrG83avLIT492QBzLnQIxYCIBaTpOaD20qRlEylyxFSeEA2ba9YOixpX8z46TSDtS40ASECx/EgAxlkQpQ9hYjgGu6EBCPMVPwVIVJqO4XCsMvViHI= -* Message = "Hello World": AkcwRAIgZRfIY3p7/DoVTty6YZbWS71bc5Vct9p9Fia83eRmw2QCICK/ENGfwLtptFluMGs2KsqoNSk89pO7F29zJLUx9a/sASECx/EgAxlkQpQ9hYjgGu6EBCPMVPwVIVJqO4XCsMvViHI= +* Message = "" (empty string): AkcwRAIgM2gBAQqvZX15ZiysmKmQpDrG83avLIT492QBzLnQIxYCIBaTpOaD20qRlEylyxFSeEA2ba9YOixpX8z46TSDtS40ASECx/EgAxlkQpQ9hYjgGu6EBCPMVPwVIVJqO4XCsMvViHI= or AkgwRQIhAPkJ1Q4oYS0htvyuSFHLxRQpFAY56b70UvE7Dxazen0ZAiAtZfFz1S6T6I23MWI2lK/pcNTWncuyL8UL+oMdydVgzAEhAsfxIAMZZEKUPYWI4BruhAQjzFT8FSFSajuFwrDL1Yhy +* Message = "Hello World": AkcwRAIgZRfIY3p7/DoVTty6YZbWS71bc5Vct9p9Fia83eRmw2QCICK/ENGfwLtptFluMGs2KsqoNSk89pO7F29zJLUx9a/sASECx/EgAxlkQpQ9hYjgGu6EBCPMVPwVIVJqO4XCsMvViHI= or AkgwRQIhAOzyynlqt93lOKJr+wmmxIens//zPzl9tqIOua93wO6MAiBi5n5EyAcPScOjf1lAqIUIQtr3zKNeavYabHyR8eGhowEhAsfxIAMZZEKUPYWI4BruhAQjzFT8FSFSajuFwrDL1Yhy === Transaction Hashes === From 4c08e2c0bfa931f0e06a008b3c21a43c92414db3 Mon Sep 17 00:00:00 2001 From: Marnix <93143998+MarnixCroes@users.noreply.github.com> Date: Thu, 13 Apr 2023 12:20:13 +0200 Subject: [PATCH 260/454] BIP38: remove dead links --- bip-0038.mediawiki | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/bip-0038.mediawiki b/bip-0038.mediawiki index 511b55adc2..bf3d09436e 100644 --- a/bip-0038.mediawiki +++ b/bip-0038.mediawiki @@ -47,12 +47,12 @@ This proposal makes use of the following functions and definitions: *'''AES256Encrypt, AES256Decrypt''': the simple form of the well-known AES block cipher without consideration for initialization vectors or block chaining. Each of these functions takes a 256-bit key and 16 bytes of input, and deterministically yields 16 bytes of output. *'''SHA256''', a well-known hashing algorithm that takes an arbitrary number of bytes as input and deterministically yields a 32-byte hash. *'''scrypt''': A well-known key derivation algorithm. It takes the following parameters: (string) password, (string) salt, (int) n, (int) r, (int) p, (int) length, and deterministically yields an array of bytes whose length is equal to the length parameter. -*'''ECMultiply''': Multiplication of an elliptic curve point by a scalar integer with respect to the [[secp256k1]] elliptic curve. -*'''G, N''': Constants defined as part of the [[secp256k1]] elliptic curve. G is an elliptic curve point, and N is a large positive integer. -*'''[[Base58Check]]''': a method for encoding arrays of bytes using 58 alphanumeric characters commonly used in the Bitcoin ecosystem. +*'''ECMultiply''': Multiplication of an elliptic curve point by a scalar integer with respect to the secp256k1 elliptic curve. +*'''G, N''': Constants defined as part of the secp256k1 elliptic curve. G is an elliptic curve point, and N is a large positive integer. +*'''Base58Check''': a method for encoding arrays of bytes using 58 alphanumeric characters commonly used in the Bitcoin ecosystem. ===Prefix=== -It is proposed that the resulting Base58Check-encoded string start with a '6'. The number '6' is intended to represent, from the perspective of the user, "a private key that needs something else to be usable" - an umbrella definition that could be understood in the future to include keys participating in multisig transactions, and was chosen with deference to the existing prefix '5' most commonly observed in [[Wallet Import Format]] which denotes an unencrypted private key. +It is proposed that the resulting Base58Check-encoded string start with a '6'. The number '6' is intended to represent, from the perspective of the user, "a private key that needs something else to be usable" - an umbrella definition that could be understood in the future to include keys participating in multisig transactions, and was chosen with deference to the existing prefix '5' most commonly observed in Wallet Import Format which denotes an unencrypted private key. It is proposed that the second character ought to give a hint as to what is needed as a second factor, and for an encrypted key requiring a passphrase, the uppercase letter P is proposed. @@ -184,7 +184,7 @@ To recalculate the address: # Hash the Bitcoin address, and verify that ''addresshash'' from the encrypted private key record matches the hash. If not, report that the passphrase entry was incorrect. ==Backwards compatibility== -Backwards compatibility is minimally applicable since this is a new standard that at most extends [[Wallet Import Format]]. It is assumed that an entry point for private key data may also accept existing formats of private keys (such as hexadecimal and [[Wallet Import Format]]); this draft uses a key format that cannot be mistaken for any existing one and preserves auto-detection capabilities. +Backwards compatibility is minimally applicable since this is a new standard that at most extends Wallet Import Format. It is assumed that an entry point for private key data may also accept existing formats of private keys (such as hexadecimal and Wallet Import Format); this draft uses a key format that cannot be mistaken for any existing one and preserves auto-detection capabilities. ==Suggestions for implementers of proposal with alt-chains== If this proposal is accepted into alt-chains, it is requested that the unused flag bytes not be used for denoting that the key belongs to an alt-chain. From 05e2c0c12f1e37dbe031994e74d8deb390868dc7 Mon Sep 17 00:00:00 2001 From: theborakompanioni Date: Thu, 23 May 2024 14:16:38 +0200 Subject: [PATCH 261/454] chore(bip-0046): rename bip-fidelity-bonds to bip-0046 --- bip-fidelity-bonds.mediawiki => bip-0046.mediawiki | 0 1 file changed, 0 insertions(+), 0 deletions(-) rename bip-fidelity-bonds.mediawiki => bip-0046.mediawiki (100%) diff --git a/bip-fidelity-bonds.mediawiki b/bip-0046.mediawiki similarity index 100% rename from bip-fidelity-bonds.mediawiki rename to bip-0046.mediawiki From 8e109f98de1dcbc8395d138f693ed42114eeefca Mon Sep 17 00:00:00 2001 From: theborakompanioni Date: Thu, 23 May 2024 14:18:08 +0200 Subject: [PATCH 262/454] docs(bip-0046): add bip number to header section --- bip-0046.mediawiki | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/bip-0046.mediawiki b/bip-0046.mediawiki index 571eca2e77..b5088fcff9 100644 --- a/bip-0046.mediawiki +++ b/bip-0046.mediawiki @@ -1,5 +1,5 @@
-  BIP: TBD. Preferably a two-digit number to match the bip44, bip49, bip84, bip86 family of bips
+  BIP: 46
   Layer: Applications
   Title: Derivation scheme for timelocked address fidelity bond based accounts
   Author: Chris Belcher 

From 64f93a239d24f6abbaa0345b190585bbaa8aa595 Mon Sep 17 00:00:00 2001
From: theborakompanioni 
Date: Thu, 23 May 2024 14:21:40 +0200
Subject: [PATCH 263/454] chore(bip-0046): fix typos and grammar

---
 bip-0046.mediawiki | 12 ++++++------
 1 file changed, 6 insertions(+), 6 deletions(-)

diff --git a/bip-0046.mediawiki b/bip-0046.mediawiki
index b5088fcff9..e456604271 100644
--- a/bip-0046.mediawiki
+++ b/bip-0046.mediawiki
@@ -23,7 +23,7 @@ It would be useful to have a common derivation scheme so that users of wallet so
 
 We largely use the same approach used in BIPs 49, 84 and 86 for ease of implementation.
 
-This standard is already implemented and deployed in JoinMarket. As most changes would requires a protocol change of a live system, there is limited scope for changing this standard in review. This BIP is more about documenting something which already exists, warts and all.
+This standard is already implemented and deployed in JoinMarket. As most changes would require a protocol change of a live system, there is limited scope for changing this standard in review. This BIP is more about documenting something which already exists, warts and all.
 
 It would be useful to be able to keep the private keys of fidelity bonds in cold storage. This would allow the sybil resistance of a system to increase without hot wallet risk.
 
@@ -52,7 +52,7 @@ It would be useful for the user to avoid having to keep a record of the timelock
 
 == Specifications ==
 
-This BIP defines the two needed steps to derive multiple deterministic addresses based on a [[bip-0032.mediawiki|BIP 32]] master private key. It also defines the format of the certificate can be signed by the deterministic address key.
+This BIP defines the two needed steps to derive multiple deterministic addresses based on a [[bip-0032.mediawiki|BIP 32]] master private key. It also defines the format of the certificate that can be signed by the deterministic address key.
 
 === Public key derivation ===
 
@@ -79,9 +79,9 @@ month = 1 + index % 12
 
 === Address derivation ===
 
-To derive the address from the above calculated public key and timelock, we create a redeemScript which locks the funds until the timelock, and then checks the signature of the derived_key. The redeemScript is hashed with SHA256 to produce a 32-byte hash value that forms the scriptPubKey of the P2WSH address.
+To derive the address from the above calculated public key and timelock, we create a witness script which locks the funds until the timelock, and then checks the signature of the derived_key. The witness script is hashed with SHA256 to produce a 32-byte hash value that forms the scriptPubKey of the P2WSH address.
 
-    redeemScript:  OP_CHECKLOCKTIMEVERIFY OP_DROP  OP_CHECKSIG
+    witnessScript:  OP_CHECKLOCKTIMEVERIFY OP_DROP  OP_CHECKSIG
     witness:       
     scriptSig:    (empty)
     scriptPubKey: 0 <32-byte-hash>
@@ -89,11 +89,11 @@ To derive the address from the above calculated public key and timelock, we crea
 
 === Message signing ===
 
-In order to support signing of certificates, implementors should support signing ascii messages.
+In order to support signing of certificates, implementors should support signing ASCII messages.
 
 A certificate message can be created by another application external to this standard. It is then prepended with the string `\x18Bitcoin Signed Message:\n` and a byte denoting the length of the certificate message. The whole thing is then signed with the private key of the derived_key. This part is identical to the "Sign Message" function which many wallets already implement.
 
-Almost all wallets implementing this standard can use their already-existing "Sign Message" function to sign the certificate message. As the certificate message itself is always an ascii string, the wallet may not need to specially implement this section at all but just rely on users copypasting their certificate message into the already-existing "Sign Message" user interface. This works as long as the wallet knows how to use the private key of the timelocked address for signing messages.
+Almost all wallets implementing this standard can use their already-existing "Sign Message" function to sign the certificate message. As the certificate message itself is always an ASCII string, the wallet may not need to specially implement this section at all but just rely on users copypasting their certificate message into the already-existing "Sign Message" user interface. This works as long as the wallet knows how to use the private key of the timelocked address for signing messages.
 
 It is most important for wallet implementions of this standard to support creating the certificate signature. Verifying the certificate signature is less important.
 

From 03a679958aedf1e152b96286571724c0199a1fc5 Mon Sep 17 00:00:00 2001
From: theborakompanioni 
Date: Thu, 23 May 2024 14:23:44 +0200
Subject: [PATCH 264/454] docs(bip-0046): change title to 'Address Scheme for
 Timelocked Fidelity Bonds'

---
 bip-0046.mediawiki | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/bip-0046.mediawiki b/bip-0046.mediawiki
index e456604271..1b85dccb10 100644
--- a/bip-0046.mediawiki
+++ b/bip-0046.mediawiki
@@ -1,7 +1,7 @@
 
   BIP: 46
   Layer: Applications
-  Title: Derivation scheme for timelocked address fidelity bond based accounts
+  Title: Address Scheme for Timelocked Fidelity Bonds
   Author: Chris Belcher 
   Status: Draft
   Type: Standards Track

From 57f1fe3f4bc902e828041ad329ecd025d847ae7d Mon Sep 17 00:00:00 2001
From: theborakompanioni 
Date: Thu, 23 May 2024 14:24:42 +0200
Subject: [PATCH 265/454] chore(bip-0046): remove (optional) Comments-Summary
 header

---
 bip-0046.mediawiki | 1 -
 1 file changed, 1 deletion(-)

diff --git a/bip-0046.mediawiki b/bip-0046.mediawiki
index 1b85dccb10..e179d93767 100644
--- a/bip-0046.mediawiki
+++ b/bip-0046.mediawiki
@@ -5,7 +5,6 @@
   Author: Chris Belcher 
   Status: Draft
   Type: Standards Track
-  Comments-Summary: No comments yet.
   Created: 2022-04-01
   License: CC0-1.0
   Post-History: 2022-5-1: https://lists.linuxfoundation.org/pipermail/bitcoin-dev/2022-May/020389.html

From 5209a28c1a25a853b0d5afbd90136a446484715d Mon Sep 17 00:00:00 2001
From: theborakompanioni 
Date: Thu, 23 May 2024 14:27:20 +0200
Subject: [PATCH 266/454] docs(bip-0046): add Comments-URI header

---
 bip-0046.mediawiki | 1 +
 1 file changed, 1 insertion(+)

diff --git a/bip-0046.mediawiki b/bip-0046.mediawiki
index e179d93767..0766796d90 100644
--- a/bip-0046.mediawiki
+++ b/bip-0046.mediawiki
@@ -3,6 +3,7 @@
   Layer: Applications
   Title: Address Scheme for Timelocked Fidelity Bonds
   Author: Chris Belcher 
+  Comments-URI: https://github.com/bitcoin/bips/wiki/Comments:BIP-0046
   Status: Draft
   Type: Standards Track
   Created: 2022-04-01

From 164412d08b7c67cf5a9b7282a4aa2a15863fa40d Mon Sep 17 00:00:00 2001
From: theborakompanioni 
Date: Thu, 23 May 2024 14:30:48 +0200
Subject: [PATCH 267/454] docs(bip-0046): add Copyright section

---
 bip-0046.mediawiki | 4 ++++
 1 file changed, 4 insertions(+)

diff --git a/bip-0046.mediawiki b/bip-0046.mediawiki
index 0766796d90..190c9caf60 100644
--- a/bip-0046.mediawiki
+++ b/bip-0046.mediawiki
@@ -15,6 +15,10 @@
 
 This BIP defines the derivation scheme for HD wallets which create timelocked addresses used for creating fidelity bonds. It also defines how to sign fidelity bond certificates, which are needed when using fidelity bonds that are stored offline.
 
+== Copyright ==
+
+This document is placed in the public domain.
+
 == Motivation ==
 
 Fidelity bonds are used to resist sybil attacks in certain decentralized anonymous protocols. They are created by locking up bitcoins using the `OP_CHECKLOCKTIMEVERIFY` opcode.

From 00c7d0b8151046bd4058deaabf67fbc48b8c05a3 Mon Sep 17 00:00:00 2001
From: theborakompanioni 
Date: Thu, 23 May 2024 15:48:23 +0200
Subject: [PATCH 268/454] fix(bip-0046): change license from Public Domain to
 CC0-1.0

---
 bip-0046.mediawiki | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/bip-0046.mediawiki b/bip-0046.mediawiki
index 190c9caf60..ea006664d0 100644
--- a/bip-0046.mediawiki
+++ b/bip-0046.mediawiki
@@ -17,7 +17,7 @@ This BIP defines the derivation scheme for HD wallets which create timelocked ad
 
 == Copyright ==
 
-This document is placed in the public domain.
+This document is licensed under the Creative Commons CC0 1.0 Universal license.
 
 == Motivation ==
 

From f9d370d3da35a242a6568179aee8d7ab66b37e69 Mon Sep 17 00:00:00 2001
From: theborakompanioni 
Date: Thu, 23 May 2024 15:52:46 +0200
Subject: [PATCH 269/454] chore(bip-0046): scriptPubKey -> witness programm

---
 bip-0046.mediawiki | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/bip-0046.mediawiki b/bip-0046.mediawiki
index ea006664d0..7f2ef5e6fb 100644
--- a/bip-0046.mediawiki
+++ b/bip-0046.mediawiki
@@ -83,7 +83,7 @@ month = 1 + index % 12
 
 === Address derivation ===
 
-To derive the address from the above calculated public key and timelock, we create a witness script which locks the funds until the timelock, and then checks the signature of the derived_key. The witness script is hashed with SHA256 to produce a 32-byte hash value that forms the scriptPubKey of the P2WSH address.
+To derive the address from the above calculated public key and timelock, we create a witness script which locks the funds until the timelock, and then checks the signature of the derived_key. The witness script is hashed with SHA256 to produce a 32-byte hash value that forms the witness program in the output script of the P2WSH address.
 
     witnessScript:  OP_CHECKLOCKTIMEVERIFY OP_DROP  OP_CHECKSIG
     witness:       

From 04d3a0609b548805fa2ebaf5d3a495f1b81a003c Mon Sep 17 00:00:00 2001
From: glozow 
Date: Mon, 15 Jan 2024 16:26:55 +0000
Subject: [PATCH 270/454] Define BIP431: TRUCs

---
 README.mediawiki   |   7 ++
 bip-0431.mediawiki | 291 +++++++++++++++++++++++++++++++++++++++++++++
 2 files changed, 298 insertions(+)
 create mode 100644 bip-0431.mediawiki

diff --git a/README.mediawiki b/README.mediawiki
index 815e8c3c67..41c729d4b4 100644
--- a/README.mediawiki
+++ b/README.mediawiki
@@ -1155,6 +1155,13 @@ Those proposing changes should consider that ultimately consent may rest with th
 | Pieter Wuille, Andrew Chow
 | Informational
 | Draft
+|-
+| [[bip-0431.mediawiki|431]]
+| Applications
+| Topology Restrictions for Pinning
+| Gloria Zhao
+| Informational
+| Draft
 |}
 
 
diff --git a/bip-0431.mediawiki b/bip-0431.mediawiki
new file mode 100644
index 0000000000..2af0e53c26
--- /dev/null
+++ b/bip-0431.mediawiki
@@ -0,0 +1,291 @@
+
+  BIP: 431
+  Layer: Applications
+  Title: Topology Restrictions for Pinning
+  Author: Gloria Zhao 
+  Comments-URI: https://github.com/bitcoin/bips/wiki/Comments:BIP-0431
+  Status: Draft
+  Type: Informational
+  Created: 2024-01-10
+  License: BSD-3-Clause
+  Post-History: 2022-01-27: https://lists.linuxfoundation.org/pipermail/bitcoin-dev/2022-January/019817.html [bitcoin-dev] discussion
+                2022-01-27: https://gist.github.com/glozow/25d9662c52453bd08b4b4b1d3783b9ff gist discussion
+                2022-09-23: https://lists.linuxfoundation.org/pipermail/bitcoin-dev/2022-September/020937.html [bitcoin-dev] proposal
+                2024-01-02: https://delvingbitcoin.org/t/v3-transaction-policy-for-anti-pinning/340 Delving Bitcoin post
+                2024-01-16: https://delvingbitcoin.org/t/lightning-transactions-with-v3-and-ephemeral-anchors/418 Delving Bitcoin post
+
+ +==Abstract== + +This document describes pinning problems that can arise from limitations in mempool policy. + +It also describes a type of policy with adjusted topology limits which, combined with other policy rules, helps minimize the potential pinning problems. These restrictions simplify the assessment of incentive compatibility of accepting or replacing such transactions, thus helping ensure any replacements are more profitable for the node. Within the context of nodes that implement this policy, fee-bumping is more reliable for users. + +==Motivation== + +Mempools typically accept and relay transactions that spend outputs from other unconfirmed transactions, but restrict package sizes through ancestor and descendant limits +https://github.com/bitcoin/bitcoin/blob/632a2bb731804dffe52bd4cbd90bfee352d25ede/doc/policy/mempool-limits.md +to limit the computational complexity of mempool operations and mitigate Denial of Service attacks. + +Users may also create unconfirmed transactions that conflict with -- or are "double spends" of -- each other by spending the same input(s) in both. +Instead of always keeping the first-seen transaction, many mempools also have some kind of Replace by Fee (RBF) policy + +[https://github.com/bitcoin/bitcoin/blob/632a2bb731804dffe52bd4cbd90bfee352d25ede/doc/policy/mempool-replacements.md Bitcoin Core's RBF policy] at the time of writing. It is slightly different from what is described in BIP 125. + +to keep the more incentive compatible transaction, i.e. one that would earn a miner more fees. Users utilize these rules when they create higher feerate double-spends (replacements) to expedite confirmation of their transactions. + +However, these policies make imperfect trade-offs between incentive compatibility and DoS-resistance. For example, malicious actors may sometimes exploit limitations to prevent incentive-compatible transactions from being accepted or fee-bumped (''pinning''). + +Pinning is consequential to contracting protocols in which untrusted parties construct and sign time-sensitive transactions to be broadcast on-chain later +Posts about pinning in LN and LN-Symmetry: +* [https://lists.linuxfoundation.org/pipermail/bitcoin-dev/2022-May/020458.html "Bringing a nuke to a knife fight: Transaction introspection to stop RBF pinning"] +* [https://lists.linuxfoundation.org/pipermail/lightning-dev/2020-April/002639.html "RBF Pinning with Counterparties and Competing Interest"] +* [https://lists.linuxfoundation.org/pipermail/lightning-dev/2020-June/002758.html "Pinning : The Good, The Bad, The Ugly"] +* [https://github.com/t-bast/lightning-docs/blob/master/pinning-attacks.md "Pinning Attacks"] +* [https://gist.github.com/instagibbs/60264606e181451e977e439a49f69fe1 "Eltoo Pinning"] +. +When the funds available to be redeemed by each party depend on a transaction confirming within a specific time window, a malicious party may be able to steal money if the honest party cannot get their transaction confirmed. As such, the ability to fee-bump a transaction to entice miners to include it in their blocks is crucial to the security of the protocol. + +===RBF pinning through absolute fees=== + +Imagine that counterparties Alice and Mallory have transactions (or packages) A and B, respectively, which conflict with each other. Alice broadcasts A and Mallory broadcasts B. RBF rules require the replacement transaction pay a higher absolute fee than the aggregate fees paid by all original transactions ([https://github.com/bitcoin/bitcoin/blob/master/doc/policy/mempool-replacements.md#current-replace-by-fee-policy "Rule 3"]). This means Mallory may increase the fees required to replace B beyond what Alice was planning to pay for A's fees. + +1. Adding transaction(s) that descend from B and pay a low feerate (too low to fee-bump B through CPFP)Example: https://lists.linuxfoundation.org/pipermail/bitcoin-dev/2023-December/022216.html. + +2. Adding a high-fee descendant of B that also spends from another large, low-feerate mempool transaction (where the fee of the descendant is too low to fee-bump both B and its other parent through CPFP)Example: https://github.com/bitcoin/bitcoin/pull/25038#issuecomment-1320295394. + +===RBF pinning through number of conflicts=== + +RBF rules require that no replacement trigger the removal of more than 100 transactions ([https://github.com/bitcoin/bitcoin/blob/master/doc/policy/mempool-replacements.md#current-replace-by-fee-policy "Rule 5"]). This number includes the descendants of the conflicted mempool transactions. Mallory can make it more difficult to replace transactions by attaching lots of descendants to them. For example, if Alice wants to batch-replace 5 transactions but each has 21 descendants, her replacement will be rejected regardless of its fees. + +===RBF incentive compatibility requirements=== + +There is currently no effective rule to enforce that a replacement transaction would be more incentive compatible to keep in the mempool. It is difficult to quantify the incentive compatibility of a set of transactions, especially in comparison with another set of transactionshttps://delvingbitcoin.org/t/mempool-incentive-compatibility/553, but the requirement of a feerate increase ([https://github.com/bitcoin/bitcoin/blob/master/doc/policy/mempool-replacements.md#current-replace-by-fee-policy "Rule 6"]) is far too simplistic. + +For example, a user could create a replacement transaction that pays more fees and is higher feerate, but has a low feerate ancestor and would confirm slower than the original transaction. As a result, all transactions signed with SIGHASH_ANYONECANPAY are vulnerable to being replaced by a transaction that will confirm later than the originalhttps://github.com/bitcoin/bitcoin/pull/23121#pullrequestreview-766271585. + +===Child fees don't count towards RBF rules=== + +A transaction must meet all fee-related requirements (Rules 3, 4, 6) alone; its child's fees cannot be used. A ''Package RBF'' policy would allow a transaction's child to be used for its RBF requirements. + +In LN Penalty, conflicting commitment transactions signed with the same fees cannot replace each other, even if accompanied by a fee-bumping child. This limitation necessitates the presence of two anchor outputs, allowing both parties to fee-bump either commitment transaction that enters their mempool. + +===Package limit pinning and replacing CPFP Carve Out=== + +Mempool policies limit the number and total virtual size of an unconfirmed transaction's descendants. A fee-bumping child of an unconfirmed transaction (CPFP) may be rejected for exceeding the descendant limit. When a transaction has multiple outputs owned by different parties, a malicious party can prevent the other(s) from CPFPing their transaction by attaching enough descendants to monopolize the descendant limit (''package limit pinning''). + +LN commitment transactions rely on CPFP carve out [https://lists.linuxfoundation.org/pipermail/bitcoin-dev/2018-November/016518.html "CPFP Carve-Out for Fee-Prediction Issues in Contracting Applications (eg Lightning)"] to avoid package limit pinning. + +There are weaknesses with this approach of using 2 anchors and CPFP Carve Out. This proposal helps address a few of them (see Related Work for how other weaknesses are addressed): + +* Cluster Mempool necessitates the removal of CPFP Carve Out https://delvingbitcoin.org/t/an-overview-of-the-cluster-mempool-proposal/393#the-cpfp-carveout-rule-can-no-longer-be-supported-12. +* CPFP Carve Out only allows ''one more'' child to be added to the transaction. This means it cannot guarantee the ability to CPFP for more than 2 parties of a shared transaction. + +==Topologically Restricted Until Confirmation== + +This section describes one approach for opt-in policy rules that can realistically be deployed today and is useful to today's applications. +It is based on the idea that most limitations stem from existing ancestor/descendant package limits being too permissive for the majority of use cases. + +The scope of the policy's anti-pinning benefits is limited to the individual node's mempool, and the degree to which a user's transaction is safe from pinning depends how much of the network has adopted this policy. + +Similarly, there are multiple approaches to creating a policy to minimize pinning, more may become available over time (see Related Work section), and the details of this approach can be tweaked if conditions change. For example, if loosening one of the topology restrictions enables a new use case while still providing acceptable pinning bounds, it can be changed. + +===Specification=== + +Senders can signal that they want a transaction to be Topologically Restricted Until Confirmation (TRUC). Specifically, set nVersion=3. +A node that implements this policy would apply their existing standardness and policy rules, along with the following set of rules, to TRUC transactions: + +1. A TRUC transaction signals replaceability, even if it does not signal BIP125 replaceability. + +2. Any TRUC transaction's unconfirmed ancestors must all be TRUC. Any descendant of an unconfirmed TRUC transaction must also be TRUC. +Rationale: +* Requiring packages to be all-or-none TRUC makes it possible to enforce the topology limits. For example, the TRUC descendant limit would not be very meaningful if it could be bypassed by creating a non-TRUC child. +* Combined with Rule 1, this requirement creates "inherited signaling" when descendants of unconfirmed transactions are created. Checking whether a transaction signals replaceability this way does not require mempool traversal, and does not change based on what transactions are mined. + +Note: A TRUC transaction can spend outputs from ''confirmed'' non-TRUC transactions. A non-TRUC transaction can spend outputs from ''confirmed'' TRUC transactions. + +3. An unconfirmed TRUC transaction cannot have more than 1 unconfirmed ancestor. An unconfirmed TRUC transaction cannot have more than 1 unconfirmed descendant. CPFP Carve Out is not granted to TRUC transactions. +Rationale: +* The larger the descendant limit, the more transactions may need to be replaced. See #1 in Rule 3 Pinning section above. This also makes pinning using Rule 5 more difficult, since a directly conflicting transaction has fewer possible descendants. +* These two limits (ancestor count 2, descendant count 2) effectively create a cluster limit using the existing ancestor and descendant limits. Increasing them to 3 would imply an infinite cluster count limit. +* This 1-parent-1-child topology makes it possible to use ancestor score (minimum of ancestor feerate and individual feerate) as a measure of incentive compatibility. + +
Q: Why not allow multiple parents to enable batched fee-bumping? +
To mitigate pinning through absolute fees, we need to prevent a child of an unconfirmed TRUC transaction from bringing in more unconfirmed ancestors. See #2 in "RBF pinning through absolute fees" section above. + +
Q: Why not allow another child? +
Allowing another child disables the ability to use ancestor score to measure incentive compatibility. Imagine the original transaction, A, has a child B and co-parent C (i.e. B spends from A and C). C also has another child, D. B is one of the original transactions and thus its ancestor feerate must be lower than the package's feerate. However, this may be an underestimation because D can bump C without B's help. This is resolved if TRUC transactions can only have TRUC ancestors, as then C cannot have another child. + +
Q: Why allow any descendants at all? +
At least 1 descendant is required to allow CPFP of the presigned transaction. Without package RBF, multiple anchor outputs would be required to allow each counterparty to fee-bump any presigned transaction. With package RBF, since the presigned transactions can replace each other, 1 anchor output is sufficient. +
+ +4. A TRUC transaction cannot have a sigop-adjusted virtual size larger than 10,000 vB. +Rationale: Limit the amount of virtual bytes (and thus fees) that may need to be replaced, while leaving a comfortable amount of space for payments, HTLCs, or other uses of the transaction. Generally, having a smaller maximum size helps to better define bounds for algorithms and memory usage, and the existing limit of 100,000 vB seems much larger than necessary. + + +5. A TRUC transaction that has an unconfirmed TRUC ancestor cannot have a sigop-adjusted virtual size larger than 1000 vB. +Rationale: Limit the amount of virtual bytes (and thus fees) that may need to be replaced, while leaving a comfortable amount of space for inputs to fund the transaction. +
Q: Why not bigger? +
The larger the descendant size limit, the more vbytes may need to be replaced. With default limits, if the child is e.g. 100,000 vB, that might be an additional 100,000 sats (at 1 sat/vbyte) or more, depending on the feerate. Restricting all children to 1000 vB reduces the upper bound of the additional fees by a factor of 100. + +
This rule is also easily tacked on to existing logic for policy and wallets. A maximum size standard transaction (100 kvB) can have up to 1000 vB of descendants to be within the default descendant limit (101 kvB). + +
Q: Why not smaller? +
The smaller this limit, the fewer UTXOs a child may use to fund this fee-bump. For example, only allowing the TRUC child to have 2 inputs would require wallets to maintain a pool of high-value confirmed UTXOs. However, as the fee-bumping child only needs to fund fees (as opposed to payments), just a few UTXOs should suffice. With a limit of 1000 vB and usage of taproot outputs, the child can have 15 inputs and 2 outputs (calculated using [https://bitcoinops.org/en/tools/calc-size/ this tool]). +
+ +6. An individual TRUC transaction is permitted to be below the mempool min relay feerate, assuming it is considered within a package that meets the mempool's feerate requirements. +Rationale: This allows contracting protocols to create presigned transactions with 0 fees and fee-bump them using CPFP at broadcast time. + + +====Implementation==== + +* https://github.com/bitcoin/bitcoin/pull/28948 +* https://github.com/bitcoin/bitcoin/pull/29873 +* https://github.com/bitcoin/bitcoin/pull/29496 + +====Related Work==== + +This 1-parent-1-child (aka cluster size 2) topology restriction makes the transactions much easier to reason about, which enables additional features like +feerate diagram comparisons + +[https://github.com/bitcoin/bitcoin/pull/29242 this PR] implements feerate diagram creation and comparison for sets of transactions in which the maximum cluster size is 2, e.g. all TRUC transactions. +, +package RBF + +[https://github.com/bitcoin/bitcoin/pull/28984 this PR] implements package RBF, enforcing incentive compatibility by comparing the feerate diagrams of the mempool before and after replacement. The feerate diagrams are easy to build when the relevant clusters are of size 2 and below, so package RBF is restricted to those scenarios. As TRUC transactions always have this property, package RBF is enabled for TRUC transactions. +, +and sibling eviction + +[https://github.com/bitcoin/bitcoin/pull/29306 This PR] implements sibling eviction for TRUC transactions: if a new transaction would exceed a transaction's descendant limit, it considers evicting the existing descendant using replacement rules. Sibling eviction is feasible for TRUC transactions because there is no difficulty in identifying which descendant to evict (there can only be 1). +. + +The [https://github.com/bitcoin/bips/pull/1524 Ephemeral Anchors] proposal builds on top of this one to add more features. +It changes the anchor script to be anyone can spend, allowing anybody to add fees and reducing the onchain footprint and fee costs. +It also allows anchor outputs to have 0 value, eliminating the need to deduct value from the input amount in order to create anchors. + +The [https://delvingbitcoin.org/t/an-overview-of-the-cluster-mempool-proposal/393/7 Cluster Mempool] proposal makes fundamental changes to mempool structure and policy rules, enabling the accurate assessment of the incentive compatibility of accepting or removing a transaction, among other things. Notably, Cluster Mempool introduces a limit to all transactions' cluster size to make incentive compatibility calculations feasible. This cluster limit is similar to TRUC limits in that it bounds computation to enable improved policies, but is applied to all transactions (not just ones that opt in) and is much less restrictive than TRUC limits. + +Cluster Mempool provides a more holistic solution to some of the problems listed (such as adding an incentive compatibility requirement to RBF and safely enabling package RBF for more complex topologies). However, it does not help resolve all problems (such as RBF Pinning through absolute fees and number of conflicts). Also, since Cluster Mempool is incompatible with CPFP Carve Outhttps://delvingbitcoin.org/t/an-overview-of-the-cluster-mempool-proposal/393#the-cpfp-carveout-rule-can-no-longer-be-supported-12, TRUC with sibling eviction and package RBF provide an alternative solution to applications that rely on it. + +Building on top of Cluster Mempool, there are also various ideas for extending TRUC transactions and creating another anti-pinning policy +https://delvingbitcoin.org/t/v3-and-some-possible-futures/523/3. + +[https://bitcoinops.org/en/topics/package-relay Package Relay] includes changes in p2p protocol, transaction relay logic, and mempool policy to enable nodes to accept and relay packages of transactions. Much of this proposal's utility relies on the existence of package relay for 1-parent-1-child packages (the topology TRUC supports). + +====Backward Compatibility==== + +Transactions with nVersion=3 were previously nonstandard. There are no known conflicts with previous usage. + +====Intended Usage==== + +Generally, users with no interest in spending unconfirmed outputs from a transaction can make them TRUC transactions for more robust RBF abilities. + +This proposal allows for a different solution to fee-bumping in LN, in which commitment transactions are signed with 0 fees and include a single anchor that can later be used to add fees at broadcast time +Proposals for changes to LN commitment transaction format using TRUC and a single anchor: +* [https://delvingbitcoin.org/t/lightning-transactions-with-v3-and-ephemeral-anchors/418 "Lightning transactions with v3 and ephemeral anchors"] +* [https://github.com/instagibbs/bolts/commits/zero_fee_commitment bolts proposal branch] +* See "Intended usage for LN" section in [https://lists.linuxfoundation.org/pipermail/bitcoin-dev/2022-September/020937.html "New transaction policies (nVersion=3) for contracting protocols"] +. +A similar fee-bumping model can also be used in other contracting protocols +Examples of non-LN protocols that have shown interest in, designed, or built fee-bumping using TRUC: +* A LN-Symmetry implementation using TRUC and ephemeral anchors: [https://delvingbitcoin.org/t/ln-symmetry-project-recap/359 LN-Symmetry Project Recap] [https://github.com/instagibbs/lightning/tree/eltoo_support branch] +* See "Managing Fees Safely" mentioning ephemeral anchors in [https://jameso.be/vaults.pdf "Vaults and Covenants"] +. + +==Alternatives== + +Various alternatives for RBF +Proposals and discussions dedicated to improving RBF: +* [https://gist.github.com/glozow/25d9662c52453bd08b4b4b1d3783b9ff "RBF Improvements"] +* [https://lists.linuxfoundation.org/pipermail/bitcoin-dev/2022-January/019817.html "Improving RBF Policy"] +* [https://lists.linuxfoundation.org/pipermail/bitcoin-dev/2019-June/016998.html "[PROPOSAL] Emergency RBF (BIP 125)"] + +and new fee-bumping mechanisms + +
Proposals and discussions dedicated to improving or creating new fee-bumping mechanisms: +* [https://github.com/lightning/bolts/pull/1036 "Add option to sign commitments at various feerates"] +* [https://lists.linuxfoundation.org/pipermail/bitcoin-dev/2021-July/019243.html "A Stroll through Fee-Bumping Techniques : Input-Based vs Child-Pay-For-Parent"] +* [https://lists.linuxfoundation.org/pipermail/bitcoin-dev/2020-September/018168.html "A Replacement for RBF and CPFP: Non-Destructive TXID Dependencies for Fee Sponsoring"] +* [https://lists.linuxfoundation.org/pipermail/bitcoin-dev/2022-February/019879.html "Thoughts on fee bumping"] +
+have been proposed across multiple discussion threads. +Most alternatives do not conflict with TRUC, and some work in conjunction with this proposal - see Related Work. +A few popular ideas that were not incorporated into this work are summarized here. + +===Alternatives: add static incentive compatibility rule in RBF policy=== + +Add incentive compatibility requirement to RBF policy using some existing score or static calculation +Examples of incentive compatibility score proposals and suggestions: +* [https://github.com/bitcoin/bitcoin/pull/23121 "check ancestor feerate in RBF, remove BIP125 Rule2"] +* [https://github.com/bitcoin/bitcoin/pull/26451 "Enforce incentive compatibility for all RBF replacements"] +* https://lists.linuxfoundation.org/pipermail/bitcoin-dev/2022-January/019841.html +* https://gist.github.com/glozow/25d9662c52453bd08b4b4b1d3783b9ff?permalink_comment_id=4081349#gistcomment-4081349 +. + +As the incentive compatibility "score" of a transaction must be dynamically calculated given the structure of mempools today, there is no satisfactory solution. A full calculation is too computationally expensive. Static values can overestimate or underestimate, leading to more pinning problems Four examples of static calculations and an example in which they are all inaccurate: https://gist.github.com/glozow/25d9662c52453bd08b4b4b1d3783b9ff#mining-score-of-a-mempool-transaction. +The ability to calculate incentive compatibility scores efficiently is a primary feature and motivation for both TRUC transactions and Cluster Mempool. + +===Alternatives: replace by feerate=== + +"Instead of using Rule 3 and/or 4 (requiring an increase in absolute fees), allow replacements with a higher feerate." + +One variation of this proposal is to apply this rule in certain exceptional scenarios or when the replacement would confirm "soon" +Examples of Replace by Feerate proposals and suggestions: +* [https://lists.linuxfoundation.org/pipermail/bitcoin-dev/2019-June/016998.html "[PROPOSAL] Emergency RBF (BIP 125)"] +* [https://gist.github.com/glozow/25d9662c52453bd08b4b4b1d3783b9ff#fees-in-next-block-and-feerate-for-the-rest-of-the-mempool] +* [https://petertodd.org/2024/one-shot-replace-by-fee-rate "One-Shot Replace-by-Fee-Rate"] +. + +The primary problem with these proposals is the potential for free relay and DDoS attacks. + +Removing Rule 3 and 4 in general would allow free relay +Examples of free relay with the removal of Rule 3 and/or 4: +
Consider a rule where the fee can be decreased (remove Rule 3 and 4) but the feerate must double. In this scenario, a 100 kvB transaction can be replaced by a 100 vB transaction paying 200 sats. That's 200 sats to relay 100,200 vB of transaction data, which is less than 0.002 sat/vB. It becomes quite cheap to replace large portions of the mempool, decreasing both its average feerate and total absolute fees. + +
Consider a rule where the fee can stay the same (keep Rule 3 but drop Rule 4) but the feerate must double. The attacker can start out with 100 kvB transaction, paying 1 sat/vB. A user can reduce its size over and over again, doubling the feerate each time until it gets too small, and end up paying 100 ksat for 100 kvB(1 + 1/2 + 1/4 + ... + log2(mintxsize)) -> approaches 200 kvB. This means the attacker pays a rate of 0.5 sat/vB to relay transactions, which is below our "free relay" threshold of 1 sat/vB. +
. + +Another issue is the complexity of defining and implementing a "would confirm soon" or "is in the top N portion of the mempool." These proposals require an efficient way to assess the incentive compatibility score of a transaction and where it ranks amongst the other mempool transactions. This isn't feasible without something like cluster mempool (also see the "add static incentive compatibility rule in RBF policy" section above) +Concerns about Replace by Feerate proposals +* https://lists.linuxfoundation.org/pipermail/bitcoin-dev/2019-June/017020.html +* https://lists.linuxfoundation.org/pipermail/bitcoin-dev/2019-June/017002.html +* https://lists.linuxfoundation.org/pipermail/bitcoin-dev/2022-February/019879.html +* https://gist.github.com/glozow/25d9662c52453bd08b4b4b1d3783b9ff?permalink_comment_id=4044451#gistcomment-4044451 +. + +===Alternatives: implement rate-limiting without fee rules=== +"Since Rule 3 and 4 (requiring an increase in absolute fees) are for rate-limiting, replace them with a mempool-wide or per-peer rate limits on replacements by outpoint and/or bandwidth +Examples of general rate-limiting proposals and suggestions: +* https://gist.github.com/glozow/25d9662c52453bd08b4b4b1d3783b9ff?permalink_comment_id=4081349#gistcomment-4081349 +* https://lists.linuxfoundation.org/pipermail/bitcoin-dev/2022-January/019820.html +* https://lists.linuxfoundation.org/pipermail/bitcoin-dev/2019-June/017024.html +
Related proposal for changing the amount of bandwidth that replacement transactions use: +* https://lists.linuxfoundation.org/pipermail/bitcoin-dev/2022-January/019820.html +
." + +A problem with any global rate limit is that, in the absence of reputation or identities, the limit could be exhausted by an attacker, thus restricting replacements for honest users. For example, an outpoint-based rate limit could be exhausted by one dishonest participant of a shared transaction, preventing the other participants from making any replacements. There are also other concerns about implementation complexity, free relay issues, and other unresolved edge cases +Concerns +* https://gist.github.com/glozow/25d9662c52453bd08b4b4b1d3783b9ff?permalink_comment_id=4081559#gistcomment-4081559 +* https://lists.linuxfoundation.org/pipermail/bitcoin-dev/2022-February/019921.html +* https://docs.google.com/document/d/1LpYF17HdbXPGHKSl3WYdxG4XTJBNJKSn-c2UJ2yphhE/edit?usp=sharing +. + + +==Acknowledgements== + +Thank you to everyone who contributed to this proposal and document, including +Jon Atack, +Matt Corallo, +Suhas Daftuar, +Mark Erhardt, +Antoine Poinsot, +Antoine Riard, +Gregory Sanders, +and Bastien Teinturier. + +==References and Rationale== + + + From 0b353bc7dbede1a8637f9074484b8a257ed2d575 Mon Sep 17 00:00:00 2001 From: theborakompanioni Date: Mon, 27 May 2024 10:10:22 +0200 Subject: [PATCH 271/454] docs(bip-0046): add Backwards Compatibility section --- bip-0046.mediawiki | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/bip-0046.mediawiki b/bip-0046.mediawiki index 7f2ef5e6fb..b793a1a281 100644 --- a/bip-0046.mediawiki +++ b/bip-0046.mediawiki @@ -31,6 +31,10 @@ This standard is already implemented and deployed in JoinMarket. As most changes It would be useful to be able to keep the private keys of fidelity bonds in cold storage. This would allow the sybil resistance of a system to increase without hot wallet risk. +== Backwards Compatibility == + +This BIP is not backwards compatible by design as described in the Considerations section of [[bip-0049.mediawiki|BIP 49]]. An incompatible wallet will not discover fidelity bonds at all and the user will notice that something is wrong. + == Background == === Fidelity bonds === From 722a388ae3e400db6e1928bcd90d8c9ece324c31 Mon Sep 17 00:00:00 2001 From: theborakompanioni Date: Mon, 27 May 2024 10:13:28 +0200 Subject: [PATCH 272/454] chore(bip-0046): fix date format in Post-History header --- bip-0046.mediawiki | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/bip-0046.mediawiki b/bip-0046.mediawiki index b793a1a281..f1fe01d32c 100644 --- a/bip-0046.mediawiki +++ b/bip-0046.mediawiki @@ -8,7 +8,7 @@ Type: Standards Track Created: 2022-04-01 License: CC0-1.0 - Post-History: 2022-5-1: https://lists.linuxfoundation.org/pipermail/bitcoin-dev/2022-May/020389.html + Post-History: 2022-05-01: https://lists.linuxfoundation.org/pipermail/bitcoin-dev/2022-May/020389.html
== Abstract == From a6f1cf3e0d391fdc7c6d8eb1291868d35e293c09 Mon Sep 17 00:00:00 2001 From: theborakompanioni Date: Mon, 27 May 2024 10:25:14 +0200 Subject: [PATCH 273/454] chore(bip-0046): improve timelock point in time explanation --- bip-0046.mediawiki | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/bip-0046.mediawiki b/bip-0046.mediawiki index f1fe01d32c..fa4dd5c06b 100644 --- a/bip-0046.mediawiki +++ b/bip-0046.mediawiki @@ -77,7 +77,7 @@ For index, addresses are numbered from 0 in a sequentially increasing m === Timelock derivation === -The timelock used in the time-locked address is derived from the index. The timelock is a unix time. It is always the first of the month at midnight. The index counts upwards the months from January 2020, ending in December 2099. At 12 months per year for 80 years this totals 960 timelocks. Note that care must be taken with the year 2038 problem on 32-bit systems. +The timelock used in the time-locked address is derived from the index. The timelock is a unix time. It is always at the start of the first second at the beginning of the month (see [[#Test vectors|Test vectors]]). The index counts upwards the months from January 2020, ending in December 2099. At 12 months per year for 80 years this totals 960 timelocks. Note that care must be taken with the year 2038 problem on 32-bit systems.
 year = 2020 + index // 12

From 25361d28ed534d06da89b92257aae47cb08db5b4 Mon Sep 17 00:00:00 2001
From: theborakompanioni 
Date: Mon, 27 May 2024 10:33:17 +0200
Subject: [PATCH 274/454] chore(bip-0046): add tbk to Author header

---
 bip-0046.mediawiki | 1 +
 1 file changed, 1 insertion(+)

diff --git a/bip-0046.mediawiki b/bip-0046.mediawiki
index fa4dd5c06b..3576345ad9 100644
--- a/bip-0046.mediawiki
+++ b/bip-0046.mediawiki
@@ -3,6 +3,7 @@
   Layer: Applications
   Title: Address Scheme for Timelocked Fidelity Bonds
   Author: Chris Belcher 
+          Thebora Kompanioni 
   Comments-URI: https://github.com/bitcoin/bips/wiki/Comments:BIP-0046
   Status: Draft
   Type: Standards Track

From 2bc326e6afc6d976b22cc8cf68ecc45d35761bb1 Mon Sep 17 00:00:00 2001
From: theborakompanioni 
Date: Mon, 27 May 2024 10:33:48 +0200
Subject: [PATCH 275/454] docs(bip-0046): add Rationale section

---
 bip-0046.mediawiki | 5 ++---
 1 file changed, 2 insertions(+), 3 deletions(-)

diff --git a/bip-0046.mediawiki b/bip-0046.mediawiki
index 3576345ad9..7bb8044909 100644
--- a/bip-0046.mediawiki
+++ b/bip-0046.mediawiki
@@ -28,8 +28,6 @@ It would be useful to have a common derivation scheme so that users of wallet so
 
 We largely use the same approach used in BIPs 49, 84 and 86 for ease of implementation.
 
-This standard is already implemented and deployed in JoinMarket. As most changes would require a protocol change of a live system, there is limited scope for changing this standard in review. This BIP is more about documenting something which already exists, warts and all.
-
 It would be useful to be able to keep the private keys of fidelity bonds in cold storage. This would allow the sybil resistance of a system to increase without hot wallet risk.
 
 == Backwards Compatibility ==
@@ -54,10 +52,11 @@ To allow for holding fidelity bonds in cold storage, there is an intermediate ke
 
 Where the endpoint might be a IRC nickname or Tor onion hostname. The certificate keypair can be kept online and used to prove ownership of the fidelity bond. Even if the hot wallet private keys are stolen, the coins in the timelocked address will still be safe, although the thief will be able to impersonate the fidelity bond until the expiry.
 
-=== Fixed timelock values ===
+== Rationale ==
 
 It would be useful for the user to avoid having to keep a record of the timelocks in the time-locked addresses. So only a limited small set of timelocks are defined by this BIP. This way the user must only store their seed phrase, and knowledge that they have coins stored using this BIP standard. The user doesn't need to remember or store any dates.
 
+This standard is already implemented and deployed in JoinMarket. As most changes would require a protocol change of a live system, there is limited scope for changing this standard in review. This BIP is more about documenting something which already exists, warts and all.
 
 == Specifications ==
 

From 1eefea0456d661b4c51f3a40b7262d6a99161edd Mon Sep 17 00:00:00 2001
From: Alexander Cyon 
Date: Tue, 28 May 2024 19:25:46 +0200
Subject: [PATCH 276/454] Fix typos on 17 files.

---
 bip-0015.mediawiki         |  2 +-
 bip-0047.mediawiki         |  2 +-
 bip-0049.mediawiki         |  4 ++--
 bip-0085.mediawiki         |  2 +-
 bip-0087.mediawiki         |  2 +-
 bip-0088.mediawiki         |  8 ++++----
 bip-0098.mediawiki         |  8 ++++----
 bip-0119.mediawiki         | 10 +++++-----
 bip-0137.mediawiki         |  2 +-
 bip-0140.mediawiki         |  2 +-
 bip-0158/gentestvectors.go |  2 +-
 bip-0327.mediawiki         |  2 +-
 bip-0340/test-vectors.py   |  2 +-
 bip-0345.mediawiki         |  2 +-
 bip-0351.mediawiki         |  4 ++--
 bip-0352/reference.py      |  2 +-
 bip-0389.mediawiki         |  2 +-
 17 files changed, 29 insertions(+), 29 deletions(-)

diff --git a/bip-0015.mediawiki b/bip-0015.mediawiki
index 52a698f235..1e9a9bc466 100644
--- a/bip-0015.mediawiki
+++ b/bip-0015.mediawiki
@@ -208,7 +208,7 @@ NameResolutionService::~NameResolutionService()
 
 void NameResolutionService::ExplodeHandle(const string& strHandle, string& strNickname, string& strDomain)
 {
-    // split address at @ furthrest to the right
+    // split address at @ furthest to the right
     size_t nPosAtsym = strHandle.rfind('@');
     strNickname = strHandle.substr(0, nPosAtsym);
     strDomain = strHandle.substr(nPosAtsym + 1, strHandle.size());
diff --git a/bip-0047.mediawiki b/bip-0047.mediawiki
index dc1f58803f..a15a15de52 100644
--- a/bip-0047.mediawiki
+++ b/bip-0047.mediawiki
@@ -275,7 +275,7 @@ Normal operation of a payment code-enabled wallet can be performed by an SPV cli
 
 Recovering a wallet from a seed, however, does require access to a fully-indexed blockchain.
 
-The required data may be obtained from copy of the blockchain under the control of the user, or via a publicly-queriable blockchain explorer.
+The required data may be obtained from copy of the blockchain under the control of the user, or via a publicly-queryable blockchain explorer.
 
 When querying a public blockchain explorer, wallets SHOULD connect to the explorer through Tor (or equivalent) and SHOULD avoid grouping queries in a manner that associates ephemeral addresses with each other.
 
diff --git a/bip-0049.mediawiki b/bip-0049.mediawiki
index a13b437b92..3e37a0164b 100644
--- a/bip-0049.mediawiki
+++ b/bip-0049.mediawiki
@@ -92,10 +92,10 @@ This BIP is not backwards compatible by design as described under [[#considerati
   // Account 0, first receiving private key = m/49'/1'/0'/0/0
   account0recvPrivateKey = cULrpoZGXiuC19Uhvykx7NugygA3k86b3hmdCeyvHYQZSxojGyXJ
   account0recvPrivateKeyHex = 0xc9bdb49cfbaedca21c4b1f3a7803c34636b1d7dc55a717132443fc3f4c5867e8
-  account0recvPublickKeyHex = 0x03a1af804ac108a8a51782198c2d034b28bf90c8803f5a53f76276fa69a4eae77f
+  account0recvPublicKeyHex = 0x03a1af804ac108a8a51782198c2d034b28bf90c8803f5a53f76276fa69a4eae77f
 
   // Address derivation
-  keyhash = HASH160(account0recvPublickKeyHex) = 0x38971f73930f6c141d977ac4fd4a727c854935b3
+  keyhash = HASH160(account0recvPublicKeyHex) = 0x38971f73930f6c141d977ac4fd4a727c854935b3
   scriptSig = <0 > = 0x001438971f73930f6c141d977ac4fd4a727c854935b3
   addressBytes = HASH160(scriptSig) = 0x336caa13e08b96080a32b5d818d59b4ab3b36742
 
diff --git a/bip-0085.mediawiki b/bip-0085.mediawiki
index 7311d8a7c0..633210c6c6 100644
--- a/bip-0085.mediawiki
+++ b/bip-0085.mediawiki
@@ -364,7 +364,7 @@ This specification relies on BIP32 but is agnostic to how the BIP32 root key is
 
 ==Discussion==
 
-The reason for running the derived key through HMAC-SHA512 and truncating the result as necessary is to prevent leakage of the parent tree should the derived key (''k'') be compromized. While the specification requires the use of hardended key derivation which would prevent this, we cannot enforce hardened derivation, so this method ensures the derived entropy is hardened. Also, from a semantic point of view, since the purpose is to derive entropy and not a private key, we are required to transform the child key. This is done out of an abundance of caution, in order to ward off unwanted side effects should ''k'' be used for a dual purpose, including as a nonce ''hash(k)'', where undesirable and unforeseen interactions could occur.
+The reason for running the derived key through HMAC-SHA512 and truncating the result as necessary is to prevent leakage of the parent tree should the derived key (''k'') be compromised. While the specification requires the use of hardended key derivation which would prevent this, we cannot enforce hardened derivation, so this method ensures the derived entropy is hardened. Also, from a semantic point of view, since the purpose is to derive entropy and not a private key, we are required to transform the child key. This is done out of an abundance of caution, in order to ward off unwanted side effects should ''k'' be used for a dual purpose, including as a nonce ''hash(k)'', where undesirable and unforeseen interactions could occur.
 
 ==Acknowledgements==
 
diff --git a/bip-0087.mediawiki b/bip-0087.mediawiki
index 308e8521e5..920bd3cb49 100644
--- a/bip-0087.mediawiki
+++ b/bip-0087.mediawiki
@@ -48,7 +48,7 @@ The second multisignature "standard" in use is m/48', which specifies:
 m / purpose' / coin_type' / account' / script_type' / change / address_index
 
-Rather than following in BIP 44/49/84's path and having a separate BIP per script after P2SH (BIP45), vendors decided to insert script_type' into the derivation path (where P2SH-P2WSH=1, P2WSH=2, Future_Script=3, etc). As described previously, this is unnecessary, as the descriptor sets the script. While it attempts to reduce maintainence work by getting rid of new BIPs-per-script, it still requires maintaining an updated, redundant, script_type list. +Rather than following in BIP 44/49/84's path and having a separate BIP per script after P2SH (BIP45), vendors decided to insert script_type' into the derivation path (where P2SH-P2WSH=1, P2WSH=2, Future_Script=3, etc). As described previously, this is unnecessary, as the descriptor sets the script. While it attempts to reduce maintenance work by getting rid of new BIPs-per-script, it still requires maintaining an updated, redundant, script_type list. The structure proposed later in this paper solves these issues and is quite comprehensive. It allows for the handling of multiple accounts, external and internal chains per account, and millions of addresses per chain, in a multi-party, multisignature, hierarchical deterministic wallet regardless of the script type '''Why propose this structure only for multisignature wallets?''' Currently, single-sig wallets are able to restore funds using just the master private key data (in the format of BIP39 usually). Even if the user doesn't recall the derivation used, the wallet implementation can iterate through common schemes (BIP44/49/84). With this proposed hierarchy, the user would either have to now backup additional data (the descriptor), or the wallet would have to attempt all script types for every account level when restoring. Because of this, even though the descriptor language handles the signature type just like it does the script type, it is best to restrict this script-agnostic hierarchy to multisignature wallets only.. diff --git a/bip-0088.mediawiki b/bip-0088.mediawiki index 49be7dba42..db21835e2e 100644 --- a/bip-0088.mediawiki +++ b/bip-0088.mediawiki @@ -41,7 +41,7 @@ addresses differently than the one they used before. The problem is common enough to warrant the creation of a dedicated website ([https://walletsrecovery.org/ walletsrecovery.org]) that tracks paths used by different wallets. -At the time of writing, this website has used their own format to succintly describe multiple +At the time of writing, this website has used their own format to succinctly describe multiple derivation paths. As far as author knows, it was the only publicitly used format to describe path templates before introduction of this BIP. The format was not specified anywhere beside the main page of the website. It used | to denote alternative derivation indexes @@ -52,7 +52,7 @@ an ad-hoc format only intended for illustration. In contrast to this ad-hoc form described in this BIP is intended for unambigouos parsing by software, and to be easily read by humans at the same time. Humans can visually detect the 'templated' parts of the path more easily than the use of | in the template could allow. Wider range of paths can be defined in a single template more -succintly and unambiguously. +succinctly and unambiguously. ===Intended use and advantages=== @@ -71,7 +71,7 @@ into using well-known paths, or convince other vendors to support their custom p scales poorly. A flexible approach proposed in this document is to define a standard notation for "BIP32 path templates" -that succintly describes the constraints to impose on the derivation path. +that succinctly describes the constraints to impose on the derivation path. Wide support for these path templates will increase interoperability and flexibility of solutions, and will allow vendors and individual developers to easily define their own custom restrictions. @@ -89,7 +89,7 @@ installation of malicious or incorrect profiles, though. ==Specification== -The format for the template was chosen to make it easy to read, convenient and visually unambigous. +The format for the template was chosen to make it easy to read, convenient and visually unambiguous. Template starts with optional prefix m/, and then one or more sections delimited by the slash character (/). diff --git a/bip-0098.mediawiki b/bip-0098.mediawiki index 8540d1ac89..a296fdc86b 100644 --- a/bip-0098.mediawiki +++ b/bip-0098.mediawiki @@ -241,16 +241,16 @@ Disallowing a node with two SKIP branches eliminates what would otherwise be a s The number of hashing operations required to verify a proof is one less than the number of hashes (SKIP and VERIFY combined), and is exactly equal to the number of inner nodes serialized as the beginning of the proof as N. -The variable-length integer encoding has the property that serialized integers, sorted lexigraphically, will also be sorted numerically. -Since the first serialized item is the number of inner nodes, sorting proofs lexigraphically has the effect of sorting the proofs by the amount of work required to verify. +The variable-length integer encoding has the property that serialized integers, sorted lexicographically, will also be sorted numerically. +Since the first serialized item is the number of inner nodes, sorting proofs lexicographically has the effect of sorting the proofs by the amount of work required to verify. The number of hashes required as input for verification of a proof is N+1 minus the number of SKIP hashes, and can be quickly calculated without parsing the tree structure. -The coding and packing rules for the serialized tree structure were also chosen to make lexigraphical comparison useful (or at least not meaningless). +The coding and packing rules for the serialized tree structure were also chosen to make lexicographical comparison useful (or at least not meaningless). If we consider a fully-expanded tree (no SKIP hashes, all VERIFY) to be encoding a list of elements in the order traversed depth-first from left-to-right, then we can extract proofs for subsets of the list by SKIP'ing the hashes of missing values and recursively pruning any resulting SKIP,SKIP nodes. -Lexigraphically comparing the resulting serialized tree structures is the same as lexigraphically comparing lists of indices from the original list verified by the derived proof. +Lexicographically comparing the resulting serialized tree structures is the same as lexicographically comparing lists of indices from the original list verified by the derived proof. Because the number of inner nodes and the number of SKIP hashes is extractible from the tree structure, both variable-length integers in the proof are redundant and could have been omitted. diff --git a/bip-0119.mediawiki b/bip-0119.mediawiki index d661f4c462..be1f70cb45 100644 --- a/bip-0119.mediawiki +++ b/bip-0119.mediawiki @@ -193,7 +193,7 @@ Deployment could be done via BIP 9 VersionBits deployed through Speedy Trial. The Bitcoin Core reference implementation includes the below parameters, configured to match Speedy Trial, as that is the current activation mechanism implemented in Bitcoin Core. Should another method become favored by the wider -Bitcoin comminity, that might be used instead. +Bitcoin community, that might be used instead. The start time and bit in the implementation are currently set to bit 5 and NEVER_ACTIVE/NO_TIMEOUT, but this is subject to change while the BIP is a draft. @@ -314,7 +314,7 @@ We treat the number of inputs as a `uint32_t` because Bitcoin's consensus decodi to `MAX_SIZE=33554432` and that is larger than `uint16_t` and smaller than `uint32_t`. 32 bits is also friendly for manipulation using Bitcoin's current math opcodes, should `OP_CAT` be added. Note that the max inputs in a block is further restricted by the block size to around 25,000, which would fit -into a `uint16_t`, but that is an uneccessary abstraction leak. +into a `uint16_t`, but that is an unnecessary abstraction leak. =====Committing to the Sequences Hash===== @@ -362,7 +362,7 @@ scripts cannot be spent at the same index, which implies that they cannot be spe This makes it safer to design wallet vault contracts without half-spend vulnerabilities. Committing to the current index doesn't prevent one from expressing a CHECKTEMPLATEVERIFY which can -be spent at multiple indicies. In current script, the CHECKTEMPLATEVERIFY operation can be wrapped +be spent at multiple indices. In current script, the CHECKTEMPLATEVERIFY operation can be wrapped in an OP_IF for each index (or Tapscript branches in the future). If OP_CAT or OP_SHA256STREAM are added to Bitcoin, the index may simply be passed in by the witness before hashing. @@ -476,7 +476,7 @@ An example of a script that could experience an DoS issue without caching is: CTV CTV CTV... CTV -Such a script would cause the intepreter to compute hashes (supposing N CTV's) over O(N*T) data. +Such a script would cause the interpreter to compute hashes (supposing N CTV's) over O(N*T) data. If the scriptSigs non-nullity is not cached, then the O(T) transaction could be scanned over O(N) times as well (although cheaper than hashing, still a DoS). As such, CTV caches hashes and computations over all variable length fields in a transaction. @@ -616,7 +616,7 @@ sponsors might be considered. An opcode which verifies the exact amount that is being spent in the transaction, the amount paid as fees, or made available in a given output could -be used to make safer OP_CHECKTEMPLATEVERIFY addressses. For instance, if the +be used to make safer OP_CHECKTEMPLATEVERIFY addresses. For instance, if the OP_CHECKTEMPLATEVERIFY program P expects exactly S satoshis, sending S-1 satoshis would result in a frozen UTXO and sending S+n satoshis would result in n satoshis being paid to fee. A range check could restrict the program to only diff --git a/bip-0137.mediawiki b/bip-0137.mediawiki index 575440b181..ccba17fc52 100644 --- a/bip-0137.mediawiki +++ b/bip-0137.mediawiki @@ -15,7 +15,7 @@ This document describes a signature format for signing messages with Bitcoin private keys. -The specification is intended to describe the standard for signatures of messages that can be signed and verfied between different clients that exist in the field today. Note: that a new signature format has been defined which has a number of advantages over this BIP, but to be backwards compatible with existing implementations this BIP will be useful. See BIP 322 [1] for full details on the new signature scheme. +The specification is intended to describe the standard for signatures of messages that can be signed and verified between different clients that exist in the field today. Note: that a new signature format has been defined which has a number of advantages over this BIP, but to be backwards compatible with existing implementations this BIP will be useful. See BIP 322 [1] for full details on the new signature scheme. One of the key problems in this area is that there are several different types of Bitcoin addresses and without introducing specific standards it is unclear which type of address format is being used. See [2]. This BIP will attempt to address these issues and define a clear and concise format for Bitcoin signatures. diff --git a/bip-0140.mediawiki b/bip-0140.mediawiki index 88131f49ec..c8f22f7899 100644 --- a/bip-0140.mediawiki +++ b/bip-0140.mediawiki @@ -62,7 +62,7 @@ This is the standard ''m-of-n'' script defined in [https://github.com/bitcoin/bi The existing OP_CHECKMULTISIG and OP_CHECKMULTISIGVERIFY have a bug[[https://bitcoin.org/en/developer-guide#multisig|Developer Documentation - Multisig]] that pops one argument too many from the stack. This bug is not reproduced in the implementation of OP_CHECKSIGEX, so the canonical solution of pushing a dummy value onto the stack is not necessary. The normalization is achieved by normalizing the transaction before computing the signaturehash, i.e., the hash that is signed. -The transaction must be normalized by replacing all transaction IDs in the inputs by their normalized variants and stripping the signature scripts. The normalized transction IDs are computed as described in the previous section. This normalization step is performed both when creating the signatures as well as when checking the signatures. +The transaction must be normalized by replacing all transaction IDs in the inputs by their normalized variants and stripping the signature scripts. The normalized transaction IDs are computed as described in the previous section. This normalization step is performed both when creating the signatures as well as when checking the signatures. === Tracking Normalized Transaction IDs === diff --git a/bip-0158/gentestvectors.go b/bip-0158/gentestvectors.go index e51b9842c6..2d11b14496 100644 --- a/bip-0158/gentestvectors.go +++ b/bip-0158/gentestvectors.go @@ -37,7 +37,7 @@ var ( {49291, "Tx pays to empty output script"}, {180480, "Tx spends from empty output script"}, {926485, "Duplicate pushdata 913bcc2be49cb534c20474c4dee1e9c4c317e7eb"}, - {987876, "Coinbase tx has unparseable output script"}, + {987876, "Coinbase tx has unparsable output script"}, {1263442, "Includes witness data"}, {1414221, "Empty data"}, } diff --git a/bip-0327.mediawiki b/bip-0327.mediawiki index 4815f409ed..181926bf87 100644 --- a/bip-0327.mediawiki +++ b/bip-0327.mediawiki @@ -554,7 +554,7 @@ influence whether ''sk1'' or ''sk2'' is provided to ''Sign This degree of freedom may allow the adversary to perform a generalized birthday attack and thereby forge a signature (see [https://lists.linuxfoundation.org/pipermail/bitcoin-dev/2022-October/021000.html bitcoin-dev mailing list post] and [https://github.com/jonasnick/musig2-tweaking writeup] for details). -Checking ''pk'' against ''InvidualPubkey(sk)'' is a simple way to ensure +Checking ''pk'' against ''IndividualPubkey(sk)'' is a simple way to ensure that the secret key provided to ''Sign'' is fully determined already when ''NonceGen'' is invoked. This removes the adversary's ability to influence the secret key after having seen the ''pubnonce'' and thus rules out the attack.Ensuring that the secret key provided to ''Sign'' is fully determined already when ''NonceGen'' is invoked is a simple policy to rule out the attack, diff --git a/bip-0340/test-vectors.py b/bip-0340/test-vectors.py index 317f2ece69..9a5a1401db 100644 --- a/bip-0340/test-vectors.py +++ b/bip-0340/test-vectors.py @@ -99,7 +99,7 @@ def insecure_schnorr_sign_fixed_nonce(msg, seckey0, k): e = int_from_bytes(tagged_hash("BIP0340/challenge", bytes_from_point(R) + bytes_from_point(P) + msg)) % n return bytes_from_point(R) + bytes_from_int((k + e * seckey) % n) -# Creates a singature with a small x(R) by using k = -1/2 +# Creates a signature with a small x(R) by using k = -1/2 def vector4(): one_half = n - 0x7fffffffffffffffffffffffffffffff5d576e7357a4501ddfe92f46681b20a0 seckey = bytes_from_int(0x763758E5CBEEDEE4F7D3FC86F531C36578933228998226672F13C4F0EBE855EB) diff --git a/bip-0345.mediawiki b/bip-0345.mediawiki index a6ead3158d..bc12f04776 100644 --- a/bip-0345.mediawiki +++ b/bip-0345.mediawiki @@ -10,7 +10,7 @@ Type: Standards Track Created: 2023-02-03 License: BSD-3-Clause - Post-History: 2023-01-09: https://lists.linuxfoundation.org/pipermail/bitcoin-dev/2023-January/021318.html [bitcoin-dev] OP_VAULT announcment + Post-History: 2023-01-09: https://lists.linuxfoundation.org/pipermail/bitcoin-dev/2023-January/021318.html [bitcoin-dev] OP_VAULT announcement 2023-03-01: https://lists.linuxfoundation.org/pipermail/bitcoin-dev/2023-March/021510.html [bitcoin-dev] BIP for OP_VAULT
diff --git a/bip-0351.mediawiki b/bip-0351.mediawiki index 0a31ca8d68..a782b0c8f9 100644 --- a/bip-0351.mediawiki +++ b/bip-0351.mediawiki @@ -31,7 +31,7 @@ A recipient that wishes to receive funds privately has several options. Each has * The BIP uses a notification mechanism that relies on publicly known per-recipient notification addresses. If Alice wants to send funds to Bob, she has to use the same notification address that everyone else uses to notify Bob. If Alice is not careful with coin selection, i.e. ensuring that her notification UTXO is not linked to her, she will publicly expose herself as someone who is trying to send funds to Bob and their relationship becomes permanently visible on the blockchain. -* The BIP does not say anything about address types. Receiving wallets therefore have to watch all address types that can be created from a single public key. Even then, a sender could send to a script that a receipient cannot spend from. +* The BIP does not say anything about address types. Receiving wallets therefore have to watch all address types that can be created from a single public key. Even then, a sender could send to a script that a recipient cannot spend from. ==Method== @@ -113,7 +113,7 @@ Notifications are performed by publishing transactions that contain a 40-byte x * P)[0..4]'' (4 bytes) * ''Nx'' is the unique public key a sender is using for a particular recipient (33 bytes) -* ''address_type'' is the '''ordinal''' value of a single address type that a sender wants to send to (1 byte). This must be selected from the recepient's accepted address types. +* ''address_type'' is the '''ordinal''' value of a single address type that a sender wants to send to (1 byte). This must be selected from the recipient's accepted address types. When Alice wants to notify Bob that he will receive future payments from her, she performs the following procedure: diff --git a/bip-0352/reference.py b/bip-0352/reference.py index c98dac8965..9f43695fee 100755 --- a/bip-0352/reference.py +++ b/bip-0352/reference.py @@ -221,7 +221,7 @@ def scanning(b_scan: ECKey, B_spend: ECPubKey, A_sum: ECPubKey, input_hash: byte ) for input in given["vin"] ] - # Conver the tuples to lists so they can be easily compared to the json list of lists from the given test vectors + # Convert the tuples to lists so they can be easily compared to the json list of lists from the given test vectors input_priv_keys = [] input_pub_keys = [] for vin in vins: diff --git a/bip-0389.mediawiki b/bip-0389.mediawiki index 500d7e3cf8..72121b7456 100644 --- a/bip-0389.mediawiki +++ b/bip-0389.mediawiki @@ -36,7 +36,7 @@ For extended keys and their derivations paths in a Key Expression, BIP 380 state ** Followed by zero or more /NUM or /NUMh path elements indicating BIP 32 derivation steps to be taken after the given extended key. ** Optionally followed by a single /* or /*h final step to denote all direct unhardened or hardened children. -This is modifed to state: +This is modified to state: * xpub encoded extended public key or xprv encoded extended private key (as defined in BIP 32) ** Followed by zero or more /NUM (may be followed by h, H, or ' to indicate a hardened step) path elements indicating BIP 32 derivation steps to be taken after the given extended key. From 996e31fa168a6b243ebae54f1bf0b2b8052cc659 Mon Sep 17 00:00:00 2001 From: Tom Briar Date: Tue, 9 Jan 2024 11:47:40 -0500 Subject: [PATCH 277/454] bip-tombriar-compressed-transactions --- ...tombriar-compressed-transactions.mediawiki | 301 ++++++++++++++++++ 1 file changed, 301 insertions(+) create mode 100644 bip-tombriar-compressed-transactions.mediawiki diff --git a/bip-tombriar-compressed-transactions.mediawiki b/bip-tombriar-compressed-transactions.mediawiki new file mode 100644 index 0000000000..3392234b6d --- /dev/null +++ b/bip-tombriar-compressed-transactions.mediawiki @@ -0,0 +1,301 @@ +
+  BIP: 337
+  Layer: API/RPC
+  Title: Compressed Transactions
+  Author: Tom Briar 
+  Comments-URI: https://github.com/bitcoin/bips/wiki/Comments:BIP-tombriar-compressed-transactions
+  Status: Draft
+  Type: Standards Track
+  Created: 2024-02-01
+  License: BSD-3-Clause
+  Post-History: https://github.com/bitcoin/bitcoin/pull/29134
+                https://lists.linuxfoundation.org/pipermail/bitcoin-dev/2023-August/021924.html
+
+ +== Introduction == + +=== Abstract === +This document proposes a serialization scheme for compressing Bitcoin transactions. The compressed Bitcoin transactions can reach a serialized size of less than 50% of the original serialized transaction. One method for compressing involves reducing the transaction outpoints in a potentially lossy way. Therefore, it is an optional path for compression. Compressing the outpoints is necessary for compressed transactions to reach less than 70% of the original size. + +=== Motivation === +Typical Bitcoin transactions usually contain a large amount of white space and padding due to specific fields that are often one of a minimal number of possibilities. We can use this fact and a few similar methods to create an encoding for 90% of Bitcoin transactions that are roughly 25-50% smaller. + +There exists a working-in-progress app that allows the use of steganography to encode data in images to be passed around via various social media groups. When used in conjunction with this compression scheme and an elligator squared encryption, this would allow for a very secure and private form of broadcasting bitcoin transactions. + +=== Rationale === + +The four main methods to achieve a lower transaction size are: + +1. Packing transaction metadata before it and each of its inputs and outputs to determine the following data structure. + +2. Replacing 32-bit numeric values with either variable-length integers (VarInts) or compact integers (CompactSizes). + +3. Using compressed signatures and public key recovery upon decompression. + +4. Replacing the 36-byte Outpoint txid/vout pair with a block height and index. + + +=== Backwards Compatibility === + +There are no concerns with backwards compatibility. + +=== Specification === + +==== Primitives ==== + +{| class="wikitable" style="margin:auto" +|- +! Name !! Width !! Description +|- +| CompactSize || 1-5 Bytes || For 0-253, encode the value directly in one byte. For 254-65535, encode 254 followed by two little-endian bytes. For 65536-(2^32-1), encode 255 followed by four little-endian bytes. +|- +| CompactSize Flag || 2 Bits || 1, 2, or 3 indicate literal values. 0 indicates that a CompactSize encoding of the value will follow. +|- +| VarInt || 1+ Bytes || 7-bit little-endian encoding, with each 7-bit word encoded in a byte. The highest bit of each byte is one if more bytes follow, and 0 for the last byte. +|- +| VLP-Bytestream || 2+ Bytes || A VarInt Length Prefixed Bytestream. It uses the prefixed VarInt to determine the length of the following byte stream. +|} + +==== General Schema ==== + +{| class="wikitable" style="margin:auto" +|- +! Name !! Width !! Description +|- +| Transaction metadata || 1 Bytes || Information on the structure of the transaction. See [[#transaction-metadata|Transaction Metadata]] +|- +| Version || 0-5 Bytes || If present according to the metadata field, a CompactSize encoding of the transaction version. +|- +| Input Count || 0-5 Bytes || If present according to the metadata field, a CompactSize encoding of the transaction input count. +|- +| Output Count || 0-5 Bytes || If present according to the metadata field, a CompactSize encoding of the transaction output count. +|- +| LockTime || 0-5 Bytes || If present according to the metadata field, a CompactSize encoding of the transaction LockTime. +|- +| Minimum Blockheight || 1-5 Bytes || If present according to the metadata field, a VarInt encoding of the minimum block height for transaction compressed inputs and LockTime. +|- +| Input Metadata+Output Metadata || 1+ Bytes || An encoding containing the metadata for all the inputs followed by all the outputs of the transaction. For each input, see [[#input-metadata|Input Metadata]], and for each output, see [[#output-metadata|Output Metadata]]. +|- +| Input Data || 66+ Bytes || See [[#input-data|Input Data]]. +|- +| Output Data || 3+ Bytes || See [[#output-data|Output Data]]. +|} + + +==== Transaction Metadata ==== + +{| class="wikitable" style="margin:auto" +|- +! Name !! Width !! Description +|- +| Version || 2 Bits || A CompactSize flag for the transaction version. +|- +| Input Count || 2 Bits || A CompactSize flag for the transaction input count. +|- +| Output Count || 2 Bits || A CompactSize flag for the transaction output count. +|- +| LockTime || 1 Bit || A boolean to indicate if the transaction has a LockTime. +|- +| Minimum Blockheight || 1 Bit || A boolean to indicate if the transaction minimum block height is greater than zero. +|} + + +==== Input Metadata ==== + +{| class="wikitable" style="margin:auto" +|- +! Name !! Width !! Description +|- +| Compressed Signature || 1 Bit || A Boolean do determine if this input's signature is compressed. The signature is only compressed for P2TR on a key spend and for P2SH when it is a wrapped P2SH-WPKH. +|- +| Standard Hash || 1 Bit || A Boolean to determine if this input's signature hash type is standard (0x00 for Taproot, 0x01 for Legacy/Segwit). +|- +| Standard Sequence || 2 Bits || A CompactSize flag for this input's sequence. Encode literal values as follows: 1 = 0x00000000, 2 = 0xFFFFFFFE, 3 = 0xFFFFFFFF. +|- +| Compressed OutPoint || 1 bit || A Boolean to determine if the input's outpoint is compressed. +|} + + +==== Output Metadata ==== + +{| class="wikitable" style="margin:auto" +|- +! Name !! Width !! Description +|- +| Encoded Script Type || 3 Bits || [[#script-type-encoding|Encoded Script Type]]. +|} + + +==== Script Type Encoding ==== + +{| class="wikitable" style="margin:auto" +|- +! Script Type !! Value +|- +| Uncompressed Custom Script || 0b000 +|- +| Uncompressed P2PK || 0b001 +|- +| Compressed P2PK || 0b010 +|- +| P2PKH || 0b011 +|- +| P2SH || 0b100 +|- +| P2WPKH || 0b101 +|- +| P2WSH || 0b110 +|- +| P2TR || 0b111 +|} + + +==== Input Data ==== + +{| class="wikitable" style="margin:auto" +|- +! Name !! Width !! Description +|- +| Outpoint || 2-37 Bytes || The Outpoint Txid/Vout are determined to be compressed or otherwise by the "Compressed Outpoint" Boolean in the input metadata. For each compressed outpoint see [[#compressed-outpoint|Compressed Outpoint]]. For each uncompressed signature see [[#uncompressed-outpoint|Uncompressed Outpoint]]. +|- +| Signature || 64+ Bytes || The Signature is determined to be compressed or otherwise by the output script of the previous transaction. For each compressed signature see [[#compressed-signature|Compressed Signature]]. For each uncompressed signature see [[#uncompressed-signature|Uncompressed Signature]]. +|- +| Sequence || 0-5 Bytes || If present due to a non-standard sequence, a VarInt encoding of the sequence. +|} + + +==== Compressed Outpoint ==== + +{| class="wikitable" style="margin:auto" +|- +! Name !! Width !! Description +|- +| Txid Block Height || 1-5 Bytes || A VarInt containing the offset from Minimum Blockheight for this Txid. +|- +| Txid Block Index || 1-5 Bytes || A VarInt containing the flattened index from the Txid block height for the Vout. +|} + + +==== Uncompressed Outpoint ==== + +{| class="wikitable" style="margin:auto" +|- +! Name !! Width !! Description +|- +| Txid || 32 Bytes || Contains the 32 Byte Txid. +|- +| Vout || 1-5 Bytes || A CompactSize Containing the Vout of the Txid. +|} + + + +==== Compressed Signature ==== + +{| class="wikitable" style="margin:auto" +|- +! Name !! Width !! Description +|- +| Signature || 64 Bytes || Contains the 64 Byte signature. +|- +| Pubkey Hash || 0-20 Bytes || If input is P2SH-P2WPKH contains the 20 byte hash of the public key. +|- +| Hash Type || 0-1 Bytes || An Optional Byte containing the Hash Type if it was non-standard. +|} + + +==== Uncompressed Signature ==== + +{| class="wikitable" style="margin:auto" +|- +! Name !! Width !! Description +|- +| Signature || 2+ Bytes || A VLP-Bytestream containing the signature. +|} + + +==== Output Data ==== + +{| class="wikitable" style="margin:auto" +|- +! Name !! Width !! Description +|- +| Output Script || 2+ Bytes || A VLP-Bytestream containing the output script. +|- +| Amount || 1-9 Bytes || A VarInt containing the output amount. +|} + +==== Ideal Transaction ==== + +The compression scheme was designed to be optimal for a "typical" transaction, spending a few close-in-age inputs and having one or two outputs. Here are size +values for such a transaction, which demonstrate the effectiveness of the compression. + +{| class="wikitable" style="margin:auto" +|- +! Field !! Requirements !! Savings Up To +|- +| Version || Less than four || 30 Bits +|- +| Input Count || Less than four || 30 Bits +|- +| Output Count || Less than four || 30 Bits +|- +| LockTime || 0 || 30 Bits +|- +| Input Sequence || 0x00, 0xFFFFFFFE, or 0xFFFFFFFF || 62 Bits For Each Input +|- +| Input Txid || Compressed Outpoint || 23 - 31 Bytes For Each Input +|- +| Input Vout || Compressed Outpoint || (-1) - 3 Bytes For Each Input +|- +| Input Signature || Non-custom Script Signing || 40 - 72 Bytes For Each Legacy Input +|- +| Input Hash Type || 0x00 for Taproot, 0x01 for Legacy || 7 Bits For Each Input +|- +| Output Script || Non-custom Scripts || 2 - 5 Bytes For Each Output +|- +| Output Amount || No Restrictions || (-1) - 7 Bytes For Each Output +|} + +=== Reference Implementation === + +This reference implementation adds two new RPC endpoints, compressrawtransaction and decompressrawtransaction. The first accepts a raw hex-encoded transaction and returns a compact hex-encoded transaction; also included in the output is a list of warnings to help ensure there are no unexpected uncompressed values. The second accepts a compact hex transaction and returns the uncompressed raw hex-encoded transaction. + +https://github.com/bitcoin/bitcoin/pull/29134 + +=== Test Vectors === + +==== Taproot ==== + +===== Uncompressed ===== +020000000001017ad1d0cc314504ec06f1b5c786c50cf3cda30bd5be88cf08ead571b0ce7481fb0000000000fdffffff0188130000000000001600142da377ed4978fefa043a58489912f8e28e16226201408ce65b3170d3fbc68e3b6980650514dc53565f915d14351f83050ff50c8609495b7aa96271c3c99cdac1a92b1b45e77a4a870251fc1673596793adf2494565e500000000 + +===== Compressed ===== +96b1ec7f968001b0218ce65b3170d3fbc68e3b6980650514dc53565f915d14351f83050ff50c8609495b7aa96271c3c99cdac1a92b1b45e77a4a870251fc1673596793adf2494565e58efefefe7d2da377ed4978fefa043a58489912f8e28e162262a608 + +==== P2WPKH ==== + +===== Uncompressed ===== +0200000000010144bcf05ab48b8789268a7ca07133241ad654c0739ac7165015b2d669eadb10ea0000000000fdffffff0188130000000000001600142da377ed4978fefa043a58489912f8e28e16226202473044022043ab639a98dfbc704f16a35bf25b8b72acb4cb928fd772285f1fcf63725caa85022001c9ff354504e7024708bce61f30370c8db13da8170cef4e8e4c4cdad0f71bfe0121030072484c24705512bfb1f7f866d95f808d81d343e552bc418113e1b9a1da0eb400000000 + +===== Compressed ===== +96b1ec71968001932643ab639a98dfbc704f16a35bf25b8b72acb4cb928fd772285f1fcf63725caa8501c9ff354504e7024708bce61f30370c8db13da8170cef4e8e4c4cdad0f71bfe8efefefe7d2da377ed4978fefa043a58489912f8e28e162262a608 + +==== P2SH-P2WPKH ==== + +===== Uncompressed ===== +0200000000010192fb2e4332b43dc9a73febba67f3b7d97ba890673cb08efde2911330f77bbdfc00000000171600147a1979232206857167b401fdac1ffbf33f8204fffdffffff0188130000000000001600142da377ed4978fefa043a58489912f8e28e16226202473044022041eb682e63c25b85a5a400b11d41cf4b9c25f309090a5f3e0b69dc15426da90402205644ddc3d5179bab49cce4bf69ebfaeab1afa34331c1a0a70be2927d2836b0e8012103c483f1b1bd24dd23b3255a68d87ef9281f9d080fd707032ccb81c1cc56c5b00200000000 + +===== Compressed ===== +96b1ec7c9e8001981641eb682e63c25b85a5a400b11d41cf4b9c25f309090a5f3e0b69dc15426da9045644ddc3d5179bab49cce4bf69ebfaeab1afa34331c1a0a70be2927d2836b0e87a1979232206857167b401fdac1ffbf33f8204ff8efefefe7d2da377ed4978fefa043a58489912f8e28e162262a608 + +==== P2PKH ==== + +===== Uncompressed ===== +02000000015f5be26862482fe2fcc900f06ef26ee256fb205bc4773e5a402d0c1b88b82043000000006a473044022031a20f5d9212023b510599c9d53d082f8e07faaa2d51482e078f8e398cb50d770220635abd99220ad713a081c4f20b83cb3f491ed8bd032cb151a3521ed144164d9c0121027977f1b6357cead2df0a0a19570088a1eb9115468b2dfa01439493807d8f1294fdffffff0188130000000000001600142da377ed4978fefa043a58489912f8e28e16226200000000 + +===== Compressed ===== +96b1ec7c968001981431a20f5d9212023b510599c9d53d082f8e07faaa2d51482e078f8e398cb50d77635abd99220ad713a081c4f20b83cb3f491ed8bd032cb151a3521ed144164d9c8efefefe7d2da377ed4978fefa043a58489912f8e28e162262a608 + + +== Acknowledgements == +Thank you to Andrew Poelstra, who helped invent and develop the ideas in the proposal and the code for reference implementation. From 73cfb05b94058e7acf06ef6762b4a4158b631731 Mon Sep 17 00:00:00 2001 From: Murch Date: Tue, 28 May 2024 14:35:46 -0400 Subject: [PATCH 278/454] BIP-0337: Fix Comments-URI --- bip-tombriar-compressed-transactions.mediawiki | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/bip-tombriar-compressed-transactions.mediawiki b/bip-tombriar-compressed-transactions.mediawiki index 3392234b6d..e87c5bc2c4 100644 --- a/bip-tombriar-compressed-transactions.mediawiki +++ b/bip-tombriar-compressed-transactions.mediawiki @@ -3,7 +3,7 @@ Layer: API/RPC Title: Compressed Transactions Author: Tom Briar - Comments-URI: https://github.com/bitcoin/bips/wiki/Comments:BIP-tombriar-compressed-transactions + Comments-URI: https://github.com/bitcoin/bips/wiki/Comments:BIP-0337 Status: Draft Type: Standards Track Created: 2024-02-01 From f240c402848fc467d2aa9a7062c943a9bf3b1f4c Mon Sep 17 00:00:00 2001 From: Murch Date: Tue, 28 May 2024 14:37:43 -0400 Subject: [PATCH 279/454] BIP-0337: Add table entry, move to numbered file --- README.mediawiki | 7 +++++++ ...compressed-transactions.mediawiki => bip-0337.mediawiki | 0 2 files changed, 7 insertions(+) rename bip-tombriar-compressed-transactions.mediawiki => bip-0337.mediawiki (100%) diff --git a/README.mediawiki b/README.mediawiki index 710e128e61..c82b2bdff1 100644 --- a/README.mediawiki +++ b/README.mediawiki @@ -1037,6 +1037,13 @@ Those proposing changes should consider that ultimately consent may rest with th | Standard | Draft |- +| [[bip-0337.mediawiki|337]] +| API/RPC +| Compressed Transactions +| Tom Briar +| Standard +| Draft +|- | [[bip-0338.mediawiki|338]] | Peer Services | Disable transaction relay message diff --git a/bip-tombriar-compressed-transactions.mediawiki b/bip-0337.mediawiki similarity index 100% rename from bip-tombriar-compressed-transactions.mediawiki rename to bip-0337.mediawiki From 46a2440718ce96681155e4c96bfc373d079d2eef Mon Sep 17 00:00:00 2001 From: cocoyeal Date: Wed, 29 May 2024 16:18:11 +0800 Subject: [PATCH 280/454] remove duplicated words --- bip-0047.mediawiki | 6 +++--- bip-0093.mediawiki | 2 +- bip-0115.mediawiki | 2 +- bip-0116.mediawiki | 2 +- bip-0135.mediawiki | 6 +++--- bip-0350.mediawiki | 2 +- bip-0352.mediawiki | 2 +- bip-0372.mediawiki | 2 +- 8 files changed, 12 insertions(+), 12 deletions(-) diff --git a/bip-0047.mediawiki b/bip-0047.mediawiki index a15a15de52..c44bea9d3b 100644 --- a/bip-0047.mediawiki +++ b/bip-0047.mediawiki @@ -17,7 +17,7 @@ RECENT CHANGES: ==Status== -This BIP can be be considered final in terms of enabling compatibility with wallets that implement version 1 and version 2 reusable payment codes, however future developments of the reusable payment codes specification will not be distributed via the BIP process. +This BIP can be considered final in terms of enabling compatibility with wallets that implement version 1 and version 2 reusable payment codes, however future developments of the reusable payment codes specification will not be distributed via the BIP process. The Open Bitcoin Privacy Project RFC repo should be consulted for specifications related to version 3 or higher payment codes: https://github.com/OpenBitcoinPrivacyProject/rfc @@ -350,12 +350,12 @@ Version 2 payment codes behave identifically to version 1 payment codes, except ====Definitions==== -* Notification change output: the change output from a notification transaction which which resides in the sender's wallet, but can be automatically located by the intended recipient +* Notification change output: the change output from a notification transaction which resides in the sender's wallet, but can be automatically located by the intended recipient * Payment code identifier: a 33 byte representation of a payment code constructed by prepending 0x02 to the SHA256 hash of the binary serialization of the payment code ====Notification Transaction==== -Note: this procedure is used if Bob uses a version 2 payment code (regardless of the the version of Alice's payment code). If Bob's payment code is not version 2, see the appropriate section in this specification. +Note: this procedure is used if Bob uses a version 2 payment code (regardless of the version of Alice's payment code). If Bob's payment code is not version 2, see the appropriate section in this specification. # Construct a notification transaction as per the version 1 instructions, except do not create the output to Bob's notification address # Create a notification change address as follows: diff --git a/bip-0093.mediawiki b/bip-0093.mediawiki index da349fdd8b..22a7ba32e9 100644 --- a/bip-0093.mediawiki +++ b/bip-0093.mediawiki @@ -354,7 +354,7 @@ Instead every different language has it own word list (or word lists) and each c We would need to encode the choice of word list in our share's meta-data, which takes up even more room, and is difficult to specify due to the ever-evolving choice of word lists. Alternatively we could standardize on the choice of the English word list, something that is nearly a de facto standard, and simply be incompatible with BIP-0039 wallets of other languages. -Such a choice also risks users of BIP-0039 recovering their entropy from their language, encoding it in in Codex32 and then failing to recover their wallet because the English word lists has replaced their language's word list. +Such a choice also risks users of BIP-0039 recovering their entropy from their language, encoding it in Codex32 and then failing to recover their wallet because the English word lists has replaced their language's word list. The main advantage of this alternative approach would be that wallets could give users an option switch between backing up their entropy as a BIP-0039 mnemonic and in Codex32 format, but again, only if their language choice happens to be the English word list. In practice, we do not expect users in switch back and forth between backup formats, and instead just generate a fresh master seed using Codex32. diff --git a/bip-0115.mediawiki b/bip-0115.mediawiki index 8bc90f6949..042d0570ec 100644 --- a/bip-0115.mediawiki +++ b/bip-0115.mediawiki @@ -98,7 +98,7 @@ What if ParamBlockHash has leading zeros? Should this be prevented? * If leading zeros are included, they should be compared to the actual block hash. (If they were truncated, fewer bytes would be compared.) * It is unlikely that the leading zeros will ever be necessary for sufficient precision, so the additional space is not a concern. -* Since all block hashes are in principle shorter than than 29 bytes, ParamBlockHash may not be larger than 28 bytes. +* Since all block hashes are in principle shorter than 29 bytes, ParamBlockHash may not be larger than 28 bytes. Why is it safe to allow checking blocks as recently as the immediate previous block? diff --git a/bip-0116.mediawiki b/bip-0116.mediawiki index 86b0f9aaae..70b340f575 100644 --- a/bip-0116.mediawiki +++ b/bip-0116.mediawiki @@ -59,7 +59,7 @@ This includes execution pathways or policy conditions which end up not being nee Not only is it inefficient to require this unnecessary information to be present on the blockchain, albeit in the witness, it also impacts privacy and fungibility as some unused script policies may be identifying. Using a Merkle hash tree to commit to the policy options, and then only forcing revelation of the policy used at redemption minimizes this information leakage. -Using Merkle hash trees to commit to policy allows for considerably more complex contracts than would would otherwise be possible, due to various built-in script size and runtime limitations. +Using Merkle hash trees to commit to policy allows for considerably more complex contracts than would otherwise be possible, due to various built-in script size and runtime limitations. With Merkle commitments to policy these size and runtime limitations constrain the complexity of any one policy that can be used rather than the sum of all possible policies. ==Rationale== diff --git a/bip-0135.mediawiki b/bip-0135.mediawiki index 1324746d59..a4c06472c3 100644 --- a/bip-0135.mediawiki +++ b/bip-0135.mediawiki @@ -170,7 +170,7 @@ A given deployment SHALL remain in the DEFINED state until it either passes the starttime (and becomes STARTED) or the timeout time (and becomes FAILED). Once a deployment has STARTED, the signal for that deployment SHALL be tallied -over the the past windowsize blocks whenever a new block is received on that +over the past windowsize blocks whenever a new block is received on that chain. A transition from the STARTED state to the LOCKED_IN state SHALL only occur @@ -183,7 +183,7 @@ when all of these are true: A similar height synchronization precondition SHALL exist for the transition from LOCKED_IN to ACTIVE. These synchronization conditions are expressed by the "mod(height, windowsize) = 0" -clauses in the diagram, and have been been added so that backward compatibility +clauses in the diagram, and have been added so that backward compatibility with BIP9's use of the 2016-block re-targeting periods can be configured for existing deployments (see above 'Optional full backward compatibility' section). @@ -261,7 +261,7 @@ proposal, although a conventional fallow period of 3 months is RECOMMENDED. Due to the constraints set by BIP 34, BIP 66 and BIP 65, there are only 0x7FFFFFFB possible nVersion values available. This limits to at most 30 independent deployments. -By restricting the top 3 bits to 001 we we are left with 29 out of those for +By restricting the top 3 bits to 001 we are left with 29 out of those for the purposes of this proposal, and support two future upgrades for different mechanisms (top bits 010 and 011). diff --git a/bip-0350.mediawiki b/bip-0350.mediawiki index 439b2a25a9..4c30b8f841 100644 --- a/bip-0350.mediawiki +++ b/bip-0350.mediawiki @@ -217,7 +217,7 @@ their invalidity. Checksums are used to detect errors introduced into data during transfer. A hash function-based checksum such as Base58Check detects any type of error uniformly, but not all classes of errors are equally likely to occur in practice. Bech32 prioritizes detection of substitution errors, but improving detection of one error class inevitably worsens detection of other error classes. During the design of Bech32, it was assumed that other simple error patterns beside substitutions would have a similar detection rate as in a hash function-based design, and detection would only be worse for complex, impractical errors. The discovered insertion weakness shows that this is not the case. -For Bech32m, we aim to retain Bech32's guarantees for substitution errors, but make sure that other common errors don't perform worse than a hash function-based checksum would. To make sure the new standard is easy to implement, we restrict the design space to only amending the final constant that is xored in, as it was [https://lists.linuxfoundation.org/pipermail/bitcoin-dev/2019-December/017521.html observed] that that is sufficient to mitigate the 'q' insertion issue while retaining the intended substitution error detection. In what follows, we explain how the new constant ''0x2bc830a3'' was chosen. +For Bech32m, we aim to retain Bech32's guarantees for substitution errors, but make sure that other common errors don't perform worse than a hash function-based checksum would. To make sure the new standard is easy to implement, we restrict the design space to only amending the final constant that is xored in, as it was [https://lists.linuxfoundation.org/pipermail/bitcoin-dev/2019-December/017521.html observed] that is sufficient to mitigate the 'q' insertion issue while retaining the intended substitution error detection. In what follows, we explain how the new constant ''0x2bc830a3'' was chosen. ===Error patterns & detection probability=== diff --git a/bip-0352.mediawiki b/bip-0352.mediawiki index 0eff355eea..4cbf9d7230 100644 --- a/bip-0352.mediawiki +++ b/bip-0352.mediawiki @@ -451,7 +451,7 @@ This distinction makes the problem for light clients more clear: light clients n Recall that a silent payment eligible transaction follows [[#scanning-silent-payment-eligible-transactions|certain conditions]] and should have at least one unspent taproot output. Full nodes (or any index server backed by a full node, such as electrum server) can build an index which collects all of the eligible public keys for a silent payments eligible transaction, sums them up, multiplies the sum by the ''input_hash'', and serves them to clients. This would be 33 bytes per silent payment eligible transaction. -For a typical bitcoin block of ~3500 txs, lets assume every transaction is a silent payments eligible transaction. This means a client would need to request ''33 bytes * 3500'' of data per block (roughly 100 kB per block). If a client were to request data for every block, this would amount to ~450 MB per month, assuming 100% taproot usage and all outputs remain unspent for > 1 month. As of today, these numbers are closer to 2–10 kB per block (10–50 MB per month)''' Data for Appendix A ''' These numbers are based on data from January 2023 until June 2023 (the last 6 months of data at time time of writing). See [https://github.com/josibake/bitcoin-data-analysis/blob/main/notebooks/silent-payments-light-client-data.ipynb Silent payments light client data] for the full analysis.. +For a typical bitcoin block of ~3500 txs, lets assume every transaction is a silent payments eligible transaction. This means a client would need to request ''33 bytes * 3500'' of data per block (roughly 100 kB per block). If a client were to request data for every block, this would amount to ~450 MB per month, assuming 100% taproot usage and all outputs remain unspent for > 1 month. As of today, these numbers are closer to 2–10 kB per block (10–50 MB per month)''' Data for Appendix A ''' These numbers are based on data from January 2023 until June 2023 (the last 6 months of data at the time of writing). See [https://github.com/josibake/bitcoin-data-analysis/blob/main/notebooks/silent-payments-light-client-data.ipynb Silent payments light client data] for the full analysis.. === Transaction cut-through === diff --git a/bip-0372.mediawiki b/bip-0372.mediawiki index bf98b7c022..ee40dd0ddf 100644 --- a/bip-0372.mediawiki +++ b/bip-0372.mediawiki @@ -17,7 +17,7 @@ ===Abstract=== This document proposes additional fields for BIP 174 PSBTv0 and BIP 370 PSBTv2 -that allow for pay-to-contract key tweaking data data to be included in a PSBT +that allow for pay-to-contract key tweaking data to be included in a PSBT of any version. These will represent an extra-transaction information required for the signer to produce valid signatures spending previous outputs. From 4f75edb2b85f55f5723e379584e52181f5f44269 Mon Sep 17 00:00:00 2001 From: Matt Corallo Date: Sat, 10 Feb 2024 22:46:16 +0000 Subject: [PATCH 281/454] Add a BIP which resolves human readable names into payment info User behavior has clearly indicated a strong demand for the resolution of human-readable names into payment instructions. This BIP defines a protocol to do so using only the DNS, providing for the ability to query such resolutions privately, while utilizing DNSSEC to provide compact and simple to verify proofs of mappings. --- README.mediawiki | 7 +++ bip-0353.mediawiki | 130 +++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 137 insertions(+) create mode 100644 bip-0353.mediawiki diff --git a/README.mediawiki b/README.mediawiki index 6dbd798420..8e6deb8e98 100644 --- a/README.mediawiki +++ b/README.mediawiki @@ -1086,6 +1086,13 @@ Those proposing changes should consider that ultimately consent may rest with th | Informational | Draft |- +| [[bip-0353.mediawiki|353]] +| Applications +| DNS Payment Instructions +| Matt Corallo, Bastien Teinturier +| Standard +| Draft +|- | [[bip-0370.mediawiki|370]] | Applications | PSBT Version 2 diff --git a/bip-0353.mediawiki b/bip-0353.mediawiki new file mode 100644 index 0000000000..16466724c3 --- /dev/null +++ b/bip-0353.mediawiki @@ -0,0 +1,130 @@ +
+  BIP: 353
+  Layer: Applications
+  Title: DNS Payment Instructions
+  Author: Matt Corallo 
+          Bastien Teinturier 
+  Comments-Summary: No comments yet.
+  Comments-URI: https://github.com/bitcoin/bips/wiki/Comments:BIP-0353
+  Status: Draft
+  Type: Standards Track
+  Created: 2024-02-10
+  License: CC0-1.0
+  Post-History: 2024-02-13: https://groups.google.com/g/bitcoindev/c/uATaflkYglQ [bitcoin-dev] Mapping Human-Readable Names to Payment Instructions
+
+ + +==Copyright== + +This BIP is licensed under the CC0-1.0 license. + +==Abstract== +This BIP proposes a standard format for encoding [[bip-0021.mediawiki|BIP 21]] URI schemes in DNS TXT records. + +==Motivation== +Various Bitcoin and other cryptocurrency applications have developed human-readable names for payment instructions over time, with marketplace adoption signaling strong demand for it from users. + +The DNS provides a standard, global, hierarchical namespace mapping human-readable labels to records of various forms. Using DNSSEC, the DNS provides cryptographic guarantees using a straightforward PKI which follows the hierarchical nature of the DNS, allowing for stateless and even offline validation of DNS records from a single trusted root. + +Further, because DNS queries are generally proxied through ISP-provided or other resolvers, DNS queries usually do not directly expose the queryer's IP address. Further, because of the prevalence of open resolvers, the simplicity of the protocol, and broad availability of DNS recursive resolver implementations, finding a proxy for DNS records is trivial. + +Thus, using TXT records to store Bitcoin payment instructions allows for human-readable Bitcoin payment destinations which can be trivially verified on hardware wallets and which can be resolved relatively privately. + +==Specification== + +=== General rules for handling === +Bitcoin wallets MUST NOT prefer to use DNS-based resolving when methods with explicit public keys or addresses are available. In other words, if a standard Bitcoin address or direct BIP 21 URI is available or would suffice, Bitcoin wallets MUST prefer to use that instead. + +=== Records === +Payment instructions are indexed by both a user and a domain. Instructions for a given `user` and `domain` are stored at `user`.user._bitcoin-payment.`domain` in a single TXT record. + +All payment instructions MUST be DNSSEC-signed. + +Payment instructions MAY resolve through CNAME or DNAME records as long as all such records and the ultimate records pointed to by them are DNSSEC signed. + +User and domain names which are not expressible using standard printable ASCII MUST be encoded using the punycode IDN encoding defined in [[https://datatracker.ietf.org/doc/html/rfc3492|RFC 3492]] and [[https://datatracker.ietf.org/doc/html/rfc5891|RFC 5891]]. + +Note that because resolvers are not required to support resolving non-ASCII identifiers, wallets SHOULD avoid using non-ASCII identifiers. + +=== Resolution === + +Clients resolving Bitcoin payment instructions MUST ignore any TXT records at the same label which do not begin with (ignoring case) "bitcoin:". Resolvers encountering multiple "bitcoin:"-matching TXT records at the same label MUST treat the records as invalid and refuse to use any payment instructions therein. + +Clients resolving Bitcoin payment instructions MUST fully validate DNSSEC signatures leading to the DNS root (including any relevant CNAME or DNAME records) and MUST NOT accept DNSSEC signatures which use SHA-1 or RSA with keys shorter than 1024 bits. Resolvers MAY accept SHA-1 DS records. + +Clients resolving Bitcoin payment instructions MUST NOT trust a remote resolver to validate DNSSEC records on their behalf. + +Clients resolving Bitcoin payment instructions MUST support resolving through CNAME or DNAME records. + +Resolvers MAY support resolving non-ASCII user and domain identifiers. Resolvers which do support non-ASCII user and domain identifiers MUST take precautions to prevent homograph attacks and SHOULD consider denying paste functionality when entering non-ASCII identifiers. Wallets which do not take any such precautions MUST instead display non-ASCII user and domain identifiers using their raw punycode. As such, wallets SHOULD NOT create identifiers which are not entirely printable ASCII. + +While clients MAY cache the payment instructions they receive from the DNS, clients MUST NOT cache the payment instructions received from the DNS for longer than the TTL provided by their DNS resolver, and further MUST NOT cache the payment instructions for longer than the lowest initial TTL (which is signed as a part of DNSSEC signatures) received in the full DNSSEC chain leading from the DNS root to the resolved TXT record. + +=== Address Reuse === + +Payment instructions with on-chain addresses which will be re-used SHOULD be rotated as regularly as possible to reduce address reuse. Such payment instructions SHOULD also use a relatively short DNS TTL to ensure regular rotation takes effect quickly. In cases where this is not practical, payment instructions SHOULD NOT contain on-chain addresses (i.e. the URI path SHOULD be empty). + +Payment instructions which do contain on-chain addresses which will be re-used SHOULD be rotated after any transaction to such an address is confirmed on-chain. + +=== Display === + +Wallets SHOULD parse recipient information in the form `user`@`domain` or ₿`user`@`domain` and resolve such entry into recipient information using the above record. Similarly, wallets accepting payment information from external devices (e.g. hardware wallets) SHOULD accept RFC 9102-formatted proofs (as a series of unsorted `AuthenticationChain` records) and, if they verify, SHOULD display the recipient in the form ₿`user`@`domain`. For the avoidance of doubt, the ₿ is *not* included in the DNS label which is resolved. + +Wallets providing users the ability to "copy" their address information generally SHOULD copy the underlying URI directly in order to avoid the DNS indirection. However, wallets providing users the ability to copy their human-readable address information MUST include the ₿ prefix (i.e. copy it in the form ₿`user`@`domain`). + +== Rationale == + +=== Display === + +There are several ways in which human-readable payment instructions could be displayed in wallets. In order to ensure compatibility with existing human-readable names schemes, @ is used as the separator between the `user` and `domain` parts. However, simply using the @ separator can lead to confusion between email addresses on a given domain and payment instructions on a domain. In order to somewhat reduce the incidence of such confusion, a ₿ prefix is used. + +=== Rotation === + +On-chain addresses which are re-used (i.e. not including schemes like [[bip-0352.mediawiki|Silent Payments]]) need to be rotated to avoid contributing substantially to address reuse. However, rotating them on a timer or any time a transaction enters the mempool could lead to substantial overhead from excess address generation. Instead, rotating addresses any time a transaction is confirmed on-chain ensures address rotation happens often while bounding the maximum number of addresses needed to one per block, which grows very slowly and will not generate an address set too large to handle while scanning the chain going forward. + +=== Alternatives === +There are many existing schemes to resolve human-readable names to cryptocurrency payment instructions. Sadly, these current schemes suffer from a myriad of drawbacks, including (a) lacking succinct proofs of namespace to public key mappings, (b) revealing sender IP addresses to recipients or other intermediaries as a side-effect of payment, (c) relying on the bloated TLS Certificate Authority infrastructure, or (d) lacking open access, not allowing anyone to create a namespace mapping. + +==== DNS Rather than blockchain-based solutions ==== +There are many blockchain-based alternatives to the DNS which feature better censorship-resistance and, in many cases, security. However, here we chose to use the standard ICANN-managed DNS namespace as many blockchain-based schemes suffer from (a), above (though in some cases this could be addressed with cryptographic SNARK schemes). Further, because they do not have simple client-side querying ability, many of these schemes use trusted intermediaries which resolve names on behalf of clients. This reintroduces drawbacks (b) and often (c) as well. + +Finally, it is worth noting that none of the blockchain-based alternatives to the DNS have had material adoption outside of their specific silos, and committing Bitcoin wallets to rely on a separate system which doesn't see broad adoption may not be sustainable. + +==== DNS Rather than HTTP-based solutions ==== +HTTP(s)-based payment instruction resolution protocols suffer from drawbacks (a), (b), and (c), above, and generally shouldn't be considered a serious alternative for payment instruction resolution. + +==== Private DNS Querying ==== +While public recursive DNS resolvers are very common (e.g. 1.1.1.1, 8.8.8.8, and 9.9.9.9), using such resolvers directly (even after validating DNSSEC signatures) introduces drawback (b), at least in regard to a centralized intermediary. Resolving payment instructions recursively locally using a resolver on the same local network or in the paying application would instead introduce drawback (b) directly to the recipient, which may well be worse. + +For payers not using VPN or other proxying technologies, they generally trust their ISP to not snoop on their DNS requests anyway, so using ISP-provided recursive DNS resolvers is likely the best option. + +However, for the best privacy, payers are encouraged to perform DNS resolution over Tor or another VPN technology. + +Lightning payers should consider utilizing DNS resolution over native onion messages, using the protocol described in [[https://github.com/lightning/blips/blob/master/blip-0032.md|BLIP 32]] + +=== DNS Enumeration === + +In most cases where payments are accepted from any third-party, user enumeration is practical by simply attempting to send small value payments to a list of possible user names. However, storing all valid users in the DNS directly may make such enumeration marginally more practical. Thus, those wishing to avoid such enumeration should carefully ensure all DNS names return valid payment instructions. Note when doing so that wildcard records are identified as such by the DNSSEC RRSIG labels counter and are differentiable from non-wildcard records. + +== Backwards Compatibility == + +This work is intended to extend and subsume the existing "Lightning Address" scheme, which maps similar names (without the ₿ prefix) using HTTPS servers to Lightning BOLT 11 payment instructions. Wallets implementing this scheme MAY fall back to existing "Lightning Address" logic if DNS resolution fails but SHOULD NOT do so after this scheme is sufficiently broadly deployed to avoid leaking sender IP address information. + +== Examples == + +`matt@mattcorallo.com` resolves to +`matt.user._bitcoin-payment.mattcorallo.com. 3600 IN TXT "bitcoin:?lno=lno1qsgqmqvgm96frzdg8m0gc6nzeqffvzsqzrxqy32afmr3jn9ggkwg3egfwch2hy0l6jut6vfd8vpsc3h89l6u3dm4q2d6nuamav3w27xvdmv3lpgklhg7l5teypqz9l53hj7zvuaenh34xqsz2sa967yzqkylfu9xtcd5ymcmfp32h083e805y7jfd236w9afhavqqvl8uyma7x77yun4ehe9pnhu2gekjguexmxpqjcr2j822xr7q34p078gzslf9wpwz5y57alxu99s0z2ql0kfqvwhzycqq45ehh58xnfpuek80hw6spvwrvttjrrq9pphh0dpydh06qqspp5uq4gpyt6n9mwexde44qv7lstzzq60nr40ff38u27un6y53aypmx0p4qruk2tf9mjwqlhxak4znvna5y"` +Note that `lno` indicates a value containing a lightning BOLT12 offer. + +== Reference Implementations == +* A DNSSEC proof generation and validation implementation can be found at https://git.bitcoin.ninja/index.cgi?p=dnssec-prover;a=summary +* A lightning-specific name to payment instruction resolver can be found at https://git.bitcoin.ninja/index.cgi?p=lightning-resolver;a=summary +* Reference implementations for parsing the URI contents can be found in [[bip-0021.mediawiki|BIP 21]]. + +== Acknowledgements == + +Thanks to Rusty Russell for the concrete address rotation suggestion. + +Thanks to the Bitcoin Design Community, and especially Christoph Ono for lots of discussion, analysis, and UX mockups in how human-readable payment instructions should be displayed. + +Thanks to Andrew Kaizer for the suggestion to explicitly restrict cache lifetime to the relevant DNS TTLs. From 87bbc4aeb6d7da736de63e86f3cb43cf87e39554 Mon Sep 17 00:00:00 2001 From: theborakompanioni Date: Thu, 6 Jun 2024 12:51:44 +0200 Subject: [PATCH 282/454] docs(bip-0046): add bip-0046 to readme --- README.mediawiki | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/README.mediawiki b/README.mediawiki index 47d3822a69..f84fcf0dc2 100644 --- a/README.mediawiki +++ b/README.mediawiki @@ -252,6 +252,13 @@ Those proposing changes should consider that ultimately consent may rest with th | Standard | Proposed |- +| [[bip-0046.mediawiki|46]] +| Applications +| Address Scheme for Timelocked Fidelity Bonds +| Chris Belcher, Thebora Kompanioni +| Standard +| Draft +|- | [[bip-0047.mediawiki|47]] | Applications | Reusable Payment Codes for Hierarchical Deterministic Wallets From 0a12bf8572c64f8b3217b58d005aba05cd4f66fe Mon Sep 17 00:00:00 2001 From: theborakompanioni Date: Thu, 6 Jun 2024 14:20:22 +0200 Subject: [PATCH 283/454] docs(bip-0046): apply minor wording improvement suggestions by @AdamISZ --- bip-0046.mediawiki | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/bip-0046.mediawiki b/bip-0046.mediawiki index 7bb8044909..70bc703e0e 100644 --- a/bip-0046.mediawiki +++ b/bip-0046.mediawiki @@ -14,7 +14,7 @@ == Abstract == -This BIP defines the derivation scheme for HD wallets which create timelocked addresses used for creating fidelity bonds. It also defines how to sign fidelity bond certificates, which are needed when using fidelity bonds that are stored offline. +This BIP defines the derivation scheme for HD wallets which create timelocked addresses used for creating fidelity bonds. It also gives advice to wallet developers on how to use fidelity bonds to sign over messages, such as certificates, which are needed when using fidelity bonds that are stored offline. == Copyright == @@ -24,11 +24,11 @@ This document is licensed under the Creative Commons CC0 1.0 Universal license. Fidelity bonds are used to resist sybil attacks in certain decentralized anonymous protocols. They are created by locking up bitcoins using the `OP_CHECKLOCKTIMEVERIFY` opcode. -It would be useful to have a common derivation scheme so that users of wallet software can have a backup of their fidelity bonds by storing only the HD seed and a reference to this BIP. Importantly the user does not need to backup any timelock values. +Having a common derivation scheme allows users of wallet software to have a backup of their fidelity bonds by storing only the HD seed and a reference to this BIP. Importantly the user does not need to backup any timelock values. We largely use the same approach used in BIPs 49, 84 and 86 for ease of implementation. -It would be useful to be able to keep the private keys of fidelity bonds in cold storage. This would allow the sybil resistance of a system to increase without hot wallet risk. +This allows keeping the private keys of fidelity bonds in cold storage, which increases the sybil resistance of a system without hot wallet risk. == Backwards Compatibility == @@ -54,7 +54,7 @@ Where the endpoint might be a IRC nickname or Tor onion hostname. The certificat == Rationale == -It would be useful for the user to avoid having to keep a record of the timelocks in the time-locked addresses. So only a limited small set of timelocks are defined by this BIP. This way the user must only store their seed phrase, and knowledge that they have coins stored using this BIP standard. The user doesn't need to remember or store any dates. +It is useful for the user to avoid having to keep a record of the timelocks in the time-locked addresses. So only a limited small set of timelocks are defined by this BIP. This way the user must only store their seed phrase, and knowledge that they have coins stored using this BIP standard. The user doesn't need to remember or store any dates. This standard is already implemented and deployed in JoinMarket. As most changes would require a protocol change of a live system, there is limited scope for changing this standard in review. This BIP is more about documenting something which already exists, warts and all. From 821fb900f8c550b7414403a59cfd5a2dd11a6050 Mon Sep 17 00:00:00 2001 From: theborakompanioni Date: Fri, 7 Jun 2024 12:04:30 +0200 Subject: [PATCH 284/454] chore(bip-0046): less ambiguous message prefix style by @AdamISZ --- bip-0046.mediawiki | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/bip-0046.mediawiki b/bip-0046.mediawiki index 70bc703e0e..a6bc180991 100644 --- a/bip-0046.mediawiki +++ b/bip-0046.mediawiki @@ -99,7 +99,7 @@ To derive the address from the above calculated public key and timelock, we crea In order to support signing of certificates, implementors should support signing ASCII messages. -A certificate message can be created by another application external to this standard. It is then prepended with the string `\x18Bitcoin Signed Message:\n` and a byte denoting the length of the certificate message. The whole thing is then signed with the private key of the derived_key. This part is identical to the "Sign Message" function which many wallets already implement. +A certificate message can be created by another application external to this standard. It is then prepended with the string `0x18 || "Bitcoin Signed Message:\n"` and a byte denoting the length of the certificate message. The whole thing is then signed with the private key of the derived_key. This part is identical to the "Sign Message" function which many wallets already implement. Almost all wallets implementing this standard can use their already-existing "Sign Message" function to sign the certificate message. As the certificate message itself is always an ASCII string, the wallet may not need to specially implement this section at all but just rely on users copypasting their certificate message into the already-existing "Sign Message" user interface. This works as long as the wallet knows how to use the private key of the timelocked address for signing messages. From 8f0962a1ba1168a81b185593e82dfb4c1c9bbcb8 Mon Sep 17 00:00:00 2001 From: theborakompanioni Date: Fri, 7 Jun 2024 12:05:20 +0200 Subject: [PATCH 285/454] chore(bip-0046): remove superfluous newline --- bip-0046.mediawiki | 1 - 1 file changed, 1 deletion(-) diff --git a/bip-0046.mediawiki b/bip-0046.mediawiki index a6bc180991..5e5ab4370c 100644 --- a/bip-0046.mediawiki +++ b/bip-0046.mediawiki @@ -172,4 +172,3 @@ Code generating these test vectors can be found here: https://github.com/chris-b * [[bip-0049.mediawiki|BIP49 - Derivation scheme for P2WPKH-nested-in-P2SH based accounts]] * [[bip-0084.mediawiki|BIP84 - Derivation scheme for P2WPKH based accounts]] * [[bip-0086.mediawiki|BIP86 - Key Derivation for Single Key P2TR Outputs]] - From b33c948f00af1e93ca3be196ed7a55b58b53ed88 Mon Sep 17 00:00:00 2001 From: Stacie Date: Sat, 8 Jun 2024 23:00:17 -0400 Subject: [PATCH 286/454] BIP79: remove repeat word --- bip-0079.mediawiki | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/bip-0079.mediawiki b/bip-0079.mediawiki index 797c8f145a..0c31c1c82a 100644 --- a/bip-0079.mediawiki +++ b/bip-0079.mediawiki @@ -84,7 +84,7 @@ After adding inputs to the transaction, the receiver generally will want to adju === Returning the partial transaction === -The receiver must sign all contributed inputs in the partial transaction. The partial transaction should also remove all witnesses from the the original template transaction as they are no longer valid, and need to be recalculated by the sender. The receiver returns the partial transaction as a binary-encoded HTTP response with a status code of 200. To ensure compatibility with web-wallets and browser-based-tools, all responses (including errors) must contain the HTTP header "Access-Control-Allow-Origin: *" +The receiver must sign all contributed inputs in the partial transaction. The partial transaction should also remove all witnesses from the original template transaction as they are no longer valid, and need to be recalculated by the sender. The receiver returns the partial transaction as a binary-encoded HTTP response with a status code of 200. To ensure compatibility with web-wallets and browser-based-tools, all responses (including errors) must contain the HTTP header "Access-Control-Allow-Origin: *" === Sender Validation === From 44984acde9786ce5722cf2dc298e7ef407a4d445 Mon Sep 17 00:00:00 2001 From: Stacie Date: Sun, 9 Jun 2024 21:56:51 -0400 Subject: [PATCH 287/454] BIP340: remove repeat words --- bip-0340/test-vectors.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/bip-0340/test-vectors.py b/bip-0340/test-vectors.py index 9a5a1401db..5a131c46e4 100644 --- a/bip-0340/test-vectors.py +++ b/bip-0340/test-vectors.py @@ -24,14 +24,14 @@ def vector0(): assert(y(P) % 2 == 0) # For historical reasons (pubkey tiebreaker was squareness and not evenness) - # we should have at least one test vector where the the point reconstructed + # we should have at least one test vector where the point reconstructed # from the public key has a square and one where it has a non-square Y # coordinate. In this one Y is non-square. pubkey_point = lift_x(pubkey) assert(not has_square_y(pubkey_point)) # For historical reasons (R tiebreaker was squareness and not evenness) - # we should have at least one test vector where the the point reconstructed + # we should have at least one test vector where the point reconstructed # from the R.x coordinate has a square and one where it has a non-square Y # coordinate. In this one Y is non-square. R = lift_x(sig[0:32]) From 14af3d6fe996547f8d053db3d1072dfd90d074c4 Mon Sep 17 00:00:00 2001 From: /dev/fd0 <147166694+1440000bytes@users.noreply.github.com> Date: Mon, 10 Jun 2024 20:05:49 +0000 Subject: [PATCH 288/454] fix bip number --- bip-0301.mediawiki | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/bip-0301.mediawiki b/bip-0301.mediawiki index e1522f8637..966db25a4b 100644 --- a/bip-0301.mediawiki +++ b/bip-0301.mediawiki @@ -78,7 +78,7 @@ Bip301 makes this specialization-of-labor trustless on layer1. If Mary takes Sim ==Specification== -Bip300 consists of two messages: "BMM Accept" and "BMM Request". These govern something called "h*". +Bip301 consists of two messages: "BMM Accept" and "BMM Request". These govern something called "h*". So we will discuss: From 85cda4e225b4d5fd7aff403f69d827f23f6afbbc Mon Sep 17 00:00:00 2001 From: Glen Cooper Date: Tue, 11 Jun 2024 18:23:48 +0000 Subject: [PATCH 289/454] =?UTF-8?q?BIP=E2=80=AF15:=20Remove=20broken=20hyp?= =?UTF-8?q?erlink=20to=20Vanitygen=20(#1618)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- bip-0015.mediawiki | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/bip-0015.mediawiki b/bip-0015.mediawiki index 1e9a9bc466..635fb7fabe 100644 --- a/bip-0015.mediawiki +++ b/bip-0015.mediawiki @@ -36,7 +36,7 @@ Their FirstBits alias becomes: It is enough information to be given the FirstBits alias ''1brmlab''. When someone wishes to make a purchase, without FirstBits, they either have to type out their address laboriously by hand, scan their QR code (which requires a mobile handset that this author does not own) or find their address on the internet to copy and paste into the client to send bitcoins. FirstBits alleviates this impracticality by providing an easy method to make payments. -Together with [[vanitygen|Vanitygen (vanity generator)]], it becomes possible to create memorable unique named addresses. Addresses that are meaningful, rather than an odd assemblage of letters and numbers but add context to the destination. +Together with Vanitygen (vanity generator), it becomes possible to create memorable unique named addresses. Addresses that are meaningful, rather than an odd assemblage of letters and numbers but add context to the destination. However FirstBits has its own problems. One is that the possible aliases one is able to generate is limited by the available computing power available. It may not be feasible to generate a complete or precise alias that is wanted- only approximates may be possible. It is also computationally resource intensive which means a large expenditure of power for generating unique aliases in the future, and may not scale up to the level of individuals at home or participants with hand-held devices in an environment of ubiquitous computing. From 6a7af366a507192d6801b0fe5f507ecf2c34b242 Mon Sep 17 00:00:00 2001 From: Tim Ruffing Date: Thu, 13 Jun 2024 20:54:57 +0200 Subject: [PATCH 290/454] bip-0327: Remove obsolete paragraph --- bip-0327.mediawiki | 3 --- 1 file changed, 3 deletions(-) diff --git a/bip-0327.mediawiki b/bip-0327.mediawiki index 181926bf87..b659629bda 100644 --- a/bip-0327.mediawiki +++ b/bip-0327.mediawiki @@ -190,9 +190,6 @@ The aggregate public key can be ''tweaked'', which modifies the key as defined i In order to apply a tweak, the KeyAgg Context output by ''KeyAgg'' is provided to the ''ApplyTweak'' algorithm with the ''is_xonly_t'' argument set to false for plain tweaking and true for X-only tweaking. The resulting KeyAgg Context can be used to apply another tweak with ''ApplyTweak'' or obtain the aggregate public key with ''GetXonlyPubkey'' or ''GetPlainPubkey''. -In addition to individual public keys, the ''KeyAgg'' algorithm accepts tweaks, which modify the aggregate public key as defined in the [[#tweaking-definition|Tweaking Definition]] subsection. -For example, if ''KeyAgg'' is run with ''v = 2'', ''is_xonly_t1 = false'', ''is_xonly_t2 = true'', then the aggregate key is first plain tweaked with ''tweak1'' and then X-only tweaked with ''tweak2''. - The purpose of supporting tweaking is to ensure compatibility with existing uses of tweaking, i.e., that the result of signing is a valid signature for the tweaked public key. The MuSig2 algorithms take arbitrary tweaks as input but accepting arbitrary tweaks may negatively affect the security of the scheme.It is an open question whether allowing arbitrary tweaks from an adversary affects the unforgeability of MuSig2. Instead, signers should obtain the tweaks according to other specifications. From 48ebcb2191e9738efcff06b425cec41985c43f5f Mon Sep 17 00:00:00 2001 From: Ava Chow Date: Mon, 15 Jan 2024 14:54:19 -0500 Subject: [PATCH 291/454] BIP 328: add MuSig2 derivation BIP --- README.mediawiki | 7 ++++ bip-0328.mediawiki | 80 ++++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 87 insertions(+) create mode 100644 bip-0328.mediawiki diff --git a/README.mediawiki b/README.mediawiki index 455d522571..1e7840533f 100644 --- a/README.mediawiki +++ b/README.mediawiki @@ -1016,6 +1016,13 @@ Those proposing changes should consider that ultimately consent may rest with th | Informational | Draft |- +| [[bip-0328.mediawiki|328]] +| Applications +| Derivation Scheme for MuSig2 Aggregate Keys +| Ava Chow +| Informational +| Draft +|- | [[bip-0329.mediawiki|329]] | Applications | Wallet Labels Export Format diff --git a/bip-0328.mediawiki b/bip-0328.mediawiki new file mode 100644 index 0000000000..3c07daba9b --- /dev/null +++ b/bip-0328.mediawiki @@ -0,0 +1,80 @@ +
+  BIP: 328
+  Layer: Applications
+  Title: Derivation Scheme for MuSig2 Aggregate Keys
+  Author: Ava Chow 
+  Comments-Summary: No comments yet.
+  Comments-URI: https://github.com/bitcoin/bips/wiki/Comments:BIP-0328
+  Status: Draft
+  Type: Informational
+  Created: 2024-01-15
+  License: CC0-1.0
+
+ +==Abstract== + +This document specifies how BIP 32 extended public keys can be constructed from a BIP 327 MuSig2 +aggregate public key and how such keys should be used for key derivation. + +==Copyright== + +This BIP is licensed under the Creative Commons CC0 1.0 Universal license. + +==Motivation== + +Multiple signers can create a single aggregate public key with MuSig2 that is indistinguishable +from a random public key. The cosigners need a method for generating additional aggregate pubkeys +to follow the best practice of using a new address for every payment. + +The obvious method is for the cosigners to generate multiple public keys and produce a +new aggregate pubkey every time one is needed. This is similar to how multisig using Bitcoin script +works where all of the cosigners share their extended public keys and do derivation to produce +the multisig script. The same could be done with MuSig2 and instead of producing a multisig script, +the result would be a MuSig2 aggregate pubkey. + +However, it is much simpler to be able to derive from a single extended public key instead of having +to derive from many extended public keys and aggregate them. As MuSig2 produces a normal looking +public key, the aggregate public can be used in this way. This reduces the storage and computation +requirements for generating new aggregate pubkeys. + +==Specification== + +A synthetic xpub can be created from a BIP 327 MuSig2 plain aggregate public key by setting +the depth to 0, the child number to 0, and attaching a chaincode with the byte string +868087ca02a6f974c4598924c36b57762d32cb45717167e300622c7167e38965'''Where does this +constant chaincode come from?''' It is the SHA256 of the text MuSig2MuSig2MuSig2. +This fixed chaincode should be used by all such synthetic xpubs following this specification. +Unhardened child public keys can be derived from the synthetic xpub as with any other xpub. Since +the aggregate public key is all that is necessary to produce the synthetic xpub, any aggregate +public key that will be used in this way shares the same privacy concerns as typical xpubs. + +Furthermore, as there is no aggregate private key, only unhardened derivation from the aggregate +public key is possible. + +When signing, all signers must compute the tweaks used in the BIP 32 derivation for the child key +being signed for. The IL value computed in ''CKDpub'' is the tweak used at each +derivation step. These are provided in the session context, each with a tweak mode of plain +(''is_xonly_t = false''). When the ''Sign'' algorithm is used, the tweaks will be applied to the +partial signatures. + +==Test Vectors== + +TBD + +==Backwards Compatibility== + +Once a synthetic xpub is created, it is fully backwards compatible with BIP 32 - only unhardened +derivation can be done, and the signers will be able to produce a signature for any derived children. + +==Rationale== + + + +==Reference Implementation== + +TBD + +==Acknowledgements== + +Thanks to Pieter Wuille, Andrew Poelstra, Sanket Kanjalkar, Salvatore Ingala, and all others who +participated in discussions on this topic. From 6b9138c1a1511719eb0477d2375c81a598ba07a0 Mon Sep 17 00:00:00 2001 From: Ava Chow Date: Mon, 15 Jan 2024 14:07:44 -0500 Subject: [PATCH 292/454] BIP 390: Add MuSig2 descriptor BIP --- README.mediawiki | 7 +++ bip-0380.mediawiki | 3 ++ bip-0390.mediawiki | 117 +++++++++++++++++++++++++++++++++++++++++++++ 3 files changed, 127 insertions(+) create mode 100644 bip-0390.mediawiki diff --git a/README.mediawiki b/README.mediawiki index 1e7840533f..3d4f25955d 100644 --- a/README.mediawiki +++ b/README.mediawiki @@ -1219,6 +1219,13 @@ Those proposing changes should consider that ultimately consent may rest with th | Informational | Draft |- +| [[bip-0390.mediawiki|390]] +| Applications +| musig() Descriptor Key Expression +| Ava Chow +| Informational +| Draft +|- | [[bip-0431.mediawiki|431]] | Applications | Topology Restrictions for Pinning diff --git a/bip-0380.mediawiki b/bip-0380.mediawiki index 27b7908b9b..823a92cf3d 100644 --- a/bip-0380.mediawiki +++ b/bip-0380.mediawiki @@ -332,4 +332,7 @@ This Table lists all available Script expressions and the BIPs specifying them. |- | tr(KEY), tr(KEY, TREE) | [[bip-0386.mediawiki|386]] +|- +| musig(KEY, KEY, ..., KEY) +| [[bip-0390.mediawiki|390]] |} diff --git a/bip-0390.mediawiki b/bip-0390.mediawiki new file mode 100644 index 0000000000..05f57347b0 --- /dev/null +++ b/bip-0390.mediawiki @@ -0,0 +1,117 @@ +
+  BIP: 390
+  Layer: Applications
+  Title: musig() Descriptor Key Expression
+  Author: Ava Chow 
+  Comments-Summary: No comments yet.
+  Comments-URI: https://github.com/bitcoin/bips/wiki/Comments:BIP-0390
+  Status: Draft
+  Type: Informational
+  Created: 2024-01-15
+  License: CC0-1.0
+
+ +==Abstract== + +This document specifies a musig() key expression for output script descriptors. +musig() expressions take multiple keys and produce an aggregate public key using BIP 327. + +==Copyright== + +This BIP is licensed under the Creative Commons CC0 1.0 Universal license. + +==Motivation== + +BIP 327 introduces the MuSig2 Multi-Signature scheme. It is useful to have a way for keys to be used +in a MuSig2 aggregate key to be expressed in descriptors so that wallets can more easily use MuSig2. + +==Specification== + +A new key expression is defined: musig(). + +===musig(KEY, KEY, ..., KEY)=== + +The musig(KEY, KEY, ..., KEY) expression can only be used inside of a tr() +expression as a key expression. It additionally cannot be nested within another musig() +expression. Repeated participant public keys are not allowed. The aggregate public key is produced +by using the KeyAgg algorithm on all KEYs specified in the expression after performing all +specified derivation. As with script expressions, KEY can contain child derivation specified by +/*. A new aggregate public key will be computed for each child index. Keys must be sorted +with the KeySort algorithm after all derivation and prior to aggregation'''Why must +the keys be sorted prior to aggregation?''' Although the descriptor's written form sets an order +for the keys that could be used for aggregation, the order should not matter as MuSig2 philosophically +operates over a set of keys, with the order merely being an implementation detail in aggregation +itself. Requiring sorting of keys prior to aggregation enforces this philosophy as keys can be +written in the descriptor in any order with the end result still being the same. Furthermore, this +aids with recovery where the descriptor was not backed up as users will not need to also have +backed up, or guess, the correct order of keys.. + +===musig(KEY, KEY, ..., KEY)/NUM/.../*=== + +musig(KEY, KEY, ..., KEY)/NUM/.../* expressions are also allowed, with the same usage +restrictions as in the previous section. The aggregate public key +is first computed as described above, with the keys also being sorted after all derivation and prior +to aggreation. Then further BIP 32 derivation will be performed on the aggregate public key as described in +[[bip-0328.mediawiki|BIP 328]]. As there is no aggregate private key, +only unhardened derivation from the aggregate public key is allowed, and thus the derivation steps +following the musig() expression cannot contain +/NUMh or /NUM' derivation steps nor /*h, or /*' child derivation. +For these musig() expressions, the KEY expressions contained within must be xpubs or derived from +xpubs, and cannot contain child derivation as specified by a /*, /*', or /*h. + +==Test Vectors== + +Valid descriptors containing followed by the scripts they produce. Descriptors involving derived child keys +will have the 0th, 1st, and 2nd scripts listed. + +* rawtr(musig(KwDiBf89QgGbjEhKnhXJuH7LrciVrZi3qYjgd9M7rFU74sHUHy8S,03dff1d77f2a671c5f36183726db2341be58feae1da2deced843240f7b502ba659,023590a94e768f8e1815c2f24b4d80a8e3149316c3518ce7b7ad338368d038ca66)) +** 5120789d937bade6673538f3e28d8368dda4d0512f94da44cf477a505716d26a1575 +* tr(musig(02f9308a019258c31049344f85f89d5229b531c845836f99b08601f113bce036f9,03dff1d77f2a671c5f36183726db2341be58feae1da2deced843240f7b502ba659,023590a94e768f8e1815c2f24b4d80a8e3149316c3518ce7b7ad338368d038ca66)) +** 512079e6c3e628c9bfbce91de6b7fb28e2aec7713d377cf260ab599dcbc40e542312 +* rawtr(musig(xpub6ERApfZwUNrhLCkDtcHTcxd75RbzS1ed54G1LkBUHQVHQKqhMkhgbmJbZRkrgZw4koxb5JaHWkY4ALHY2grBGRjaDMzQLcgJvLJuZZvRcEL,xpub68NZiKmJWnxxS6aaHmn81bvJeTESw724CRDs6HbuccFQN9Ku14VQrADWgqbhhTHBaohPX4CjNLf9fq9MYo6oDaPPLPxSb7gwQN3ih19Zm4Y)/0/*) +** 51209508c08832f3bb9d5e8baf8cb5cfa3669902e2f2da19acea63ff47b93faa9bfc +** 51205ca1102663025a83dd9b5dbc214762c5a6309af00d48167d2d6483808525a298 +** 51207dbed1b89c338df6a1ae137f133a19cae6e03d481196ee6f1a5c7d1aeb56b166 +* tr(musig(xpub6ERApfZwUNrhLCkDtcHTcxd75RbzS1ed54G1LkBUHQVHQKqhMkhgbmJbZRkrgZw4koxb5JaHWkY4ALHY2grBGRjaDMzQLcgJvLJuZZvRcEL,xpub68NZiKmJWnxxS6aaHmn81bvJeTESw724CRDs6HbuccFQN9Ku14VQrADWgqbhhTHBaohPX4CjNLf9fq9MYo6oDaPPLPxSb7gwQN3ih19Zm4Y)/0/*,pk(f9308a019258c31049344f85f89d5229b531c845836f99b08601f113bce036f9)) +** 51201d377b637b5c73f670f5c8a96a2c0bb0d1a682a1fca6aba91fe673501a189782 +** 51208950c83b117a6c208d5205ffefcf75b187b32512eb7f0d8577db8d9102833036 +** 5120a49a477c61df73691b77fcd563a80a15ea67bb9c75470310ce5c0f25918db60d +* tr(f9308a019258c31049344f85f89d5229b531c845836f99b08601f113bce036f9,pk(musig(xpub6ERApfZwUNrhLCkDtcHTcxd75RbzS1ed54G1LkBUHQVHQKqhMkhgbmJbZRkrgZw4koxb5JaHWkY4ALHY2grBGRjaDMzQLcgJvLJuZZvRcEL,xpub68NZiKmJWnxxS6aaHmn81bvJeTESw724CRDs6HbuccFQN9Ku14VQrADWgqbhhTHBaohPX4CjNLf9fq9MYo6oDaPPLPxSb7gwQN3ih19Zm4Y)/0/*)) +** 512068983d461174afc90c26f3b2821d8a9ced9534586a756763b68371a404635cc8 +** 5120368e2d864115181bdc8bb5dc8684be8d0760d5c33315570d71a21afce4afd43e +** 512097a1e6270b33ad85744677418bae5f59ea9136027223bc6e282c47c167b471d5 + +Invalid descriptors + +* musig() is not allowed in pk(): pk(musig(02f9308a019258c31049344f85f89d5229b531c845836f99b08601f113bce036f9,03dff1d77f2a671c5f36183726db2341be58feae1da2deced843240f7b502ba659,023590a94e768f8e1815c2f24b4d80a8e3149316c3518ce7b7ad338368d038ca66)) +* musig() is not allowed in pkh(): pkh(musig(02f9308a019258c31049344f85f89d5229b531c845836f99b08601f113bce036f9,03dff1d77f2a671c5f36183726db2341be58feae1da2deced843240f7b502ba659,023590a94e768f8e1815c2f24b4d80a8e3149316c3518ce7b7ad338368d038ca66)) +* musig() is not allowed in wpkh(): wpkh(musig(02f9308a019258c31049344f85f89d5229b531c845836f99b08601f113bce036f9,03dff1d77f2a671c5f36183726db2341be58feae1da2deced843240f7b502ba659,023590a94e768f8e1815c2f24b4d80a8e3149316c3518ce7b7ad338368d038ca66)) +* musig() is not allowed in combo(): combo(musig(02f9308a019258c31049344f85f89d5229b531c845836f99b08601f113bce036f9,03dff1d77f2a671c5f36183726db2341be58feae1da2deced843240f7b502ba659,023590a94e768f8e1815c2f24b4d80a8e3149316c3518ce7b7ad338368d038ca66)) +* musig() is not allowed in sh(wpkh()): sh(wpkh(musig(02f9308a019258c31049344f85f89d5229b531c845836f99b08601f113bce036f9,03dff1d77f2a671c5f36183726db2341be58feae1da2deced843240f7b502ba659,023590a94e768f8e1815c2f24b4d80a8e3149316c3518ce7b7ad338368d038ca66))) +* musig() is not allowed in sh(wsh()): sh(wsh(pk(musig(02f9308a019258c31049344f85f89d5229b531c845836f99b08601f113bce036f9,03dff1d77f2a671c5f36183726db2341be58feae1da2deced843240f7b502ba659,023590a94e768f8e1815c2f24b4d80a8e3149316c3518ce7b7ad338368d038ca66)))) +* musig() is not allowed in wsh(): wsh(musig(02f9308a019258c31049344f85f89d5229b531c845836f99b08601f113bce036f9,03dff1d77f2a671c5f36183726db2341be58feae1da2deced843240f7b502ba659,023590a94e768f8e1815c2f24b4d80a8e3149316c3518ce7b7ad338368d038ca66)) +* musig() is not allowed in sh(): sh(musig(02f9308a019258c31049344f85f89d5229b531c845836f99b08601f113bce036f9,03dff1d77f2a671c5f36183726db2341be58feae1da2deced843240f7b502ba659,023590a94e768f8e1815c2f24b4d80a8e3149316c3518ce7b7ad338368d038ca66)) +* Ranged musig() requires all participants to be xpubs: tr(musig(02f9308a019258c31049344f85f89d5229b531c845836f99b08601f113bce036f9,03dff1d77f2a671c5f36183726db2341be58feae1da2deced843240f7b502ba659,023590a94e768f8e1815c2f24b4d80a8e3149316c3518ce7b7ad338368d038ca66)/0/0) +* Cannot have ranged participants if musig() is also ranged: tr(musig(xpub6ERApfZwUNrhLCkDtcHTcxd75RbzS1ed54G1LkBUHQVHQKqhMkhgbmJbZRkrgZw4koxb5JaHWkY4ALHY2grBGRjaDMzQLcgJvLJuZZvRcEL/*,xpub68NZiKmJWnxxS6aaHmn81bvJeTESw724CRDs6HbuccFQN9Ku14VQrADWgqbhhTHBaohPX4CjNLf9fq9MYo6oDaPPLPxSb7gwQN3ih19Zm4Y)/0/*) +* musig() cannot have hardened derivation steps: tr(musig(xpub6ERApfZwUNrhLCkDtcHTcxd75RbzS1ed54G1LkBUHQVHQKqhMkhgbmJbZRkrgZw4koxb5JaHWkY4ALHY2grBGRjaDMzQLcgJvLJuZZvRcEL,xpub68NZiKmJWnxxS6aaHmn81bvJeTESw724CRDs6HbuccFQN9Ku14VQrADWgqbhhTHBaohPX4CjNLf9fq9MYo6oDaPPLPxSb7gwQN3ih19Zm4Y)/0h/*) +* musig() cannot have hardened child derivation: tr(musig(xpub6ERApfZwUNrhLCkDtcHTcxd75RbzS1ed54G1LkBUHQVHQKqhMkhgbmJbZRkrgZw4koxb5JaHWkY4ALHY2grBGRjaDMzQLcgJvLJuZZvRcEL,xpub68NZiKmJWnxxS6aaHmn81bvJeTESw724CRDs6HbuccFQN9Ku14VQrADWgqbhhTHBaohPX4CjNLf9fq9MYo6oDaPPLPxSb7gwQN3ih19Zm4Y)/0/*h) + +==Backwards Compatibility== + +musig() expressions use the format and general operation specified in +[[bip-0380.mediawiki|BIP 380]]. As these are a set of wholly new expressions, they are not compatible +with any implementation. However the keys are produced using a standard process so existing software +are likely to be familiar with them. + +==Rationale== + + + +==Reference Implementation== + +TBD + +==Acknowledgements== + +Thanks to Pieter Wuille, Andrew Poelstra, Sanket Kanjalkar, Salvatore Ingala, and all others who +participated in discussions on this topic. From 806b8b886fef460a7a812c219f30d5b09d74d2d0 Mon Sep 17 00:00:00 2001 From: Ava Chow Date: Mon, 15 Jan 2024 14:07:56 -0500 Subject: [PATCH 293/454] BIP 373: add MuSig2 PSBT Fields BIP --- README.mediawiki | 7 ++ bip-0174.mediawiki | 60 +++++++++++++ bip-0373.mediawiki | 216 +++++++++++++++++++++++++++++++++++++++++++++ 3 files changed, 283 insertions(+) create mode 100644 bip-0373.mediawiki diff --git a/README.mediawiki b/README.mediawiki index 3d4f25955d..91f7c4ce7a 100644 --- a/README.mediawiki +++ b/README.mediawiki @@ -1149,6 +1149,13 @@ Those proposing changes should consider that ultimately consent may rest with th | Standard | Draft |- +| [[bip-0373.mediawiki|373]] +| Applications +| MuSig2 PSBT Fields +| Ava Chow +| Standard +| Draft +|- | [[bip-0380.mediawiki|380]] | Applications | Output Script Descriptors General Operation diff --git a/bip-0174.mediawiki b/bip-0174.mediawiki index 95a5573b45..94a52f2d0f 100644 --- a/bip-0174.mediawiki +++ b/bip-0174.mediawiki @@ -483,6 +483,52 @@ The currently defined per-input types are defined as follows: | 0, 2 | [[bip-0371.mediawiki|371]] |- +| MuSig2 Participant Public Keys +| PSBT_IN_MUSIG2_PARTICIPANT_PUBKEYS = 0x1a +| <33 byte plain aggregate pubkey> +| The MuSig2 aggregate plain public key from the KeyAgg algorithm. This key may or may not +be in the script directly (as x-only). It may instead be a parent public key from which the public keys in the +script were derived. +| <33 byte compressed pubkey>* +| A list of the compressed public keys of the participants in the MuSig2 aggregate key in the order +required for aggregation. If sorting was done, then the keys must be in the sorted order. +| +| +| 0, 2 +| [[bip-0373.mediawiki|373]] +|- +| MuSig2 Public Nonce +| PSBT_IN_MUSIG2_PUB_NONCE = 0x1b +| <33 byte compressed pubkey> <33 byte plain pubkey> <32 byte hash or omitted> +| The compressed public key of the participant providing this nonce, followed by the plain public +key the participant is providing the nonce for, followed by the BIP 341 tapleaf hash of +the Taproot leaf script that will be signed. If the aggregate key is the taproot internal key or the +taproot output key, then the tapleaf hash must be omitted. The plain public key must be +the key found in the script and not the aggregate public key that it was derived from, if it was +derived from an aggregate key. +| <66 byte public nonce> +| The public nonce produced by the NonceGen algorithm. +| +| +| 0, 2 +| [[bip-0373.mediawiki|373]] +|- +| MuSig2 Participant Partial Signature +| PSBT_IN_MUSIG2_PARTIAL_SIG = 0x1c +| <33 byte compressed pubkey> <33 byte plain pubkey> <32 byte hash or omitted> +| The compressed public key of the participant providing this partial signature, followed by the +plain public key the participant is providing the signature for, followed by the BIP 341 tapleaf hash +of the Taproot leaf script that will be signed. If the aggregate key is the taproot internal key or +the taproot output key, then the tapleaf hash must be omitted. Note that the plain public key must +be the key found in the script and not the aggregate public key that it was derived from, if it was +derived from an aggregate key. +| <32 byte partial signature> +| The partial signature produced by the Sign algorithm. +| +| +| 0, 2 +| [[bip-0373.mediawiki|373]] +|- | Proprietary Use Type | PSBT_IN_PROPRIETARY = 0xFC | @@ -599,6 +645,20 @@ determine which outputs are change outputs and verify that the change is returni | 0, 2 | [[bip-0371.mediawiki|371]] |- +| MuSig2 Participant Public Keys +| PSBT_OUT_MUSIG2_PARTICIPANT_PUBKEYS = 0x08 +| <33 byte plain aggregate pubkey> +| The MuSig2 aggregate plain public key from the KeyAgg algorithm. This key may or may not +be in the script directly. It may instead be a parent public key from which the public keys in the +script were derived. +| <33 byte compressed pubkey>* +| A list of the compressed public keys of the participants in the MuSig2 aggregate key in the order +required for aggregation. If sorting was done, then the keys must be in the sorted order. +| +| +| 0, 2 +| [[bip-0373.mediawiki|373]] +|- | Proprietary Use Type | PSBT_OUT_PROPRIETARY = 0xFC | diff --git a/bip-0373.mediawiki b/bip-0373.mediawiki new file mode 100644 index 0000000000..d9dec45615 --- /dev/null +++ b/bip-0373.mediawiki @@ -0,0 +1,216 @@ +
+  BIP: 373
+  Layer: Applications
+  Title: MuSig2 PSBT Fields
+  Author: Ava Chow 
+  Comments-Summary: No comments yet.
+  Comments-URI: https://github.com/bitcoin/bips/wiki/Comments:BIP-0373
+  Status: Draft
+  Type: Standards Track
+  Created: 2024-01-15
+  License: CC0-1.0
+
+ +==Introduction== + +===Abstract=== + +This document proposes additional fields for BIP 174 PSBTv0 and BIP 370 PSBTv2 that allow for BIP +327 MuSig2 Multi-Signature data to be included in a PSBT of any version. These will be fields for +the participants' keys, the public nonces, and the partial signatures produced with MuSig2. + +===Copyright=== + +This BIP is licensed under the Creative Commons CC0 1.0 Universal license. + +===Motivation=== + +BIP 327 specifies a way to create BIP 340 compatible public keys and signatures using the MuSig2 +Multi-Signature scheme. The existing PSBT fields are unable to support MuSig2 as it introduces new +concepts and additional rounds of communication. Therefore new fields must be defined to allow PSBTs +to carry the information necessary to produce a valid signature with MuSig2. + +==Specification== + +The new per-input types are defined as follows: + +{| +! Name +! +! +! +! Versions Requiring Inclusion +! Versions Requiring Exclusion +! Versions Allowing Inclusion +|- +| rowspan="2"|MuSig2 Participant Public Keys +| rowspan="2"|PSBT_IN_MUSIG2_PARTICIPANT_PUBKEYS = 0x1a +| <33 byte plain aggregate pubkey> +| <33 byte compressed pubkey>* +| rowspan="2"| +| rowspan="2"| +| rowspan="2"| 0, 2 +|- +| The MuSig2 aggregate plain public key'''Why the plain aggregate public key instead of x-only?''' +BIP 32 requires public keys to include their evenness byte. Aggregate public keys are expected to be +derived from, following [[bip-0328.mediawiki|BIP 328]], and therefore will +need to include the evenness. Furthermore, PSBT_IN_TAP_BIP32_DERIVATION fields include fingerprints +to identify master keys, and these fingerprints require full compressed public keys. By including +the aggregate key as a full public key, signers that are unaware of the MuSig2 outside of the PSBT +will still be able to identify which keys are derived from the aggregate key by computing and then +comparing the fingerprints. This is necessary for the signer to apply the correct tweaks to their +partial signature. from the KeyAgg algorithm. This key may or may not +be in the script directly (as x-only). It may instead be a parent public key from which the public keys in the +script were derived. +| A list of the compressed public keys of the participants in the MuSig2 aggregate key in the order +required for aggregation. If sorting was done, then the keys must be in the sorted order. +|- +| rowspan="2"|MuSig2 Public Nonce +| rowspan="2"|PSBT_IN_MUSIG2_PUB_NONCE = 0x1b +| <33 byte compressed pubkey> <33 byte plain pubkey> <32 byte hash or omitted> +| <66 byte public nonce> +| rowspan="2"| +| rowspan="2"| +| rowspan="2"| 0, 2 +|- +| The compressed public key of the participant providing this nonce, followed by the plain public +key the participant is providing the nonce for, followed by the BIP 341 tapleaf hash of +the Taproot leaf script that will be signed. If the aggregate key is the taproot internal key or the +taproot output key, then the tapleaf hash must be omitted. The plain public key must be +the key found in the script and not the aggregate public key that it was derived from, if it was +derived from an aggregate key. +| The public nonce produced by the NonceGen algorithm. +|- +| rowspan="2"|MuSig2 Participant Partial Signature +| rowspan="2"|PSBT_IN_MUSIG2_PARTIAL_SIG = 0x1c +| <33 byte compressed pubkey> <33 byte plain pubkey> <32 byte hash or omitted> +| <32 byte partial signature> +| rowspan="2"| +| rowspan="2"| +| rowspan="2"| 0, 2 +|- +| The compressed public key of the participant providing this partial signature, followed by the +plain public key the participant is providing the signature for, followed by the BIP 341 tapleaf hash +of the Taproot leaf script that will be signed. If the aggregate key is the taproot internal key or +the taproot output key, then the tapleaf hash must be omitted. Note that the plain public key must +be the key found in the script and not the aggregate public key that it was derived from, if it was +derived from an aggregate key. +| The partial signature produced by the Sign algorithm. +|} + +The new per-output types are defined as follows: + +{| +! Name +! +! +! +! Versions Requiring Inclusion +! Versions Requiring Exclusion +! Versions Allowing Inclusion +|- +| rowspan="2"|MuSig2 Participant Public Keys +| rowspan="2"|PSBT_OUT_MUSIG2_PARTICIPANT_PUBKEYS = 0x08 +| <33 byte compressed pubkey> +| <33 byte compressed pubkey>* +| rowspan="2"| +| rowspan="2"| +| rowspan="2"|0, 2 +|- +| The MuSig2 aggregate plain public key from the KeyAgg algorithm. This key may or may not +be in the script directly. It may instead be a parent public key from which the public keys in the +script were derived. +| A list of the compressed public keys of the participants in the MuSig2 aggregate key in the order +required for aggregation. If sorting was done, then the keys must be in the sorted order. +|} + +==Roles== + +===Updater=== + +When an updater observes a Taproot output which involves a MuSig2 aggregate public key that it is +aware if, it can add a PSBT_IN_MUSIG2_PARTICIPANT_PUBKEYS field containing the public keys +of the participants. This aggregate public key may be directly in the script, the Taproot internal +key, the Taproot output key, or a public key from which the key in the script was derived from. + +An aggregate public key that appears directly in the script or internal key may be from the result +of deriving child pubkeys from participant xpubs. If the updater has this derivation information, it +should also add PSBT_IN_TAP_BIP32_DERIVATION for each participant public key. + +If the public key found was derived from an aggregate public key, then all MuSig2 PSBT fields for +that public key should contain the aggregate public key rather than the found pubkey itself. The +updater should also add PSBT_IN_TAP_BIP32_DERIVATION that contains the derivation path used +to derive the found pubkey from the aggregate pubkey. +Derivation from the aggregate pubkey can be assumed to follow [[bip-0328.mediawiki|BIP 328]] +if there is no PSBT_IN_GLOBAL_XPUB that specifies the synthetic xpub for the aggregate +public key. + +Updaters should add PSBT_OUT_MUSIG2_PARTICIPANT_PUBKEYS and +PSBT_OUT_TAP_BIP32_DERIVATION similarly to inputs to aid in change detection. + +===Signer=== + +To determine whether a signer is a participant in the MuSig2 aggregate key, the signer should first +look at all PSBT_IN_MUSIG2_PARTICIPANT_PUBKEYS and see if any key which it knows the +private key for appears as a participant in any aggregate pubkey. Signers should also check whether +any of the keys in PSBT_IN_TAP_BIP32_DERIVATION belong to it, and if any of those keys +appear in as a participant in PSBT_IN_MUSIG2_PARTICIPANT_PUBKEYS. + +For each aggregate public key that the signer is a participant of that it wants +to produce a signature for, if the signer does not find an existing +PSBT_IN_MUSIG2_PUB_NONCE field for its key, then it should add one using +the NonceGen algorithm (or one of its variations) to produce a public +nonce that is added in a PSBT_IN_MUSIG2_PUB_NONCE field. However +signers must keep in mind that '''improper nonce usage can compromise private +keys.''' Please see BIP 327 for best practices on nonce generation and usage. + +Once all signers have added their PSBT_IN_MUSIG2_PUB_NONCE fields, each signer will perform +the NonceAgg algorithm followed by the Sign algorithm in order to produce the +partial signature for their key. The result will be added to the PSBT in a +PSBT_IN_MUSIG2_PARTIAL_SIG field. + +Signers must remember to apply any relevant tweaks such as a tweak that is the result of performing +BIP 32 unhardened dervation with the aggregate public key as the parent key. + +If all other signers have provided a PSBT_IN_MUSIG2_PARTIAL_SIG, then the final signer may +perform the PartialSigAgg algorithm and produce a BIP 340 compatible signature that can be +placed into a PSBT_IN_TAP_KEY_SIG or a PSBT_IN_TAP_SCRIPT_SIG. + +===Finalizer=== + +A finalizer may perform the same PartialSigAgg step as the final signer if it has not +already been done. + +Otherwise, the resulting signature is a BIP 340 compatible signature and finalizers should treat it +as such. + +==Backwards Compatibility== + +These are simply new fields added to the existing PSBT format. Because PSBT is designed to be +extensible, old software will ignore the new fields. + +Reusing PSBT_IN_TAP_BIP32_DERIVATION to provide derivation paths for participant public +keys may cause software unaware of MuSig2 to produce a signature for that public key. This is still +safe. If that public key does not directly appear in the leaf script that was signed, then the +signature produced will not be useful and so cannot be replayed. If the public key does directly +appear in the leaf script, then the signer will have validated the script as if it did not involve a +MuSig2 and will have found it acceptable in order for it to have produced a signature. In either +case, producing a signature does not give rise to the possibility of losing funds. + +==Test Vectors== + +TBD + +==Rationale== + + + +==Reference implementation== + +The reference implementation of the PSBT format is available at TBD. + +==Acknowledgements== + +Thanks to Sanket Kanjalkar whose notes on this topic formed the initial basis of this BIP. Also +thanks to Pieter Wuille, Jonas Nick, Tim Ruffing, Marko Bencun, Salvatore Ingala, and all others who +have participated in discussions about these fields. From b7a5f9ce60188e96364d54a85784f04630542aec Mon Sep 17 00:00:00 2001 From: theborakompanioni Date: Wed, 19 Jun 2024 14:06:41 +0200 Subject: [PATCH 294/454] docs(bip-0046): apply minor wording improvement suggestions by @murchandamus --- bip-0046.mediawiki | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/bip-0046.mediawiki b/bip-0046.mediawiki index 5e5ab4370c..84fd2e2d17 100644 --- a/bip-0046.mediawiki +++ b/bip-0046.mediawiki @@ -73,7 +73,7 @@ m / 84' / 0' / 0' / 2 / index A key derived with this derivation path pattern will be referred to as derived_key further in this document. -For index, addresses are numbered from 0 in a sequentially increasing manner, but index does not increase forever like in other similar standards. The index only goes up to 959 inclusive. Only 960 addresses can be derived for a given BIP32 master key. Furthermore there is no concept of a gap limit, instead wallets must always generate all 960 addresses and check all of them if they have a balance and history. +For index, addresses are numbered from 0 in a sequentially increasing manner, but index does not increase forever like in other similar standards. The index only goes up to 959 inclusive. Only 960 addresses can be derived for a given BIP32 master key. Furthermore there is no concept of a gap limit, instead wallets must always generate all 960 addresses and check for all of them if they have a balance and history. === Timelock derivation === @@ -162,7 +162,7 @@ address = bc1qsqex3czzqzrn0n6rjayvhddygj0rz8df4fj2uwk9dkzdqkt9f7zs5c Code generating these test vectors can be found here: https://github.com/chris-belcher/timelocked-addresses-fidelity-bond-bip-testvectors -==Reference== +== Reference == * [[https://gist.github.com/chris-belcher/18ea0e6acdb885a2bfbdee43dcd6b5af/|Design for improving JoinMarket's resistance to sybil attacks using fidelity bonds]] * [[https://github.com/JoinMarket-Org/joinmarket-clientserver/blob/master/docs/fidelity-bonds.md|JoinMarket fidelity bonds doc page]] From fe0f83531e35f76d3582813da4cbb518d9bb1d12 Mon Sep 17 00:00:00 2001 From: Sebastian Falbesoner Date: Wed, 19 Jun 2024 23:56:42 +0200 Subject: [PATCH 295/454] BIP-352: generate `input_hash` after summing up keys (simplification) For both sender and receiver, generating the input hash is currently listed as the first step. This already involves summing up the public keys, even though summing up key material (private keys for sender, public keys of inputs for receiver) is then again listed explicitly in later steps. It seems to be more obvious and less redundant (and also hopefully less confusing for readers) to reorder the instructions to calculate the input_hash _after_ the key aggregation is done to reuse the result. In case of the sender, the private key sum has to be multiplicated with G in order to the get to the corresponding input pubkey sum. This also corresponds to the current BIP352 implementation in the secp256k1 library (https://github.com/bitcoin-core/secp256k1/pull/1519). The reference implementation in Python here is adapted for the sender side, the receiver side has already generated the input_hash after summing up the pubkeys. --- bip-0352.mediawiki | 8 +++----- bip-0352/reference.py | 8 ++++---- 2 files changed, 7 insertions(+), 9 deletions(-) diff --git a/bip-0352.mediawiki b/bip-0352.mediawiki index 4cbf9d7230..f36f359272 100644 --- a/bip-0352.mediawiki +++ b/bip-0352.mediawiki @@ -98,9 +98,8 @@ In our simplified example we have been referring to Alice's transactions as havi Alice performs the tweak with the sum of her input private keys in the following manner: -* Let ''A = A1 + A2 + ... + An'' -* Let ''input_hash = hash(outpointL || A)'', where ''outpointL'' is the smallest outpoint lexicographically'''Why use the lexicographically smallest outpoint for the hash?''' Recall that the purpose of including the input hash is so that the sender and receiver can both come up with a deterministic nonce that ensures that a unique address is generated each time, even when reusing the same scriptPubKey as an input. Choosing the smallest outpoint lexicographically satisifes this requirement, while also ensuring that the generated output is not dependent on the final ordering of inputs in the transaction. Using a single outpoint also works well with memory constrained devices (such as hardware signing devices) as it does not require the device to have the entire transaction in memory in order to generate the silent payment output. * Let ''a = a1 + a2 + ... + an'' +* Let ''input_hash = hash(outpointL || (a·G))'', where ''outpointL'' is the smallest outpoint lexicographically'''Why use the lexicographically smallest outpoint for the hash?''' Recall that the purpose of including the input hash is so that the sender and receiver can both come up with a deterministic nonce that ensures that a unique address is generated each time, even when reusing the same scriptPubKey as an input. Choosing the smallest outpoint lexicographically satisifes this requirement, while also ensuring that the generated output is not dependent on the final ordering of inputs in the transaction. Using a single outpoint also works well with memory constrained devices (such as hardware signing devices) as it does not require the device to have the entire transaction in memory in order to generate the silent payment output. * Let ''P0 = B + hash(input_hash·a·B || 0)·G'' ''' Spend and Scan Key ''' @@ -284,7 +283,6 @@ The receiver obtains the public key from the ''scriptSig''. The receiver MUST pa The sender and receiver MUST calculate an input hash for the transaction in the following manner: -* Let ''A = A1 + A2 + ... + An'', where each ''Ai'' is the public key of an input from the ''[[#inputs-for-shared-secret-derivation|Inputs For Shared Secret Derivation]]'' list * Let ''input_hash = hashBIP0352/Inputs(outpointL || A)'', where ''outpointL'' is the smallest outpoint lexicographically by txid and vout used in the transaction === Sender === @@ -301,10 +299,10 @@ The sending wallet performs coin selection as usual with the following restricti After the inputs have been selected, the sender can create one or more outputs for one or more silent payment addresses in the following manner: -* Generate the ''input_hash'' with the smallest outpoint lexicographically, using the method described above * Collect the private keys for each input from the ''[[#inputs-for-shared-secret-derivation|Inputs For Shared Secret Derivation]]'' list * For each private key ''ai'' corresponding to a [https://github.com/bitcoin/bips/blob/master/bip-0341.mediawiki BIP341] taproot output, check that the private key produces a point with an even Y coordinate and negate the private key if not'''Why do taproot private keys need to be checked?''' Recall from [https://github.com/bitcoin/bips/blob/master/bip-0340.mediawiki BIP340] that each X-only public key has two corresponding private keys, ''d'' and ''n - d''. To maintain parity between sender and receiver, it is necessary to use the private key corresponding to the even Y coordinate when performing the ECDH step since the receiver will assume the even Y coordinate when summing the taproot X-only public keys. * Let ''a = a1 + a2 + ... + an'', where each ''ai'' has been negated if necessary +* Generate the ''input_hash'' with the smallest outpoint lexicographically and ''A = a·G'', using the method described above * Group receiver silent payment addresses by ''Bscan'' (e.g. each group consists of one ''Bscan'' and one or more ''Bm'') * For each group: ** Let ''ecdh_shared_secret = input_hash·a·Bscan'' @@ -335,8 +333,8 @@ A scan and spend key pair using BIP32 derivation are defined (taking inspiration If each of the checks in ''[[#scanning-silent-payment-eligible-transactions|Scanning silent payment eligible transactions]]'' passes, the receiving wallet must: -* Generate the ''input_hash'' with the smallest outpoint lexicographically, using the method described above * Let ''A = A1 + A2 + ... + An'', where each ''Ai'' is the public key of an input from the ''[[#inputs-for-shared-secret-derivation|Inputs For Shared Secret Derivation]]'' list +* Generate the ''input_hash'' with the smallest outpoint lexicographically and ''A'', using the method described above * Let ''ecdh_shared_secret = input_hash·bscan·A'' * Check for outputs: ** Let ''outputs_to_check'' be the taproot output keys from all taproot outputs in the transaction (spent and unspent). diff --git a/bip-0352/reference.py b/bip-0352/reference.py index 9f43695fee..9b35d0400f 100755 --- a/bip-0352/reference.py +++ b/bip-0352/reference.py @@ -117,7 +117,7 @@ def decode_silent_payment_address(address: str, hrp: str = "tsp") -> Tuple[ECPub return B_scan, B_spend -def create_outputs(input_priv_keys: List[Tuple[ECKey, bool]], input_hash: bytes, recipients: List[str], hrp="tsp") -> List[str]: +def create_outputs(input_priv_keys: List[Tuple[ECKey, bool]], outpoints: List[COutPoint], recipients: List[str], hrp="tsp") -> List[str]: G = ECKey().set(1).get_pubkey() negated_keys = [] for key, is_xonly in input_priv_keys: @@ -127,6 +127,7 @@ def create_outputs(input_priv_keys: List[Tuple[ECKey, bool]], input_hash: bytes, negated_keys.append(k) a_sum = sum(negated_keys) + input_hash = get_input_hash(outpoints, a_sum * G) silent_payment_groups: Dict[ECPubKey, List[ECPubKey]] = {} for recipient in recipients: B_scan, B_m = decode_silent_payment_address(recipient, hrp=hrp) @@ -236,9 +237,8 @@ def scanning(b_scan: ECKey, B_spend: ECPubKey, A_sum: ECPubKey, input_hash: byte sending_outputs = [] if (len(input_pub_keys) > 0): - A_sum = reduce(lambda x, y: x + y, input_pub_keys) - input_hash = get_input_hash([vin.outpoint for vin in vins], A_sum) - sending_outputs = create_outputs(input_priv_keys, input_hash, given["recipients"], hrp="sp") + outpoints = [vin.outpoint for vin in vins] + sending_outputs = create_outputs(input_priv_keys, outpoints, given["recipients"], hrp="sp") # Note: order doesn't matter for creating/finding the outputs. However, different orderings of the recipient addresses # will produce different generated outputs if sending to multiple silent payment addresses belonging to the From 0f1eba2a607e84d85c1787b127c14333adf358ee Mon Sep 17 00:00:00 2001 From: theborakompanioni Date: Thu, 20 Jun 2024 17:29:37 +0200 Subject: [PATCH 296/454] docs(bip-0046): add test certificate for the 960th timelocked address --- bip-0046.mediawiki | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/bip-0046.mediawiki b/bip-0046.mediawiki index 84fd2e2d17..1dc124efca 100644 --- a/bip-0046.mediawiki +++ b/bip-0046.mediawiki @@ -122,7 +122,7 @@ redeemscript = 0400e10b5eb1752102a1b09f93073c63f205086440898141c0c3c6d24f scriptPubKey = 0020bdee9515359fc9df912318523b4cd22f1c0b5410232dc943be73f9f4f07e39ad address = bc1qhhhf29f4nlyalyfrrpfrknxj9uwqk4qsyvkujsa7w0ulfur78xkspsqn84 -// Test certificate using first timelocked address +// Test certificate using the first timelocked address // Note that as signatures contains a random nonce, it might not be exactly the same when your code generates it // p2pkh address is the p2pkh address corresponding to the derived public key, it can be used to verify the message // signature in any wallet that supports Verify Message. @@ -158,6 +158,12 @@ string locktime = 2099-12-01 00:00:00 redeemscript = 0580785df400b175210308c5751121b1ae5c973cdc7071312f6fc10ab864262f0cbd8134f056166e50f3ac scriptPubKey = 0020803268e042008737cf439748cbb5a4449e311da9aa64ae3ac56d84d059654f85 address = bc1qsqex3czzqzrn0n6rjayvhddygj0rz8df4fj2uwk9dkzdqkt9f7zs5c493u + +// Test certificate using the 960th timelocked address +Message = fidelity-bond-cert|020000000000000000000000000000000000000000000000000000000000000001|750 +Address = bc1qsqex3czzqzrn0n6rjayvhddygj0rz8df4fj2uwk9dkzdqkt9f7zs5c493u +p2pkh address = 1JmTqEXY9pHwrao9XXPo1MeiQerMETmwP3 +Signature = H9LWcv9PXjOLdGmA6s6jRKnPP9bKeOSUGN7ZF80dphKOUrLQnoIJx8NtHraTq5o6BbRBoNjKHuo4Mnok3/JXGBY=
Code generating these test vectors can be found here: https://github.com/chris-belcher/timelocked-addresses-fidelity-bond-bip-testvectors From 47033c62dc101080c31c1e8a88118ae8288f6d36 Mon Sep 17 00:00:00 2001 From: Sebastian Falbesoner Date: Sat, 22 Jun 2024 01:18:37 +0200 Subject: [PATCH 297/454] BIP-352: sending: add step to fail if input privkeys sum a is zero The test vector data was generated with a Python script (see https://github.com/theStack/bitcoin/blob/bc15ea8d0f282908b912dbf62bba816ecd82424d/contrib/silentpayments/submit_input_pubkeys_infinity_tx.py), leading to the following output: --------------------------------------------------------------------------------------------------------- Privkey 1: a6df6a0bb448992a301df4258e06a89fe7cf7146f59ac3bd5ff26083acb22ceb Privkey 2: 592095f44bb766d5cfe20bda71f9575ed2df6b9fb9addc7e5fdffe0923841456 Pubkey 1: 02557ef3e55b0a52489b4454c1169e06bdea43687a69c1f190eb50781644ab6975 Pubkey 2: 03557ef3e55b0a52489b4454c1169e06bdea43687a69c1f190eb50781644ab6975 scriptPubKey 1: 00149d9e24f9fab4e35bf1a6df4b46cb533296ac0792 scriptPubKey 2: 00149860538b5575962776ed0814ae222c7d60c72d7b Address 1: tb1qnk0zf706kn34hudxma95dj6nx2t2cpujz7j5t5 Address 2: tb1qnps98z64wktzwahdpq22ug3v04svwttm7gs8wn -> Funding tx submitted: 3a286147b25e16ae80aff406f2673c6e565418c40f45c071245cdebc8a94174e Taproot output address for spending tx: tb1pqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqkgkkf5 -> Spending tx submitted: fe788cf6578d547819def43d79e6c8f0153d4885f5a343d12bd03f34507aabd6 --------------------------------------------------------------------------------------------------------- --- bip-0352.mediawiki | 1 + bip-0352/reference.py | 3 ++ bip-0352/send_and_receive_test_vectors.json | 47 ++++++++++++++++++++- 3 files changed, 50 insertions(+), 1 deletion(-) diff --git a/bip-0352.mediawiki b/bip-0352.mediawiki index f36f359272..def4d0b27b 100644 --- a/bip-0352.mediawiki +++ b/bip-0352.mediawiki @@ -302,6 +302,7 @@ After the inputs have been selected, the sender can create one or more outputs f * Collect the private keys for each input from the ''[[#inputs-for-shared-secret-derivation|Inputs For Shared Secret Derivation]]'' list * For each private key ''ai'' corresponding to a [https://github.com/bitcoin/bips/blob/master/bip-0341.mediawiki BIP341] taproot output, check that the private key produces a point with an even Y coordinate and negate the private key if not'''Why do taproot private keys need to be checked?''' Recall from [https://github.com/bitcoin/bips/blob/master/bip-0340.mediawiki BIP340] that each X-only public key has two corresponding private keys, ''d'' and ''n - d''. To maintain parity between sender and receiver, it is necessary to use the private key corresponding to the even Y coordinate when performing the ECDH step since the receiver will assume the even Y coordinate when summing the taproot X-only public keys. * Let ''a = a1 + a2 + ... + an'', where each ''ai'' has been negated if necessary +** If ''a = 0'', fail * Generate the ''input_hash'' with the smallest outpoint lexicographically and ''A = a·G'', using the method described above * Group receiver silent payment addresses by ''Bscan'' (e.g. each group consists of one ''Bscan'' and one or more ''Bm'') * For each group: diff --git a/bip-0352/reference.py b/bip-0352/reference.py index 9b35d0400f..7882ad1ba0 100755 --- a/bip-0352/reference.py +++ b/bip-0352/reference.py @@ -127,6 +127,9 @@ def create_outputs(input_priv_keys: List[Tuple[ECKey, bool]], outpoints: List[CO negated_keys.append(k) a_sum = sum(negated_keys) + if not a_sum.valid: + # Input privkeys sum is zero -> fail + return [] input_hash = get_input_hash(outpoints, a_sum * G) silent_payment_groups: Dict[ECPubKey, List[ECPubKey]] = {} for recipient in recipients: diff --git a/bip-0352/send_and_receive_test_vectors.json b/bip-0352/send_and_receive_test_vectors.json index f9b205b8d3..c0288bc5b9 100644 --- a/bip-0352/send_and_receive_test_vectors.json +++ b/bip-0352/send_and_receive_test_vectors.json @@ -2669,5 +2669,50 @@ } } ] + }, + { + "comment": "Input keys sum up to zero / point at infinity: sending fails, receiver skips tx", + "sending": [ + { + "given": { + "vin": [ + { + "txid": "3a286147b25e16ae80aff406f2673c6e565418c40f45c071245cdebc8a94174e", + "vout": 0, + "scriptSig": "", + "txinwitness": "024730440220085003179ce1a3a88ce0069aa6ea045e140761ab88c22a26ae2a8cfe983a6e4602204a8a39940f0735c8a4424270ac8da65240c261ab3fda9272f6d6efbf9cfea366012102557ef3e55b0a52489b4454c1169e06bdea43687a69c1f190eb50781644ab6975", + "prevout": { + "scriptPubKey": { + "hex": "00149d9e24f9fab4e35bf1a6df4b46cb533296ac0792" + } + }, + "private_key": "a6df6a0bb448992a301df4258e06a89fe7cf7146f59ac3bd5ff26083acb22ceb" + }, + { + "txid": "3a286147b25e16ae80aff406f2673c6e565418c40f45c071245cdebc8a94174e", + "vout": 1, + "scriptSig": "", + "txinwitness": "0247304402204586a68e1d97dd3c6928e3622799859f8c3b20c3c670cf654cc905c9be29fdb7022043fbcde1689f3f4045e8816caf6163624bd19e62e4565bc99f95c533e599782c012103557ef3e55b0a52489b4454c1169e06bdea43687a69c1f190eb50781644ab6975", + "prevout": { + "scriptPubKey": { + "hex": "00149860538b5575962776ed0814ae222c7d60c72d7b" + } + }, + "private_key": "592095f44bb766d5cfe20bda71f9575ed2df6b9fb9addc7e5fdffe0923841456" + } + ], + "recipients": [ + "sp1qqtrqglu5g8kh6mfsg4qxa9wq0nv9cauwfwxw70984wkqnw2uwz0w2qnehen8a7wuhwk9tgrzjh8gwzc8q2dlekedec5djk0js9d3d7qhnq6lqj3s" + ] + }, + "expected": { + "outputs": [ + [] + ] + } + } + ], + "receiving": [ + ] } -] \ No newline at end of file +] From 59cc43d727000794f18dac0a502cd87c0daec22a Mon Sep 17 00:00:00 2001 From: Sebastian Falbesoner Date: Fri, 14 Jun 2024 14:33:40 +0200 Subject: [PATCH 298/454] BIP-352: scanning: add step to skip tx if input pubkeys sum A is point at infinity The input data for the test vector is taken from the signet transaction fe788cf6578d547819def43d79e6c8f0153d4885f5a343d12bd03f34507aabd6 which spends two P2WPKH inputs with negated pubkeys (x, y) and (x, -y) from the funding transaction 3a286147b25e16ae80aff406f2673c6e565418c40f45c071245cdebc8a94174e (see also https://github.com/bitcoin-core/secp256k1/pull/1519#issuecomment-2143167510 and the output from the script in the previous commit message). Co-authored-by: josibake --- bip-0352.mediawiki | 1 + bip-0352/reference.py | 4 ++ bip-0352/send_and_receive_test_vectors.json | 42 +++++++++++++++++++++ 3 files changed, 47 insertions(+) diff --git a/bip-0352.mediawiki b/bip-0352.mediawiki index def4d0b27b..0cf63a9f79 100644 --- a/bip-0352.mediawiki +++ b/bip-0352.mediawiki @@ -335,6 +335,7 @@ A scan and spend key pair using BIP32 derivation are defined (taking inspiration If each of the checks in ''[[#scanning-silent-payment-eligible-transactions|Scanning silent payment eligible transactions]]'' passes, the receiving wallet must: * Let ''A = A1 + A2 + ... + An'', where each ''Ai'' is the public key of an input from the ''[[#inputs-for-shared-secret-derivation|Inputs For Shared Secret Derivation]]'' list +** If ''A'' is the point at infinity, skip the transaction * Generate the ''input_hash'' with the smallest outpoint lexicographically and ''A'', using the method described above * Let ''ecdh_shared_secret = input_hash·bscan·A'' * Check for outputs: diff --git a/bip-0352/reference.py b/bip-0352/reference.py index 7882ad1ba0..b4eaf94560 100755 --- a/bip-0352/reference.py +++ b/bip-0352/reference.py @@ -300,6 +300,10 @@ def scanning(b_scan: ECKey, B_spend: ECPubKey, A_sum: ECPubKey, input_hash: byte add_to_wallet = [] if (len(input_pub_keys) > 0): A_sum = reduce(lambda x, y: x + y, input_pub_keys) + if A_sum.get_bytes() is None: + # Input pubkeys sum is point at infinity -> skip tx + assert expected["outputs"] == [] + continue input_hash = get_input_hash([vin.outpoint for vin in vins], A_sum) pre_computed_labels = { (generate_label(b_scan, label) * G).get_bytes(False).hex(): generate_label(b_scan, label).hex() diff --git a/bip-0352/send_and_receive_test_vectors.json b/bip-0352/send_and_receive_test_vectors.json index c0288bc5b9..264f7becb5 100644 --- a/bip-0352/send_and_receive_test_vectors.json +++ b/bip-0352/send_and_receive_test_vectors.json @@ -2713,6 +2713,48 @@ } ], "receiving": [ + { + "given": { + "vin": [ + { + "txid": "3a286147b25e16ae80aff406f2673c6e565418c40f45c071245cdebc8a94174e", + "vout": 0, + "scriptSig": "", + "txinwitness": "024730440220085003179ce1a3a88ce0069aa6ea045e140761ab88c22a26ae2a8cfe983a6e4602204a8a39940f0735c8a4424270ac8da65240c261ab3fda9272f6d6efbf9cfea366012102557ef3e55b0a52489b4454c1169e06bdea43687a69c1f190eb50781644ab6975", + "prevout": { + "scriptPubKey": { + "hex": "00149d9e24f9fab4e35bf1a6df4b46cb533296ac0792" + } + } + }, + { + "txid": "3a286147b25e16ae80aff406f2673c6e565418c40f45c071245cdebc8a94174e", + "vout": 1, + "scriptSig": "", + "txinwitness": "0247304402204586a68e1d97dd3c6928e3622799859f8c3b20c3c670cf654cc905c9be29fdb7022043fbcde1689f3f4045e8816caf6163624bd19e62e4565bc99f95c533e599782c012103557ef3e55b0a52489b4454c1169e06bdea43687a69c1f190eb50781644ab6975", + "prevout": { + "scriptPubKey": { + "hex": "00149860538b5575962776ed0814ae222c7d60c72d7b" + } + } + } + ], + "outputs": [ + "0000000000000000000000000000000000000000000000000000000000000000" + ], + "key_material": { + "spend_priv_key": "0000000000000000000000000000000000000000000000000000000000000001", + "scan_priv_key": "0000000000000000000000000000000000000000000000000000000000000002" + }, + "labels": [] + }, + "expected": { + "addresses": [ + "sp1qqtrqglu5g8kh6mfsg4qxa9wq0nv9cauwfwxw70984wkqnw2uwz0w2qnehen8a7wuhwk9tgrzjh8gwzc8q2dlekedec5djk0js9d3d7qhnq6lqj3s" + ], + "outputs": [] + } + } ] } ] From 496e4295e76579b75dbafbd8a6c6e49948cc0d8d Mon Sep 17 00:00:00 2001 From: Sebastian Falbesoner Date: Sat, 22 Jun 2024 01:55:00 +0200 Subject: [PATCH 299/454] BIP-352: add change log (SemVer format) The first paragraph is taken from BIP-327, with the sentence about MAJOR version zero removed, as it's not relevant here (we don't track the pre-merge history). --- bip-0352.mediawiki | 11 +++++++++++ 1 file changed, 11 insertions(+) diff --git a/bip-0352.mediawiki b/bip-0352.mediawiki index 0cf63a9f79..c9f18547c1 100644 --- a/bip-0352.mediawiki +++ b/bip-0352.mediawiki @@ -483,6 +483,17 @@ A malicious notification could potentially cause the following issues: Wallet designers can choose which tradeoffs they find appropriate. For example, a wallet could check the block filter to at least probabilistically confirm the likely existence of the UTXO, thus efficiently cutting down on spam. The payment could then be marked as unconfirmed until a scan is performed and the existence of the UTXO in accordance to the silent payment specification is verified. +== Change Log == + +To help implementers understand updates to this document, we attach a version number that resembles ''semantic versioning'' (MAJOR.MINOR.PATCH). +The MAJOR version is incremented if changes to the BIP are introduced that are incompatible with prior versions. +The MINOR version is incremented whenever the inputs or the output of an algorithm changes in a backward-compatible way or new backward-compatible functionality is added. +The PATCH version is incremented for other changes that are noteworthy (bug fixes, test vectors, important clarifications, etc.). + +* '''1.0.1''' (2024-06-22): +** Add steps to fail if private key sum is zero (for sender) or public key sum is point at infinity (for receiver), add corresponding test vectors. +* '''1.0.0''' (2024-05-08): +** Initial version, merged as BIP-352. == Acknowledgements == From a1590ca121c112b1ff51b01a1215d719ec3783ae Mon Sep 17 00:00:00 2001 From: Orfeas Stefanos Thyfronitis Litos Date: Tue, 25 Jun 2024 17:13:41 +0100 Subject: [PATCH 300/454] Fix typo --- bip-0143.mediawiki | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/bip-0143.mediawiki b/bip-0143.mediawiki index 81763a0774..59b2bb58dd 100644 --- a/bip-0143.mediawiki +++ b/bip-0143.mediawiki @@ -114,7 +114,7 @@ Refer to the reference implementation, reproduced below, for the precise algorit ss << hashSequence; // The input being signed (replacing the scriptSig with scriptCode + amount) // The prevout may already be contained in hashPrevout, and the nSequence - // may already be contain in hashSequence. + // may already be contained in hashSequence. ss << txTo.vin[nIn].prevout; ss << static_cast(scriptCode); ss << amount; From 3d299b4eb026eb3983966711b9ee43cfc1167aaf Mon Sep 17 00:00:00 2001 From: Elias Rad <146735585+nnsW3@users.noreply.github.com> Date: Tue, 25 Jun 2024 20:26:19 +0300 Subject: [PATCH 301/454] BIP39: fix grammar in wordlists doc (#1626) --- bip-0039/bip-0039-wordlists.md | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/bip-0039/bip-0039-wordlists.md b/bip-0039/bip-0039-wordlists.md index 5acf87d1f1..7cf8fcb2cf 100644 --- a/bip-0039/bip-0039-wordlists.md +++ b/bip-0039/bip-0039-wordlists.md @@ -28,7 +28,7 @@ for two smaller words (This would be a problem with any of the 3 character sets ### Spanish -1. Words can be uniquely determined typing the first 4 characters (sometimes less). +1. Words can be uniquely determined by typing the first 4 characters (sometimes less). 2. Special Spanish characters like 'ñ', 'ü', 'á', etc... are considered equal to 'n', 'u', 'a', etc... in terms of identifying a word. Therefore, there is no need to use a Spanish keyboard to introduce the passphrase, an application with the Spanish wordlist will be able to identify the words after the first 4 chars have been typed even if the chars with accents have been replaced with the equivalent without accents. @@ -92,7 +92,7 @@ Credits: @zizelevak (Jan Lansky zizelevak@gmail.com) Words chosen using the following rules: 1. Words are 4-8 letters long. -2. Words can be uniquely determined typing the first 4 letters. +2. Words can be uniquely determined by typing the first 4 letters. 3. Only words containing all letters without diacritical marks. (It was the hardest task, because one third of all Czech letters has diacritical marks.) 4. Only nouns, verbs and adverbs, no other word types. All words are in basic form. 5. No personal names or geographical names. @@ -104,7 +104,7 @@ Words chosen using the following rules: Credits: @alegotardo @bitmover-studio @brenorb @kuthullu @ninjastic @sabotag3x @Trimegistus -1. Words can be uniquely determined typing the first 4 characters. +1. Words can be uniquely determined by typing the first 4 characters. 2. No accents or special characters. 3. No complex verb forms. 4. No plural words, unless there's no singular form. From 3b995946605623c16adc954b5c841104db2d3022 Mon Sep 17 00:00:00 2001 From: Ava Chow Date: Wed, 10 Apr 2024 09:37:34 -0400 Subject: [PATCH 302/454] BIP 379: Specify Miniscript Co-Authored-By: Antoine Poinsot --- README.mediawiki | 7 + bip-0379.md | 423 +++++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 430 insertions(+) create mode 100644 bip-0379.md diff --git a/README.mediawiki b/README.mediawiki index 548e3c035b..fbddd61b58 100644 --- a/README.mediawiki +++ b/README.mediawiki @@ -1163,6 +1163,13 @@ Those proposing changes should consider that ultimately consent may rest with th | Standard | Draft |- +| [[bip-0379.md|379]] +| Applications +| Miniscript +| Pieter Wuille, Andrew Poelstra, Sanket Kanjalkar, Antoine Poinsot, Ava Chow +| Informational +| Draft +|- | [[bip-0380.mediawiki|380]] | Applications | Output Script Descriptors General Operation diff --git a/bip-0379.md b/bip-0379.md new file mode 100644 index 0000000000..10755d4e8e --- /dev/null +++ b/bip-0379.md @@ -0,0 +1,423 @@ +
+  BIP: 379
+  Layer: Applications
+  Title: Miniscript
+  Author: Pieter Wuille 
+          Andrew Poelstra 
+          Sanket Kanjalkar 
+          Antoine Poinsot 
+          Ava Chow 
+  Comments-Summary: No comments yet.
+  Comments-URI: https://github.com/bitcoin/bips/wiki/Comments:BIP-0379
+  Status: Draft
+  Type: Informational
+  Created: 2023-10-10
+  License: CC0-1.0
+
+ +## Abstract + +This document specifies Miniscript, a language for writing (a subset of) Bitcoin Scripts in a +structured way, enabling analysis, composition, generic signing and more. + +## Copyright + +This document is licensed under the Creative Commons CC0 1.0 Universal license. + +## Motivation + +Bitcoin Script is an unusual stack-based language with many edge cases, designed for implementing +spending conditions consisting of various combinations of signatures, hash locks, and time locks. +Yet, despite being limited in functionality, it is still highly nontrivial to: + +* Given a combination of spending conditions, finding the most economical script to implement it. +* Given two scripts, construct a script that implements a composition of their spending conditions (e.g. a multisig where one of the "keys" is another multisig). +* Given a script, find out what spending conditions it permits. +* Given a script and access to a sufficient set of private keys, construct a general satisfying witness for it. +* Given a script, be able to predict the cost of spending an output. +* Given a script, know whether particular resource limitations like the ops limit might be hit when spending. + +Miniscript functions as a representation for scripts that makes this sort of operations possible. +It has a structure that allows composition. It is very easy to statically analyze for various +properties (spending conditions, correctness, security properties, malleability, ...). It can be +targeted by spending policy compilers. Finally, compatible scripts can easily be converted to +Miniscript form - avoiding the need for additional metadata for e.g. signing devices that support +it. + +## Specification + +These specifications apply to P2WSH ([BIP 141](bip-0141.mediawiki)) and Tapscript ([BIP 342](bip-0342.mediawiki)) scripts, with only minor +variations between the two. Differences are noted inline. Unless explicitly stated otherwise, +specifications apply to both. P2SH and bare scripts are excluded from this specification. + +### Translation Table + +Miniscript consists of a set of script *fragments* which are designed to be safely and correctly composabe. + +This table shows all Miniscript *fragments* and their associated semantics and Bitcoin Script. +Fragments that do not change the semantics of their subexpressions are called *wrappers*. Normal +fragments use a `fragment(arg1,arg2,...)` notation, while wrappers are written using +prefixes separated from other fragments by a colon. The colon is dropped between subsequent +wrappers; e.g. `dv:older(144)` is the `d:` wrapper applied to the +`v:` wrapper applied to the `older` fragment for 144 blocks. + +The `pk`, `pkh`, and `and_n` fragments and `t:`, +`l:`, and `u:` wrappers are syntactic sugar for other Miniscripts, as listed +in the table below. Note that `<20>` are in hex representation in this document. + +Miniscript fragments are expected to be used in [BIP 382](bip-0382.mediawiki) `wsh()` descriptors +and [BIP 386](bip-0386.mediawiki) `tr()` descriptors. Key expressions are specified in +[BIP 380](bip-0380.mediawiki#user-content-Key_Expressions). Additionally, BIPs 382 and 386 specify +restrictions on key expressions and what they resolve to - these apply to key expressions in +Miniscript. BIP 382's key expression restrictions apply to Miniscript in P2WSH contexts, and BIP +386's key expression restrictions apply to Miniscript in P2TR contexts. From a user's perspective, +Miniscript is not a separate language, but rather a significant expansion of the descriptor language. + +| Semantics | Miniscript Fragment | Bitcoin Script +|----------------------------------------------------------|-------------------------------|--------------- +| false | `0` | `0` +| true | `1` | `1` +| check(key) | `pk_k(key)` | `` +| | `pk_h(key)` | `DUP HASH160 EQUALVERIFY ` +| | `pk(key)` = `c:pk_k(key)` | ` CHECKSIG` +| | `pkh(key)` = `c:pk_h(key)` | `DUP HASH160 EQUALVERIFY CHECKSIG` +| nSequence ≥ n (and compatible) | `older(n)` | ` CHECKSEQUENCEVERIFY` +| nLockTime ≥ n (and compatible) | `after(n)` | ` CHECKLOCKTIMEVERIFY` +| len(x) = 32 and SHA256(x) = h | `sha256(h)` | `SIZE <20> EQUALVERIFY SHA256 EQUAL` +| len(x) = 32 and HASH256(x) = h | `hash256(h)` | `SIZE <20> EQUALVERIFY HASH256 EQUAL` +| len(x) = 32 and RIPEMD160(x) = h | `ripemd160(h)` | `SIZE <20> EQUALVERIFY RIPEMD160 EQUAL` +| len(x) = 32 and HASH160(x) = h | `hash160(h)` | `SIZE <20> EQUALVERIFY HASH160 EQUAL` +| (X and Y) or Z | `andor(X,Y,Z)` | `[X] NOTIF [Z] ELSE [Y] ENDIF` +| X and Y | `and_v(X,Y)` | `[X] [Y]` +| | `and_b(X,Y)` | `[X] [Y] BOOLAND` +| | `and_n(X,Y)` = `andor(X,Y,0)` | `[X] NOTIF 0 ELSE [Y] ENDIF` +| X or Z | `or_b(X,Z)` | `[X] [Z] BOOLOR` +| | `or_c(X,Z)` | `[X] NOTIF [Z] ENDIF` +| | `or_d(X,Z)` | `[X] IFDUP NOTIF [Z] ENDIF` +| | `or_i(X,Z)` | `IF [X] ELSE [Z] ENDIF` +| X_1 + ... + X_n = k | `thresh(k,X_1,...,X_n)` | `[X_1] [X_2] ADD ... [X_n] ADD ... EQUAL` +| check(key_1) + ... + check(key_n) = k *(P2WSH only)* | `multi(k,key_1,...,key_n)` | ` ... CHECKMULTISIG` +| check(key_1) + ... + check(key_n) = k *(Tapscript only)* | `multi_a(k,key_1,...,key_n)` | ` CHECKSIG CHECKSIGADD ... CHECKSIGADD NUMEQUAL` +| X (identities) | `a:X` | `TOALTSTACK [X] FROMALTSTACK` +| | `s:X` | `SWAP [X]` +| | `c:X` | `[X] CHECKSIG` +| | `t:X` = `and_v(X,1)` | `[X] 1` +| | `d:X` | `DUP IF [X] ENDIF` +| | `v:X` | `[X] VERIFY (or VERIFY version of last opcode in [X])` +| | `j:X` | `SIZE 0NOTEQUAL IF [X] ENDIF` +| | `n:X` | `[X] 0NOTEQUAL` +| | `l:X` = `or_i(0,X)` | `IF 0 ELSE [X] ENDIF` +| | `u:X` = `or_i(X,0)` | `IF [X] ELSE 0 ENDIF` + +### Type System + +Not every Miniscript expression can be composed with every other. Some return their result by +putting true or false on the stack; others can only abort or continue. Some require subexpressions +that consume an exactly known number of arguments, while others need a subexpression that has a +nonzero top stack element to satisfy. To model all these properties, we define a correctness type +system for Miniscript. + +#### Correctness + +Every miniscript expression has one of four basic types: "**B**" (base), "**V**" (verify), +"**K**" (key) and "**W**" (wrapped). Then there are 5 type modifiers that guarantee additional +properties: "**z**" (zero-arg), "**o**" (one-arg), "**n**" (nonzero), "**d**" +(dissatisfiable), and "**u**" (unit). + +The following table lists the correctness requirements for each of the Miniscript expressions, and +its type properties in function of those of their subexpressions. + +| Miniscript | Requires | Type | Properties +|------------------------------|-------------------------------------------------------|-------------|----------- +| `0` | | B | z; u; d +| `1` | | B | z; u +| `pk_k(key)` | | K | o; n; d; u +| `pk_h(key)` | | K | n; d; u +| `older(n)`, `after(n)` | 1 ≤ n < 231 | B | z +| `sha256(h)` | | B | o; n; d; u +| `ripemd160(h)` | | B | o; n; d; u +| `hash256(h)` | | B | o; n; d; u +| `hash160(h)` | | B | o; n; d; u +| `andor(X,Y,Z)` | X is Bdu; Y and Z are both B, K, or V | same as Y/Z | z=zXzYzZ; o=zXoYoZ or oXzYzZ; u=uYuZ; d=dZ +| `and_v(X,Y)` | X is V; Y is B, K, or V | same as Y | z=zXzY; o=zXoY or zYoX; n=nX or zXnY; u=uY +| `and_b(X,Y)` | X is B; Y is W | B | z=zXzY; o=zXoY or zYoX; n=nX or zXnY; d=dXdY; u +| `or_b(X,Z)` | X is Bd; Z is Wd | B | z=zXzZ; o=zXoZ or zZoX; d; u +| `or_c(X,Z)` | X is Bdu; Z is V | V | z=zXzZ; o=oXzZ +| `or_d(X,Z)` | X is Bdu; Z is B | B | z=zXzZ; o=oXzZ; d=dZ; u=uZ +| `or_i(X,Z)` | both are B, K, or V | same as X/Z | o=zXzZ; u=uXuZ; d=dX or dZ +| `thresh(k,X_1,...,X_n)` | 1 ≤ k ≤ n; X1 is Bdu; others are Wdu | B | z=all are z; o=all are z except one is o; d; u +| `multi(k,key_1,...,key_n)` | 1 ≤ k ≤ n ≤ 20 | B | n; d; u +| `multi_a(k,key_1,...,key_n)` | 1 ≤ k ≤ n | B | d; u +| `a:X` | X is B | W | d=dX; u=uX +| `s:X` | X is Bo | W | d=dX; u=uX +| `c:X` | X is K | B | o=oX; n=nX; d=dX; u +| `d:X` | X is Vz | B | o; n; d; *(Tapscript only)* u +| `v:X` | X is B | V | z=zX; o=oX; n=nX +| `j:X` | X is Bn | B | o=oX; n; d; u=uX +| `n:X` | X is B | B | z=zX; o=oX; n=nX; d=dX; u + +#### Timelock Type Mixing + +There is one additional correctness property that Miniscript expressions must satisfy: +the four timelock types (absolute time based, absolute height based, relative time based, and +relative height based) must not be mixed in an incompatible way. + +Within `and` combinators and the `thresh` combinator where k >= 2, it is illegal for both absolute +height based and time based timelocks to appear, or for both relative height based and time based +timelocks to appear. + +For all other combinators, it is legal to mix timelock types. It is also always legal to +mix absolute and relative timelocks (even if one is height based and the other is time based). + +#### Malleability + +Malleability is the ability for a third party (someone who does *not* hold a participating private +key) to modify an existing satisfaction into another valid satisfaction. To analyze the +malleability guarantees of a script we define three additional type properties: "**s**" (signed), +"**f**" (forced) and "**e**" (expressive). + +The following table lists the malleability properties and requirement of each fragment. + +| Miniscript | Requires | Properties +|------------------------------|---------------------------------------------------------------------|----------- +| `0` | | s, e +| `1` | | f +| `pk_k(key)` | | s, e +| `pk_h(key)` | | s, e +| `older(n)` | | f +| `after(n)` | | f +| `sha256(h)` | | +| `ripemd160(h)` | | +| `hash256(h)` | | +| `hash160(h)` | | +| `andor(X,Y,Z)` | eX and (sX or sY or sZ) | s=sZ and (sX or sY); f=fZ and (sX or fY); e=eZ and (sX or fY) +| `and_v(X,Y)` | | s=sX or sY; f=sX or fY +| `and_b(X,Y)` | | s=sX or sY; f=fXfY or sXfX or sYfY; e=eXeYsXsY +| `or_b(X,Z)` | eXeZ and (sX or sZ) | s=sXsZ; e +| `or_c(X,Z)` | eX and (sX or sZ) | s=sXsZ; f +| `or_d(X,Z)` | eX and (sX or sZ) | s=sXsZ; f=fZ; e=eZ +| `or_i(X,Z)` | sX or sZ | s=sXsZ; f=fXfZ; e=eXfZ or eZfX +| `thresh(k,X_1,...,X_n)` | all are e; at most k are non-s | s=at most k-1 are non-s; e=all are s +| `multi(k,key_1,...,key_n)` | | s; e +| `multi_a(k,key_1,...,key_n)` | | s; e +| `a:X` | | s=sX; f=fX; e=eX +| `s:X` | | s=sX; f=fX; e=eX +| `c:X` | | s; f=fX; e=eX +| `d:X` | | s=sX; e +| `v:X` | | s=sX; f +| `j:X` | | s=sX; e=fX +| `n:X` | | s=sX; f=fX; e=eX + +### Satisfaction + +The following table shows all valid satisfactions and dissatisfactions for every Miniscript, using +satisfactions and dissatisfactions of its subexpressions. Multiple possibilities are separated by +semicolons. Some options are inefficient and provably unnecessary to the satisfaction algorithm +described below, but are valid according to script rules and could be used by a malleator or other +non-standard actor. These are called *non-canonical* options, and are listed for completeness, but +~~[struckthrough]~~. The fragments where a satisfaction or dissatisfaction does not exist will +contain *(none)*. The fragments where the satisfaction or dissatisfaction is to provide no data +will contain *(empty)*. + +| Miniscript | Dissatisfactions (dsat) | Satisfactions (sat) +|------------------------------|---------------------------------------------------------|-------------------- +| `0` | *(empty)* | *(none)* +| `1` | *(none)* | *(empty)* +| `pk_k(key)` | 0 | sig +| `pk_h(key)` | 0 key | sig key +| `older(n)` | *(none)* | *(empty)* +| `after(n)` | *(none)* | *(empty)* +| `sha256(h)` | any 32-byte vector except the preimage | preimage +| `ripemd160(h)` | any 32-byte vector except the preimage | preimage +| `hash256(h)` | any 32-byte vector except the preimage | preimage +| `hash160(h)` | any 32-byte vector except the preimage | preimage +| `andor(X,Y,Z)` | dsat(Z) dsat(X); ~~[dsat(Y) sat(X)]~~ | sat(Y) sat(X); sat(Z) dsat(X) +| `and_v(X,Y)` | *(none)*; ~~[dsat(Y) sat(X)]~~ | sat(Y) sat(X) +| `and_b(X,Y)` | dsat(Y) dsat(X); ~~[sat(Y) dsat(X)]; [dsat(Y) sat(X)]~~ | sat(Y) sat(X) +| `or_b(X,Z)` | dsat(Z) dsat(X) | dsat(Z) sat(X); sat(Z) dsat(X); ~~[sat(Z) sat(X)]~~ +| `or_c(X,Z)` | *(none)* | sat(X); sat(Z) dsat(X) +| `or_d(X,Z)` | dsat(Z) dsat(X) | sat(X); sat(Z) dsat(X) +| `or_i(X,Z)` | dsat(X) 1; dsat(Z) 0 | sat(X) 1; sat(Z) 0 +| `thresh(k,X_1,...,X_n)` | All dsats; ~~[Sats/dsats with 1 ≤ #(sats) ≠ k]~~ | Sats/dsats with #(sats) = k +| `multi(k,key_1,...,key_n)` | 0 0 ... 0 (k+1 times) | 0 sig ... sig +| `multi_a(k,key_1,...,key_n)` | 0 ... 0 (n times); ~~[sig/0 with #(sig) ≠ k]~~ | sig/0 with #(sig) = k and #(sigs/0) = n +| `a:X` | dsat(X) | sat(X) +| `s:X` | dsat(X) | sat(X) +| `c:X` | dsat(X) | sat(X) +| `d:X` | 0 | sat(X) 1 +| `v:X` | *(none)* | sat(X) +| `j:X` | 0; ~~[dsat(X) (if nonzero top stack)]~~ | sat(X) +| `n:X` | dsat(X) | sat(X) + +#### Non-malleable Satisfaction Algorithm + +In order to produce non-malleable satisfactions we make use of a function that returns the optimal +satisfaction and dissatisfaction for a given expression (if any exist), or a special DONTUSE ("don't use") value, +together with an optional HASSIG ("has signature") marker that tracks whether the solution contains at least one +signature. To implement the function: +* Invoke the function recursively for all subexpressions, obtaining all their satisfactions/dissatisfactions. +* Iterate over all the valid satisfactions/dissatisfactions in the table above (including the non-canonical ones), taking into account: + * The dissatisfactions for `sha256`, `ripemd160`, `hash256`, and `hash160` are always malleable, so instead use DONTUSE there. + * The non-canonical options for `and_b`, `or_b`, and `thresh` are always overcomplete, so instead use DONTUSE there as well (with HASSIG flag if the original non-canonical solution had one). + * The satisfactions for `pk_k`, `pk_h`, and `multi` can be marked HASSIG. + * When constructing solutions by combining results for subexpressions, the result is DONTUSE if any of the constituent results is DONTUSE. Furthermore, the result gets the HASSIG tag if any of the constituents does. +* If among all valid solutions (including DONTUSE ones) more than one does not have the HASSIG marker, return DONTUSE. +* If instead exactly one does not have the HASSIG marker, return that solution. +* If all valid solutions have the HASSIG marker, but all of them are DONTUSE, return DONTUSE-HASSIG. The HASSIG marker is important because while this represents a choice between multiple options that would cause malleability if used, they are not available to the attacker, and we may be able to avoid them entirely still. +* Otherwise, all not-DONTUSE options are valid, so return the smallest one (in terms of witness size). + +To produce an overall satisfaction, invoke the function on the toplevel expression. If no valid +satisfaction is returned, or it is DONTUSE, fail. Otherwise, if any timelocking is used in the +script but the result does not have the HASSIG flag, also fail. If the satisfaction is both not +DONTUSE and HASSIG, return it. + + +## Discussion + +## Security + +Miniscript primarily aims to provide guarantees on the correctness of a Bitcoin Script. That is, to +guarantee **consensus soundness** and **standardness completeness**. Consensus soundness means +it is not possible to construct a consensus-valid witness for a Bitcoin Script unless the Miniscript +spending conditions are met. Standardness completeness means a standardness-valid witness can be +created for all spending paths of a Miniscript, assuming the resource limits are respected and there +is no timelock mixing. + +Additionally, Miniscript can guarantee the non-malleability and maximum size of a witness. These can +assist in assessing the soundness of protocols where transaction fees (and therefore transaction +size) are security-critical parameters. + +Hash preimages are constrained to 32 bytes to disallow various forms of griefing, including making +non-standard (un-relayable) transactions, consensus-invalid swaps across blockchains, as well as +ensure that satisfaction cost can be accurately calculated. + +In order for these properties to not just apply to script, but to an entire transaction, it's +important that the witness commits to all data relevant for verification. In practice this means +that scripts whose conditions can be met without any digital signature are insecure. Besides being +trivially insecure, note how a transaction lacking a signature check allows an attacker to change +its nLockTime and nSequence fields to meet additional timelock conditions. + +### Type System + +To statically verify the correctness and malleability guarantees discussed in the previous section, +we define a type system. See the specifications above for a reference of each fragment's +requirements and properties. Here we give more information about each type. + +Every expression has one of four basic types: +* "**B**" Base expressions. These take their inputs from the top of the stack. When satisfied, they push a nonzero value of up to 4 bytes onto the stack. When dissatisfied, they push an exact 0 onto the stack (if dissatisfaction without aborting is possible at all). This type is used for most expressions, and required for the top level expression. An example is `older(n)` = ` CHECKSEQUENCEVERIFY`. +* "**V**" Verify expressions. Like "B", these take their inputs from the top of the stack. Upon satisfaction however, they continue without pushing anything. They cannot be dissatisfied (will abort instead). A "V" can be obtained using the `v:` wrapper on a "B" expression, or by combining other "V" expressions using `and_v`, `or_i`, `or_c`, or `andor`. An example is `v:pk(key)` = ` CHECKSIGVERIFY`. +* "**K**" Key expressions. They again take their inputs from the top of the stack, but instead of verifying a condition directly they always push a public key onto the stack, for which a signature is still required to satisfy the expression. A "K" can be converted into a "B" using the `c:` wrapper. An example is `pk_h(key)` = `DUP HASH160 EQUALVERIFY`. +* "**W**" Wrapped expressions. They take their inputs from one below the top of the stack, and push a nonzero (in case of satisfaction) or zero (in case of dissatisfaction) either on top of the stack, or one below. So for example a 3-input "W" would take the stack "A B C D E F" and turn it into "A B F 0" or "A B 0 F" in case of dissatisfaction, and "A B F n" or "A B n F" in case of satisfaction (with n a nonzero value). Every "W" is either `s:B` (SWAP B) or `a:B` (TOALTSTACK B FROMALTSTACK). An example is `s:pk(key)` = `SWAP CHECKSIG`. + +Then there are 6 type modifiers, which guarantee additional properties: +* "**z**" Zero-arg: this expression always consumes exactly 0 stack elements. +* "**o**" One-arg: this expression always consumes exactly 1 stack element. +* "**n**" Nonzero: this expression always consumes at least 1 stack element, no satisfaction for this expression requires the top input stack element to be zero. +* "**d**" Dissatisfiable: a dissatisfaction for this expression can unconditionally be constructed. This implies the dissatisfaction cannot include any signature or hash preimage, and cannot rely on timelocks being satisfied. +* "**u**" Unit: when satisfied, this expression will put an exact 1 on the stack (as opposed to any nonzero value). +* "**k**" No timelock mixing. This expression does not contain a mix of heightlock and timelock of the same type. If the miniscript does not have the "k" property, the miniscript template will not match the user expectation of the corresponding spending policy. + +Finally to analyze malleability guarantees we introduce 3 new type modifiers: +* "**s**" Signed: satisfying this expression always requires a signature (predicting whether all satisfactions will be HASSIG). +* "**f**" Forced: dissatisfying this expression always requires a signature (predicting whether all dissatisfactions will be HASSIG). +* "**e**" Expressive: this requires a unique unconditional dissatisfaction to exist, and forces all conditional dissatisfactions (if any) to require a signature. + + +### Malleability + +Since Segwit, malleating a transaction no longer breaks the validity of unconfirmed descendant +transactions. However, unintentional malleability may still have a number of much weaker undesirable +effects. If a witness can be stuffed with additional data, the transaction's feerate will go down, +potentially to the point where its ability to propagate and get confirmed is impacted. Additionally, +malleability can be exploited to add roundtrips to BIP152 block propagation, by trying to get +different miners to mine different versions of the same transaction. Finally, malleability may +interfere with the usage of hash locks as a mechanism for publishing preimages. + +Using the malleability type properties it is possible to determine statically whether a script can +be non-malleably satisfied under all circumstances. In many cases it is reasonable to only accept +such guaranteed-non-malleable scripts, as unexpected behavior can occur when using other scripts. + +For example, when running the non-malleable satisfaction algorithm above, adding available +preimages, or increasing the nLockTime/nSequence values actually may make it fail where it succeeded +before. This is because a larger set of met conditions may mean an existing satisfaction goes from +non-malleable to malleable. Restricting things to scripts that are guaranteed to be satisfiable in a +non-malleable way avoids this problem. + +When analysing Miniscripts for resource limits, restricting yourself to just non-malleable solutions +(or even non-malleable scripts) also leads to tighter bounds, as all non-canonical satisfactions and +dissatisfactions can be left out of consideration. + +The malleability analysis makes the following assumptions: +* The attacker does not have access to any of the private keys of public keys that participate in the Script. Participants with private keys inherently have the ability to produce different satisfactions by creating multiple signatures. While it is also interesting to study the impact rogue participants can have, we treat it as a distinct problem. +* The attacker only has access to hash preimages that honest users have access to as well. This is a reasonable assumption because hash preimages are revealed once globally, and then available to everyone. On the other hand, making the assumption that attackers may have access to more preimages than honest users makes a large portion of scripts impossible to satisfy in a non-malleable way. +* The attacker gets to see exactly one satisfying witness of any transaction. If he sees multiple, it becomes possible for the attacker to mix and match different satisfactions. This is very hard to reason about. +* We restrict this analysis to scripts where no public key is repeated. If signatures constructed for one part of the script can be bound to other checks in the same script, a variant of the mixing from the previous point becomes available that is equally hard to reason about. Furthermore this situation can be avoided by using separate keys. +* The attacker is constrained by common standardness rules. A miner may be able to malleate a witness considered non-malleable by Miniscript. + +#### Non-Malleable Satisfaction + +Malleable satisfactions or dissatisfactions appear whenever options are available to attackers distinct from the one taken by honest users. This can happen for multiple reasons: +1. Two or more options for a satisfaction or dissatisfaction are listed in the table above which are both available to attackers directly. Regardless of which option is used in the honest solution, the attacker can change the solution to the other one. +2. Two or more options for a satisfaction or dissatisfaction are listed in the table above, only one of which is available to attackers, but the honest solution uses another one. In that case, the attacker can modify the solution to pick the one available to him. +3. The honest users pick a solution that contains a satisfaction which can be turned into a dissatisfaction without invalidating the overall witness. Those are called overcomplete solutions. + +Because we assume attackers never have access to private keys, we can treat any solution that +includes a signature as one that is unavailable to attackers. For others, the worst case is that the +attacker has access to every solution the honest users have, but no others: for preimages this is an +explicit assumption, while timelock availability is determined by the nLockTime and nSequence fields +in the transaction. As long as the overall satisfaction includes at least one signature, those +values are fixed, and timelock availability is identical for attackers and honest users. + +The description of the non-malleable satisfaction algorithm can be used to show that no +non-canonical solutions listed in the satisfaction table can occur inside non-malleable +satisfaction: +* Some of the non-canonical options (the `or_b`, `and_b`, and `thresh` ones) are overcomplete, and thus can clearly not appear in non-malleable satisfactions. +* The fact that non-"d" expressions cannot be dissatisfied in valid witnesses rules out the usage of the non-canonical `and_v` dissatisfaction. +* "d" expressions are defined to be unconditionally dissatisfiable, which implies that for those a non-HASSIG dissatisfaction must exist. Non-HASSIG solutions must be preferred over HASSIG ones (reason 2), and when multiple non-HASSIG ones exist, none can be used (reason 1). This lets us rule out the other non-canonical options in the table: + * `j:X` is always "d", its non-HASSIG dissatisfaction "0" always exists, and thus rules out any usage of "dsat(X)". + * If `andor(X,Y,Z)` is "d", a non-HASSIG dissatisfaction "dsat(Z) dsat(X)" must exist, and thus rules out any usage of "dsat(Y) sat(X)". + * If `and_b(X,Y)` is "d", a non-HASSIG dissatisfaction "dsat(Y) dsat(X)" must exist, and thus rules out any usage of "dsat(Y) sat(X)" and "sat(Y) dsat(X)". Those are also overcomplete. + * `thresh(k,...)` is always "d", a non-HASSIG dissatisfaction with just dissatisfactions must exist due to typing rules, and thus rules out usage of the other dissatisfactions. They are also overcomplete. + + +### Resource Limits + +Various types of Bitcoin Scripts have different resource limitations, either through consensus or standardness. Some of them affect otherwise valid Miniscripts: +* In P2WSH, scripts larger than 3600 bytes are invalid by standardness. In Tapscript, scripts are implicitly bounded by the maximum size of a block (1 million virtual bytes). +* In P2WSH, script satisfactions where the total number of non-push opcodes plus the number of keys participating in all executed `CHECKMULTISIG` is above 201 are invalid by consensus. +* In both Tapscript and P2WSH, script satisfactions which make the stack exceed 1000 elements before or during execution are invalid. +* In P2WSH, satisfactions with a witness consisting of over 100 stack elements (excluding the script itself) are invalid by standardness. + +A static analysis can be performed on a Miniscript to verify if none, all or any of the spending +paths hit any of the limits. + + +## Test Vectors + +TBD + +## Backwards Compatibility + +Miniscript's syntax is compatible with BIP 380 Output Script Descriptors, and should be considered +an extension to it that provides a new type of Script expression that is only valid in +`wsh()` and `tr()` contexts. As these are wholly new expressions, they are not +compatible with any existing implementation of descriptors. Additionally, the scripts produced are +unlikely to be standard scripts. + +The `pk()`, `pkh()`, `multi()`, and `multi_a()` +fragments overlap with existing descriptors. These parse to the same semantic meanings as those +descriptors and produce the same scripts. + +## Reference Implementation + +A first reference implementation and documentation for Miniscript in P2WSH was originally published at +https://github.com/sipa/miniscript . + +The reference implementation for Miniscript in P2WSH was introduced in Bitcoin Core through PRs +[24147](https://github.com/bitcoin/bitcoin/pull/24147), [24148](https://github.com/bitcoin/bitcoin/pull/24148), and +[24149](https://github.com/bitcoin/bitcoin/pull/24149). The last one to be merged was released in Bitcoin +Core version 25.0. + +The reference implementation for Miniscript in Tapscript was introduced in Bitcoin Core in PR +[27255](https://github.com/bitcoin/bitcoin/pull/27255). This PR was merged and released in Bitcoin Core +version 26.0. From 8ac84bd344c2375c4ffc57e65da1527ec191cc5f Mon Sep 17 00:00:00 2001 From: josibake Date: Sat, 29 Jun 2024 14:28:37 +0200 Subject: [PATCH 303/454] BIP352: improve input_hash wording Since https://github.com/bitcoin/bips/pull/1622, it makes more sense to define input_hash inline, vs having its own section. --- bip-0352.mediawiki | 10 ++-------- 1 file changed, 2 insertions(+), 8 deletions(-) diff --git a/bip-0352.mediawiki b/bip-0352.mediawiki index c9f18547c1..483bed3b4b 100644 --- a/bip-0352.mediawiki +++ b/bip-0352.mediawiki @@ -279,12 +279,6 @@ The sender performs the tweak using the private key for the nested ''P2WPKH'' ou The receiver obtains the public key from the ''scriptSig''. The receiver MUST parse the ''scriptSig'' for the public key, even if the ''scriptSig'' does not match the template specified (e.g. OP_DROP ). This is to address the [https://en.bitcoin.it/wiki/Transaction_malleability third-party malleability of ''P2PKH'' ''scriptSigs'']. -=== Input hash === - -The sender and receiver MUST calculate an input hash for the transaction in the following manner: - -* Let ''input_hash = hashBIP0352/Inputs(outpointL || A)'', where ''outpointL'' is the smallest outpoint lexicographically by txid and vout used in the transaction - === Sender === ==== Selecting inputs ==== @@ -303,7 +297,7 @@ After the inputs have been selected, the sender can create one or more outputs f * For each private key ''ai'' corresponding to a [https://github.com/bitcoin/bips/blob/master/bip-0341.mediawiki BIP341] taproot output, check that the private key produces a point with an even Y coordinate and negate the private key if not'''Why do taproot private keys need to be checked?''' Recall from [https://github.com/bitcoin/bips/blob/master/bip-0340.mediawiki BIP340] that each X-only public key has two corresponding private keys, ''d'' and ''n - d''. To maintain parity between sender and receiver, it is necessary to use the private key corresponding to the even Y coordinate when performing the ECDH step since the receiver will assume the even Y coordinate when summing the taproot X-only public keys. * Let ''a = a1 + a2 + ... + an'', where each ''ai'' has been negated if necessary ** If ''a = 0'', fail -* Generate the ''input_hash'' with the smallest outpoint lexicographically and ''A = a·G'', using the method described above +* Let ''input_hash = hashBIP0352/Inputs(outpointL || A)'', where ''outpointL'' is the smallest ''outpoint'' lexicographically used in the transaction and ''A = a·G'' * Group receiver silent payment addresses by ''Bscan'' (e.g. each group consists of one ''Bscan'' and one or more ''Bm'') * For each group: ** Let ''ecdh_shared_secret = input_hash·a·Bscan'' @@ -336,7 +330,7 @@ If each of the checks in ''[[#scanning-silent-payment-eligible-transactions|Scan * Let ''A = A1 + A2 + ... + An'', where each ''Ai'' is the public key of an input from the ''[[#inputs-for-shared-secret-derivation|Inputs For Shared Secret Derivation]]'' list ** If ''A'' is the point at infinity, skip the transaction -* Generate the ''input_hash'' with the smallest outpoint lexicographically and ''A'', using the method described above +* Let ''input_hash = hashBIP0352/Inputs(outpointL || A)'', where ''outpointL'' is the smallest ''outpoint'' lexicographically used in the transaction * Let ''ecdh_shared_secret = input_hash·bscan·A'' * Check for outputs: ** Let ''outputs_to_check'' be the taproot output keys from all taproot outputs in the transaction (spent and unspent). From 2a99b8f925bcab62dd106a46fbc80876c1030db9 Mon Sep 17 00:00:00 2001 From: Sebastian Falbesoner Date: Sat, 29 Jun 2024 16:08:49 +0200 Subject: [PATCH 304/454] BIP-352: use own ripemd160 for reference implementation (#1616) On some operating systems, Python doesn't provide the expected ripemd160 implementation anymore, so the reference implementation fails to start. E.g. in Ubuntu 22.04: ---------------------------------------------------------------------------------------------- $ ./reference.py send_and_receive_test_vectors.json Simple send: two inputs Traceback (most recent call last): File "/usr/lib/python3.10/hashlib.py", line 160, in __hash_new return _hashlib.new(name, data, **kwargs) ValueError: [digital envelope routines] unsupported During handling of the above exception, another exception occurred: Traceback (most recent call last): File "/home/thestack/bips/bip-0352/./reference.py", line 228, in pubkey = get_pubkey_from_input(vin) File "/home/thestack/bips/bip-0352/./reference.py", line 46, in get_pubkey_from_input pubkey_hash = hash160(pubkey_bytes) File "/home/thestack/bips/bip-0352/bitcoin_utils.py", line 130, in hash160 return hashlib.new("ripemd160", hashlib.sha256(s).digest()).digest() File "/usr/lib/python3.10/hashlib.py", line 166, in __hash_new return __get_builtin_constructor(name)(data) File "/usr/lib/python3.10/hashlib.py", line 123, in __get_builtin_constructor raise ValueError('unsupported hash type ' + name) ValueError: unsupported hash type ripemd160 ---------------------------------------------------------------------------------------------- Fix this by providing a manual implementation, taken from the functional test framework of Bitcoin Core. See corresponding issue https://github.com/bitcoin/bitcoin/issues/23710 and PR https://github.com/bitcoin/bitcoin/pull/23716 --- bip-0352/bitcoin_utils.py | 3 +- bip-0352/ripemd160.py | 130 ++++++++++++++++++++++++++++++++++++++ 2 files changed, 132 insertions(+), 1 deletion(-) create mode 100644 bip-0352/ripemd160.py diff --git a/bip-0352/bitcoin_utils.py b/bip-0352/bitcoin_utils.py index 443c096d0e..ee55f2d3b3 100644 --- a/bip-0352/bitcoin_utils.py +++ b/bip-0352/bitcoin_utils.py @@ -1,6 +1,7 @@ import hashlib import struct from io import BytesIO +from ripemd160 import ripemd160 from secp256k1 import ECKey from typing import Union @@ -127,7 +128,7 @@ def is_null(self): def hash160(s: Union[bytes, bytearray]) -> bytes: - return hashlib.new("ripemd160", hashlib.sha256(s).digest()).digest() + return ripemd160(hashlib.sha256(s).digest()) def is_p2tr(spk: bytes) -> bool: diff --git a/bip-0352/ripemd160.py b/bip-0352/ripemd160.py new file mode 100644 index 0000000000..12801364b4 --- /dev/null +++ b/bip-0352/ripemd160.py @@ -0,0 +1,130 @@ +# Copyright (c) 2021 Pieter Wuille +# Distributed under the MIT software license, see the accompanying +# file COPYING or http://www.opensource.org/licenses/mit-license.php. +"""Test-only pure Python RIPEMD160 implementation.""" + +import unittest + +# Message schedule indexes for the left path. +ML = [ + 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, + 7, 4, 13, 1, 10, 6, 15, 3, 12, 0, 9, 5, 2, 14, 11, 8, + 3, 10, 14, 4, 9, 15, 8, 1, 2, 7, 0, 6, 13, 11, 5, 12, + 1, 9, 11, 10, 0, 8, 12, 4, 13, 3, 7, 15, 14, 5, 6, 2, + 4, 0, 5, 9, 7, 12, 2, 10, 14, 1, 3, 8, 11, 6, 15, 13 +] + +# Message schedule indexes for the right path. +MR = [ + 5, 14, 7, 0, 9, 2, 11, 4, 13, 6, 15, 8, 1, 10, 3, 12, + 6, 11, 3, 7, 0, 13, 5, 10, 14, 15, 8, 12, 4, 9, 1, 2, + 15, 5, 1, 3, 7, 14, 6, 9, 11, 8, 12, 2, 10, 0, 4, 13, + 8, 6, 4, 1, 3, 11, 15, 0, 5, 12, 2, 13, 9, 7, 10, 14, + 12, 15, 10, 4, 1, 5, 8, 7, 6, 2, 13, 14, 0, 3, 9, 11 +] + +# Rotation counts for the left path. +RL = [ + 11, 14, 15, 12, 5, 8, 7, 9, 11, 13, 14, 15, 6, 7, 9, 8, + 7, 6, 8, 13, 11, 9, 7, 15, 7, 12, 15, 9, 11, 7, 13, 12, + 11, 13, 6, 7, 14, 9, 13, 15, 14, 8, 13, 6, 5, 12, 7, 5, + 11, 12, 14, 15, 14, 15, 9, 8, 9, 14, 5, 6, 8, 6, 5, 12, + 9, 15, 5, 11, 6, 8, 13, 12, 5, 12, 13, 14, 11, 8, 5, 6 +] + +# Rotation counts for the right path. +RR = [ + 8, 9, 9, 11, 13, 15, 15, 5, 7, 7, 8, 11, 14, 14, 12, 6, + 9, 13, 15, 7, 12, 8, 9, 11, 7, 7, 12, 7, 6, 15, 13, 11, + 9, 7, 15, 11, 8, 6, 6, 14, 12, 13, 5, 14, 13, 13, 7, 5, + 15, 5, 8, 11, 14, 14, 6, 14, 6, 9, 12, 9, 12, 5, 15, 8, + 8, 5, 12, 9, 12, 5, 14, 6, 8, 13, 6, 5, 15, 13, 11, 11 +] + +# K constants for the left path. +KL = [0, 0x5a827999, 0x6ed9eba1, 0x8f1bbcdc, 0xa953fd4e] + +# K constants for the right path. +KR = [0x50a28be6, 0x5c4dd124, 0x6d703ef3, 0x7a6d76e9, 0] + + +def fi(x, y, z, i): + """The f1, f2, f3, f4, and f5 functions from the specification.""" + if i == 0: + return x ^ y ^ z + elif i == 1: + return (x & y) | (~x & z) + elif i == 2: + return (x | ~y) ^ z + elif i == 3: + return (x & z) | (y & ~z) + elif i == 4: + return x ^ (y | ~z) + else: + assert False + + +def rol(x, i): + """Rotate the bottom 32 bits of x left by i bits.""" + return ((x << i) | ((x & 0xffffffff) >> (32 - i))) & 0xffffffff + + +def compress(h0, h1, h2, h3, h4, block): + """Compress state (h0, h1, h2, h3, h4) with block.""" + # Left path variables. + al, bl, cl, dl, el = h0, h1, h2, h3, h4 + # Right path variables. + ar, br, cr, dr, er = h0, h1, h2, h3, h4 + # Message variables. + x = [int.from_bytes(block[4*i:4*(i+1)], 'little') for i in range(16)] + + # Iterate over the 80 rounds of the compression. + for j in range(80): + rnd = j >> 4 + # Perform left side of the transformation. + al = rol(al + fi(bl, cl, dl, rnd) + x[ML[j]] + KL[rnd], RL[j]) + el + al, bl, cl, dl, el = el, al, bl, rol(cl, 10), dl + # Perform right side of the transformation. + ar = rol(ar + fi(br, cr, dr, 4 - rnd) + x[MR[j]] + KR[rnd], RR[j]) + er + ar, br, cr, dr, er = er, ar, br, rol(cr, 10), dr + + # Compose old state, left transform, and right transform into new state. + return h1 + cl + dr, h2 + dl + er, h3 + el + ar, h4 + al + br, h0 + bl + cr + + +def ripemd160(data): + """Compute the RIPEMD-160 hash of data.""" + # Initialize state. + state = (0x67452301, 0xefcdab89, 0x98badcfe, 0x10325476, 0xc3d2e1f0) + # Process full 64-byte blocks in the input. + for b in range(len(data) >> 6): + state = compress(*state, data[64*b:64*(b+1)]) + # Construct final blocks (with padding and size). + pad = b"\x80" + b"\x00" * ((119 - len(data)) & 63) + fin = data[len(data) & ~63:] + pad + (8 * len(data)).to_bytes(8, 'little') + # Process final blocks. + for b in range(len(fin) >> 6): + state = compress(*state, fin[64*b:64*(b+1)]) + # Produce output. + return b"".join((h & 0xffffffff).to_bytes(4, 'little') for h in state) + + +class TestFrameworkKey(unittest.TestCase): + def test_ripemd160(self): + """RIPEMD-160 test vectors.""" + # See https://homes.esat.kuleuven.be/~bosselae/ripemd160.html + for msg, hexout in [ + (b"", "9c1185a5c5e9fc54612808977ee8f548b2258d31"), + (b"a", "0bdc9d2d256b3ee9daae347be6f4dc835a467ffe"), + (b"abc", "8eb208f7e05d987a9b044a8e98c6b087f15a0bfc"), + (b"message digest", "5d0689ef49d2fae572b881b123a85ffa21595f36"), + (b"abcdefghijklmnopqrstuvwxyz", + "f71c27109c692c1b56bbdceb5b9d2865b3708dbc"), + (b"abcdbcdecdefdefgefghfghighijhijkijkljklmklmnlmnomnopnopq", + "12a053384a9c0c88e405a06c27dcf49ada62eb2b"), + (b"ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789", + "b0e20b6e3116640286ed3a87a5713079b21f5189"), + (b"1234567890" * 8, "9b752e45573d4b39f4dbd3323cab82bf63326bfb"), + (b"a" * 1000000, "52783243c1697bdbe16d37f97f68f08325dc1528") + ]: + self.assertEqual(ripemd160(msg).hex(), hexout) From 5700a230dc9c1fc31748a3155f4984cc7e5b95ef Mon Sep 17 00:00:00 2001 From: Stacie Date: Wed, 19 Jun 2024 22:13:28 -0400 Subject: [PATCH 305/454] BIP78: spelling and grammar updates Co-authored-by: Dan Gould Co-authored-by: Jon Atack --- bip-0078.mediawiki | 48 +++++++++++++++++++++++----------------------- 1 file changed, 24 insertions(+), 24 deletions(-) diff --git a/bip-0078.mediawiki b/bip-0078.mediawiki index 352872562c..cc3ef5c307 100644 --- a/bip-0078.mediawiki +++ b/bip-0078.mediawiki @@ -95,7 +95,7 @@ The payjoin proposal PSBT is sent in the HTTP response body, base64 serialized w To ensure compatibility with web-wallets and browser-based-tools, all responses (including errors) must contain the HTTP header Access-Control-Allow-Origin: *. -The sender must ensure that the url refers to a scheme or protocol using authenticated encryption, for example TLS with certificate validation, or a .onion link to a hidden service whose public key identifier has already been communicated via a TLS connection. Senders SHOULD NOT accept a url representing an unencrypted or unauthenticated connection. +The sender must ensure that the URL refers to a scheme or protocol using authenticated encryption, for example TLS with certificate validation, or a .onion link to a hidden service whose public key identifier has already been communicated via a TLS connection. Senders SHOULD NOT accept a URL representing an unencrypted or unauthenticated connection. The original PSBT MUST: * Have all the witnessUTXO or nonWitnessUTXO information filled in. @@ -108,7 +108,7 @@ The original PSBT MAY: The payjoin proposal MUST: * Use all the inputs from the original PSBT. -* Use all the outputs which do not belongs to the receiver from the original PSBT. +* Use all the outputs which do not belong to the receiver from the original PSBT. * Only finalize the inputs added by the receiver. (Referred later as additional inputs) * Only fill the witnessUTXO or nonWitnessUTXO for the additional inputs. @@ -187,10 +187,10 @@ The well-known error codes are: |The receiver rejected the original PSBT. |} -The receiver is allowed to return implementation specific errors which may assist the sender to diagnose any issue. +The receiver is allowed to return implementation-specific errors which may assist the sender to diagnose any issue. However, it is important that error codes that are not well-known and that the message do not appear on the sender's software user interface. -Such error codes or messages could be used maliciously to phish a non technical user. +Such error codes or messages could be used maliciously to phish a non-technical user. Instead those errors or messages can only appear in debug logs. It is advised to hard code the description of the well known error codes into the sender's software. @@ -213,7 +213,7 @@ To prevent this, the sender can agree to pay more fee so the receiver make sure * The sender's transaction is time sensitive. -When a sender pick a specific fee rate, the sender expects the transaction to be confirmed after a specific amount of time. But if the receiver adds an input without bumping the fee of the transaction, the payjoin transaction fee rate will be lower, and thus, longer to confirm. +When a sender picks a specific fee rate, the sender expects the transaction to be confirmed after a specific amount of time. But if the receiver adds an input without bumping the fee of the transaction, the payjoin transaction fee rate will be lower, and thus, longer to confirm. Our recommendation for maxadditionalfeecontribution= is originalPSBTFeeRate * vsize(sender_input_type). @@ -244,8 +244,8 @@ The receiver needs to do some check on the original PSBT before proceeding: * If the sender included inputs in the original PSBT owned by the receiver, the receiver must either return error original-psbt-rejected or make sure they do not sign those inputs in the payjoin proposal. * If the sender's inputs are all from the same scriptPubKey type, the receiver must match the same type. If the receiver can't match the type, they must return error unavailable. * Make sure that the inputs included in the original transaction have never been seen before. -** This prevent [[#probing-attack|probing attacks]]. -** This prevent reentrant payjoin, where a sender attempts to use payjoin transaction as a new original transaction for a new payjoin. +** This prevents [[#probing-attack|probing attacks]]. +** This prevents reentrant payjoin, where a sender attempts to use payjoin transaction as a new original transaction for a new payjoin. *: Interactive receivers are not required to validate the original PSBT because they are not exposed to [[#probing-attack|probing attacks]]. @@ -257,26 +257,26 @@ The sender should check the payjoin proposal before signing it to prevent a mali * If the receiver's BIP21 signalled pjos=0, disable payment output substitution. * Verify that the transaction version, and the nLockTime are unchanged. * Check that the sender's inputs' sequence numbers are unchanged. -* For each inputs in the proposal: -** Verify that no keypaths is in the PSBT input +* For each input in the proposal: +** Verify that no keypaths are in the PSBT input ** Verify that no partial signature has been filled -** If it is one of the sender's input +** If it is one of the sender's inputs: *** Verify that input's sequence is unchanged. *** Verify the PSBT input is not finalized *** Verify that non_witness_utxo and witness_utxo are not specified. -** If it is one of the receiver's input +** If it is one of the receiver's inputs: *** Verify the PSBT input is finalized *** Verify that non_witness_utxo or witness_utxo are filled in. -** Verify that the payjoin proposal did not introduced mixed input's sequence. -** Verify that the payjoin proposal did not introduced mixed input's type. +** Verify that the payjoin proposal inputs all specify the same sequence value. +** Verify that the payjoin proposal did not introduce mixed input's type. ** Verify that all of sender's inputs from the original PSBT are in the proposal. -* For each outputs in the proposal: -** Verify that no keypaths is in the PSBT output +* For each output in the proposal: +** Verify that no keypaths are in the PSBT output ** If the output is the [[#fee-output|fee output]]: *** The amount that was subtracted from the output's value is less than or equal to maxadditionalfeecontribution. Let's call this amount actual contribution. -*** Make sure the actual contribution is only paying fee: The actual contribution is less than or equals to the difference of absolute fee between the payjoin proposal and the original PSBT. -*** Make sure the actual contribution is only paying for fee incurred by additional inputs: actual contribution is less than or equals to originalPSBTFeeRate * vsize(sender_input_type) * (count(payjoin_proposal_inputs) - count(original_psbt_inputs)). (see [[#fee-output|Fee output]] section) -** If the output is the payment output and payment output substitution is allowed. +*** Make sure the actual contribution is only going towards fees: The actual contribution is less than or equals to the difference of absolute fee between the payjoin proposal and the original PSBT. +*** Make sure the actual contribution is only paying for fees incurred by additional inputs: actual contribution is less than or equal to originalPSBTFeeRate * vsize(sender_input_type) * (count(payjoin_proposal_inputs) - count(original_psbt_inputs)). (see [[#fee-output|Fee output]] section) +** If the output is the payment output and payment output substitution is allowed, *** Do not make any check ** Else *** Make sure the output's value did not decrease. @@ -287,8 +287,8 @@ The sender must be careful to only sign the inputs that were present in the orig Note: * The sender must allow the receiver to add/remove or modify the receiver's own outputs. (if payment output substitution is disabled, the receiver's outputs must not be removed or decreased in value) -* The sender should allow the receiver to not add any inputs. This is useful for the receiver to change the paymout output scriptPubKey type. -* If no input have been added, the sender's wallet implementation should accept the payjoin proposal, but not mark the transaction as an actual payjoin in the user interface. +* The sender should allow the receiver to not add any inputs. This is useful for the receiver to change the payment output scriptPubKey type. +* If the receiver added no inputs, the sender's wallet implementation should accept the payjoin proposal, but not mark the transaction as an actual payjoin in the user interface. Our method of checking the fee allows the receiver and the sender to batch payments in the payjoin transaction. It also allows the receiver to pay the fee for batching adding his own outputs. @@ -344,7 +344,7 @@ On top of this the receiver can poison analysis by randomly faking a round amoun ===Payment output substitution=== -Unless disallowed by sender explicitly via `disableoutputsubstitution=true` or by the BIP21 url via query parameter the `pjos=0`, the receiver is free to decrease the amount, remove, or change the scriptPubKey output paying to himself. +Unless disallowed by the sender explicitly via disableoutputsubstitution=true or by the BIP21 URL via the query parameter pjos=0, the receiver is free to decrease the amount, remove, or change the scriptPubKey output paying to himself. Note that if payment output substitution is disallowed, the reveiver can still increase the amount of the output. (See [[#reference-impl|the reference implementation]]) For example, if the sender's scriptPubKey type is P2WPKH while the receiver's payment output in the original PSBT is P2SH, then the receiver can substitute the payment output to be P2WPKH to match the sender's scriptPubKey type. @@ -358,7 +358,7 @@ A compromised payjoin server could steal the hot wallet outputs of the receiver, ===Impacted heuristics=== -Our proposal of payjoin is breaking the following blockchain heuristics: +Our proposal of payjoin breaks the following blockchain heuristics: * Common inputs heuristics. @@ -408,7 +408,7 @@ With payjoin, the maximum amount of money that can be lost is equal to two payme ==Reference sender's implementation== Here is pseudo code of a sender implementation. -RequestPayjoin takes the bip21 URI of the payment, the wallet and the signedPSBT. +RequestPayjoin takes the BIP21 URI of the payment, the wallet and the signedPSBT. The signedPSBT represents a PSBT which has been fully signed, but not yet finalized. We then prepare originalPSBT from the signedPSBT via the CreateOriginalPSBT function and get back the proposal. @@ -674,7 +674,7 @@ A successful exchange with: ==Backward compatibility== -The receivers are advertising payjoin capabilities through [[bip-0021.mediawiki|BIP21's URI Scheme]]. +The receivers advertise payjoin capabilities through [[bip-0021.mediawiki|BIP21's URI Scheme]]. Senders not supporting payjoin will just ignore the pj variable and thus, will proceed to normal payment. From 7acfe207e0e78ee6fc6053789cc90ac848dcfeb2 Mon Sep 17 00:00:00 2001 From: azuchi Date: Sat, 6 Jul 2024 21:49:37 +0900 Subject: [PATCH 306/454] BIP-0386: Fix uncompressed private key test vector --- bip-0386.mediawiki | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/bip-0386.mediawiki b/bip-0386.mediawiki index 759887d41d..2c2ab80818 100644 --- a/bip-0386.mediawiki +++ b/bip-0386.mediawiki @@ -101,7 +101,7 @@ Valid descriptors followed by the scripts they produce. Descriptors involving de Invalid Descriptors -* Uncompressed private key: tr(5kyzdueo39z3fprtux2qbbwgnnp5ztd7yyr2sc1j299sbcnwjss) +* Uncompressed private key: tr(5KYZdUEo39z3FPrtuX2QbbwGnNP5zTd7yyr2SC1j299sBCnWjss) * Uncompressed public key: tr(04a34b99f22c790c4e36b2b3c2c35a36db06226e41c692fc82b8b56ac1c540c5bd5b8dec5235a0fa8722476c7709c02559e3aa73aa03918ba2d492eea75abea235) * tr() nested in wsh: wsh(tr(a34b99f22c790c4e36b2b3c2c35a36db06226e41c692fc82b8b56ac1c540c5bd)) * tr() nested in sh: sh(tr(a34b99f22c790c4e36b2b3c2c35a36db06226e41c692fc82b8b56ac1c540c5bd)) From d3ff66e984a951b9497a84f90368e707b4c9bf4b Mon Sep 17 00:00:00 2001 From: douglaz Date: Sun, 7 Jul 2024 01:01:03 +0000 Subject: [PATCH 307/454] Fix typo in bip-0065 --- bip-0065.mediawiki | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/bip-0065.mediawiki b/bip-0065.mediawiki index 1365884c09..15dca78419 100644 --- a/bip-0065.mediawiki +++ b/bip-0065.mediawiki @@ -170,7 +170,7 @@ Proving the sacrifice of some limited resource is a common technique in a variety of cryptographic protocols. Proving sacrifices of coins to mining fees has been proposed as a ''universal public good'' to which the sacrifice could be directed, rather than simply destroying the coins. However doing so is -non-trivial, and even the best existing technqiue - announce-commit sacrifices +non-trivial, and even the best existing technique - announce-commit sacrifices - could encourage mining centralization. CHECKLOCKTIMEVERIFY can be used to create outputs that are provably spendable by anyone (thus to mining fees assuming miners behave optimally and rationally) but only at a time From 0cdb745ee001b11fe4b1da55ec1fb4f2351b6451 Mon Sep 17 00:00:00 2001 From: theborakompanioni Date: Mon, 8 Jul 2024 10:48:53 +0200 Subject: [PATCH 308/454] docs(bip-0046): apply minor wording improvement suggestions by @AdamISZ --- bip-0046.mediawiki | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/bip-0046.mediawiki b/bip-0046.mediawiki index 1dc124efca..83ddd5eb03 100644 --- a/bip-0046.mediawiki +++ b/bip-0046.mediawiki @@ -73,7 +73,7 @@ m / 84' / 0' / 0' / 2 / index A key derived with this derivation path pattern will be referred to as derived_key further in this document. -For index, addresses are numbered from 0 in a sequentially increasing manner, but index does not increase forever like in other similar standards. The index only goes up to 959 inclusive. Only 960 addresses can be derived for a given BIP32 master key. Furthermore there is no concept of a gap limit, instead wallets must always generate all 960 addresses and check for all of them if they have a balance and history. +For index, addresses are numbered from 0 in a sequentially increasing manner with a fixed upper bound: The index only goes up to 959 inclusive. Only 960 addresses can be derived for a given BIP32 master key. Furthermore there is no concept of a gap limit, instead wallets must always generate all 960 addresses and check for all of them if they have a balance and history. === Timelock derivation === From b916adebae2606edf4934eb6f4a1d056425abf05 Mon Sep 17 00:00:00 2001 From: theborakompanioni Date: Mon, 8 Jul 2024 11:01:26 +0200 Subject: [PATCH 309/454] docs(bip-0046): add cert format and clarify expiry param --- bip-0046.mediawiki | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/bip-0046.mediawiki b/bip-0046.mediawiki index 83ddd5eb03..7eb5d99049 100644 --- a/bip-0046.mediawiki +++ b/bip-0046.mediawiki @@ -99,6 +99,10 @@ To derive the address from the above calculated public key and timelock, we crea In order to support signing of certificates, implementors should support signing ASCII messages. +The certificate message is defined as `"fidelity-bond-cert" || "|" || cert_pubkey || "|" || cert_expiry`. + +The certificate expiry `cert_expiry` is the number of the 2016-block period after which the certificate is no longer valid. For example, if `cert_expiry` is 330 then the certificate will become invalid after block height 665280 (:=330x2016). The purpose of the expiry parameter is so that in case the certificate keypair is compromised, the attacker can only impersonate the fidelity bond for a limited amount of time. + A certificate message can be created by another application external to this standard. It is then prepended with the string `0x18 || "Bitcoin Signed Message:\n"` and a byte denoting the length of the certificate message. The whole thing is then signed with the private key of the derived_key. This part is identical to the "Sign Message" function which many wallets already implement. Almost all wallets implementing this standard can use their already-existing "Sign Message" function to sign the certificate message. As the certificate message itself is always an ASCII string, the wallet may not need to specially implement this section at all but just rely on users copypasting their certificate message into the already-existing "Sign Message" user interface. This works as long as the wallet knows how to use the private key of the timelocked address for signing messages. From 4f788d69f501d26f6c88db7fe0cf19696b608059 Mon Sep 17 00:00:00 2001 From: theborakompanioni Date: Mon, 8 Jul 2024 12:25:37 +0200 Subject: [PATCH 310/454] docs(bip-0046): add endpoint signing example --- bip-0046.mediawiki | 25 +++++++++++++++++-------- 1 file changed, 17 insertions(+), 8 deletions(-) diff --git a/bip-0046.mediawiki b/bip-0046.mediawiki index 7eb5d99049..e3ad575074 100644 --- a/bip-0046.mediawiki +++ b/bip-0046.mediawiki @@ -131,10 +131,10 @@ address = bc1qhhhf29f4nlyalyfrrpfrknxj9uwqk4qsyvkujsa7w0ulfur78xksps // p2pkh address is the p2pkh address corresponding to the derived public key, it can be used to verify the message // signature in any wallet that supports Verify Message. // As mentioned before, it is more important for implementors of this standard to support signing such messages, not verifying them -Message = fidelity-bond-cert|020000000000000000000000000000000000000000000000000000000000000001|375 -Address = bc1qhhhf29f4nlyalyfrrpfrknxj9uwqk4qsyvkujsa7w0ulfur78xkspsqn84 +message = fidelity-bond-cert|020000000000000000000000000000000000000000000000000000000000000001|375 +address = bc1qhhhf29f4nlyalyfrrpfrknxj9uwqk4qsyvkujsa7w0ulfur78xkspsqn84 p2pkh address = 16vmiGpY1rEaYnpGgtG7FZgr2uFCpeDgV6 -Signature = H2b/90XcKnIU/D1nSCPhk8OcxrHebMCr4Ok2d2yDnbKDTSThNsNKA64CT4v2kt+xA1JmGRG/dMnUUH1kKqCVSHo= +signature = H2b/90XcKnIU/D1nSCPhk8OcxrHebMCr4Ok2d2yDnbKDTSThNsNKA64CT4v2kt+xA1JmGRG/dMnUUH1kKqCVSHo= // 2nd timelocked address = m/84'/0'/0'/2/1 derived private_key = KxctaFBzetyc9KXeUr6jxESCZiCEXRuwnQMw7h7hroP6MqnWN6Pf @@ -163,11 +163,20 @@ redeemscript = 0580785df400b175210308c5751121b1ae5c973cdc7071312f6fc10ab8 scriptPubKey = 0020803268e042008737cf439748cbb5a4449e311da9aa64ae3ac56d84d059654f85 address = bc1qsqex3czzqzrn0n6rjayvhddygj0rz8df4fj2uwk9dkzdqkt9f7zs5c493u -// Test certificate using the 960th timelocked address -Message = fidelity-bond-cert|020000000000000000000000000000000000000000000000000000000000000001|750 -Address = bc1qsqex3czzqzrn0n6rjayvhddygj0rz8df4fj2uwk9dkzdqkt9f7zs5c493u -p2pkh address = 1JmTqEXY9pHwrao9XXPo1MeiQerMETmwP3 -Signature = H9LWcv9PXjOLdGmA6s6jRKnPP9bKeOSUGN7ZF80dphKOUrLQnoIJx8NtHraTq5o6BbRBoNjKHuo4Mnok3/JXGBY= +// Test certificate and endpoint signing using the first timelocked address = m/84'/0'/0'/2/0 (see above) +bond private_key = L2tQBEdhC48YLeEWNg3e4msk94iKfyVa9hdfzRwUERabZ53TfH3d +bond p2pkh address = 16vmiGpY1rEaYnpGgtG7FZgr2uFCpeDgV6 + +certificate private_key = KyZpNDKnfs94vbrwhJneDi77V6jF64PWPF8x5cdJb8ifgg2DUc9d +certificate public_key = 0330d54fd0dd420a6e5f8d3624f5f3482cae350f79d5f0753bf5beef9c2d91af3c +certificate p2pkh address = 1JaUQDVNRdhfNsVncGkXedaPSM5Gc54Hso + +certificate message = fidelity-bond-cert|0330d54fd0dd420a6e5f8d3624f5f3482cae350f79d5f0753bf5beef9c2d91af3c|375 +certificate signature = INOP3cB9UW7F1e1Aglj8rI9QhnyxmgWDEPt+nOMvl7hJJne7rH/KCNDYvLiqNuB9qWaWUojutjRsgPJrvyDQ+0Y= + +// example endpoint signing two IRC nicknames (used in JoinMarket) +endpoint message = J54LS6YyJPoseqFS|J55VZ6U6ZyFDNeuv +endpoint signature = H18WE4MugDNoWZIf9jU0njhQptdUyBDUf7lToG9bpMKmeJK0lOoABaDs5bKnohSuZ0e9gnSco5OL9lXdKU7gP5E=