├── .gitignore ├── README.md ├── SUMMARY.md ├── assets ├── lnpbp-0004.png └── lnpbp-layers.png ├── lnpbp-0001.md ├── lnpbp-0002.md ├── lnpbp-0003.md ├── lnpbp-0004.md ├── lnpbp-0005.md ├── lnpbp-0006.md ├── lnpbp-0008.md ├── lnpbp-0010.md ├── lnpbp-0012.md ├── lnpbp-0037.md ├── lnpbp-0046.md ├── lnpbp-0050.md ├── lnpbp-0051.md ├── lnpbp-0053.md ├── lnpbp-0055.md ├── lnpbp-0081.md └── lnpbp-template.md /.gitignore: -------------------------------------------------------------------------------- 1 | .env 2 | 3 | .idea 4 | *.iml 5 | 6 | .DS_Store 7 | 8 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # LNPBPs: LNP/BP Standards Repository 2 | 3 | LNP/BP stands for "Bitcoin Protocol / Lightning Network Protocol". 4 | This repository covers standards & best practices for Layer 2+ in cases when they do 5 | not require soft- or hard-forks of the Bitcoin blockchain level and are not 6 | directly related to issues covered in Lightning Network RFCs (BOLTs). 7 | 8 | LNPBP sstandards cover client-side validation protocols, 9 | which can be anchored or build on top of to Bitcoin. 10 | It includes primitives for L2+ solution design and describes complex 11 | use cases which can be built from some primitives. This allows such solutions as 12 | financial assets, storage, messaging, computing and different forms of secondary 13 | markets leveraging Bitcoin security model and Bitcoin as a method of 14 | payment/medium of exchange. 15 | 16 | Criteria for a LNP/BP specification proposal: 17 | 18 | * Should not be covered by existing or proposed BIPs 19 | * Should not cause soft- or hard-fork in Bitcoin blockchain (but may depend on 20 | soft-forks from an existing BIP proposals) 21 | * Should not distort Bitcoin miner's economic incentives 22 | * Should not pollute Bitcoin blockchain with unnecessary non-transaction related 23 | data or have to maintain such pollution as low as possible 24 | * Must not require a utility or security tokens to function (but may enable 25 | creation of digital assets or tokenized physical goods) 26 | * Must not depend on non-bitcoin blockchains (but may be applicable to other 27 | blockchains) 28 | 29 | 30 | ## Verticals for LNP/BP proposals: 31 | 32 | | Name | Description | Examples | 33 | |-----------------|-------------------------------|-------------------------------------------------| 34 | | Cryptography | Cryptographic primitives | Cryptography, zero knowledge | 35 | | Wallet | Standards for wallet and apps | Derivation paths, APIs, RGB asset schemata | 36 | | Networking | P2P network communications | Network encryption, framing, connectivity etc | 37 | | Smart contracts | Distributed smart contracts | Scriptless scripts, RGB, lightning channels etc | 38 | 39 | 40 | ## List of LNP/BP standards and proposals 41 | 42 | | No | Vertical | Title | Type | Status | 43 | |------:|-----------------|-------------------------------------------------------------------------------------------|---------------|----------| 44 | | [1] | Cryptography | Key tweaking: collision-resistant elliptic curve-based commitments | Standard | Proposal | 45 | | [2] | Cryptography | Script tweaking: deterministic embedding of cryptographic commitments into script pubkeys | Standard | Proposal | 46 | | [3] | Cryptography | Deterministic definition of transaction output containing cryptographic commitment | Standard | Proposal | 47 | | [4] | Cryptography | Multi-protocol commitment scheme with zero-knowledge provable uniqueness | Standard | Proposal | 48 | | [5] | Wallet | Universal short Bitcoin identifiers for blocks, transactions and their inputs & outputs | Standard | Proposal | 49 | | [6] | Cryptography | Deterministic bitcoin commitments | Standard | Proposal | 50 | | 7 | Cryptography | Commitments for structural and hierarchical data | Standard | Proposal | 51 | | [8] | Cryptography | Single-use-seals | Informational | Draft | 52 | | [9] | Cryptography | Client-side-validation | Informational | Draft | 53 | | [10] | Cryptography | Bitcoin transaction output-based single-use-seals | Standard | Proposal | 54 | | 11 | Cryptography | Anchoring multiple deterministic bitcoin commitments in the same transaction output | Standard | Final | 55 | | [12] | Cryptography | TapRet: Taproot script tree-based OP_RETURN deterministic bitcoin commitments | Standard | Final | 56 | | 13-18 | *Reserved* | *For the future use* | | | 57 | | 19 | Cryptography | *Reserved for sign-to-contract deterministic bitcoin commitments* | | | 58 | | 20-31 | *Reserved* | *For the future use* | | | 59 | | 32 | Wallet | BIP-32 derivation path extension for read-only wallets | Standard | Draft | 60 | | [33] | Smart contracts | Lightspeed: micro-payments for Lightning Network | Draft | | 61 | | [34] | Smart contracts | Zero-knowledge arguments for data persistence using probabilistic checkable proofs | Standard | Draft | 62 | | [35] | Smart contracts | Bifrost: LN message extensions for RGB data propagation | Standard | Planned | 63 | | 36-37 | *Reserved* | *For future use by bitcoin protocol extensions* | | | 64 | | [38] | Wallet | Universal LNP/BP invoices | Standard | Draft | 65 | | 39 | *Reserved* | *For future use by bitcoin protocol extensions* | | | 66 | | [40] | Smart contracts | Storm: trustless storage with escrow contracts | Standard | Draft | 67 | | 41 | Smart contracts | Lightning network message extensions for Storm | Standard | Planned | 68 | | 42 | *Reserved* | *For future use* | | | 69 | | 43 | *Reserved* | *For future use by bitcoin protocol extensions* | | | 70 | | 44 | Wallet | Script templating: key derivations within Bitcoin scripts | Standard | Planned | 71 | | 45 | Smart contracts | Lightning network message extensions for decentralized exchange functionality | Standard | Planned | 72 | | 46 | Wallet | Deterministic derivation paths for LNP | Draft | | 73 | | 47,48 | *Reserved* | *For future use by bitcoin protocol extensions* | | | 74 | | 49 | Smart contracts | Synchronized multi-hop state updates via delegation in Lightning network | Standard | Planned | 75 | | [50] | Smart contracts | Bifrost: generalized Lightning network protocol core | Standard | Planned | 76 | | [51] | Smart contracts | Bifrost: channel management protocol | Standard | Draft | 77 | | 52 | Smart contracts | Bifrost routed messaging system based on Sphinx protocol | Standard | Draft | 78 | | [53] | Smart contracts | Milti-peer payment channels for Bifrost | Standard | Draft | 79 | | 54 | Smart contracts | Channel factories based on Bifrost protocol | Standard | Draft | 80 | | [55] | Smart contracts | HTLC channel synchronization in Bifrost | Standard | Draft | 81 | | 56 | Smart contracts | PTLC channel synchronization in Bifrost | Standard | Draft | 82 | | 57 | Smart contracts | Decentralized naming & name resolution system | Standard | Planned | 83 | | [58] | Cryptography | Apophis: distributed elliptic curve-based key creation with shared secrets | Standard | Draft | 84 | | [59] | Smart contracts | Typhon: trustless Bitcoin sidechains | Standard | Draft | 85 | | [60] | Smart contracts | Ibiss: reputation-based interactive computation integrity arguments | Informational | Draft | 86 | | [61] | Smart contracts | Toth: reputation-based interactive settlement for computation integrity arguments | Informational | Draft | 87 | | [62] | Smart contracts | Prometheus: trustless multiparty computing with escrow & arbitration on bitcoin | Standard | Draft | 88 | | 63 | Smart contracts | Prometheus+: prometheus over LN with tokenized RGB reputation | Standard | Planned | 89 | | 64-79 | *Reserved* | *For the future use by lightning network protocol extensions* | | | 90 | | [80] | Cryptography | Merkle mountain ranges | Standard | Final | 91 | | [81] | Cryptography | Tagged merkle trees for client-side-validation | Standard | Draft | 92 | | 82 | Cryptography | OpenTimestamps bitcoin transaction commitments | Standard | Final | 93 | | 83 | Cryptography | OpenTimestamps proof construction & verification | Standard | Final | 94 | | 83 | Cryptography | OpenTimestamps proof serialization | Standard | Final | 95 | | 84 | Cryptography | OpenTimestamps calendar and attestation services | Standard | Final | 96 | | 85-99 | *Reserved* | | | | 97 | | 100 | *Reserved* | *For future use by a scalable & confidential single-use-seal commitment layer 1* | | | 98 | 99 | ### Invited or planned proposals to join LNP/BP standards family 100 | 101 | 1. Discreet log contracts: 102 | * [Specification effort][dlc] 103 | * [Lightning Discreet Log Contract Channels][dlc-ln] 104 | 2. Different [pre-Schnorr schemes for scriptless scripts][scriptless] 105 | 3. Other lightning network extensions: 106 | * [eltoo] 107 | * [PTLC] 108 | 109 | [1]: lnpbp-0001.md 110 | [2]: lnpbp-0002.md 111 | [3]: lnpbp-0003.md 112 | [4]: lnpbp-0004.md 113 | [5]: lnpbp-0005.md 114 | [6]: lnpbp-0006.md 115 | [7]: lnpbp-0007.md 116 | [8]: lnpbp-0008.md 117 | [9]: https://diyhpl.us/wiki/transcripts/scalingbitcoin/milan/client-side-validation/ 118 | 119 | [10]: lnpbp-0010.md 120 | [11]: lnpbp-0011.md 121 | [12]: lnpbp-0012.md 122 | [13]: lnpbp-0013.md 123 | [14]: lnpbp-0014.md 124 | [15]: lnpbp-0015.md 125 | [16]: lnpbp-0016.md 126 | [17]: lnpbp-0017.md 127 | [18]: lnpbp-0018.md 128 | [19]: lnpbp-0019.md 129 | 130 | [20]: lnpbp-0020.md 131 | [21]: lnpbp-0021.md 132 | [22]: lnpbp-0022.md 133 | [23]: lnpbp-0023.md 134 | [24]: lnpbp-0024.md 135 | [25]: lnpbp-0025.md 136 | [26]: lnpbp-0026.md 137 | [27]: lnpbp-0027.md 138 | [28]: lnpbp-0028.md 139 | [29]: lnpbp-0029.md 140 | 141 | [30]: lnpbp-0030.md 142 | [31]: lnpbp-0031.md 143 | [32]: lnpbp-0032.md 144 | [33]: https://github.com/LNP-BP/LNPBPs/issues/24 145 | [34]: https://github.com/storm-org/storm-spec 146 | [35]: https://github.com/LNP-BP/LNPBPs/pull/97 147 | [36]: lnpbp-0036.md 148 | [37]: lnpbp-0037.md 149 | [38]: https://github.com/LNP-BP/FAQ/blob/master/Presentation%20slides/Universal%20LNP-BP%20invoices.pdf 150 | [39]: lnpbp-0039.md 151 | 152 | [40]: https://github.com/storm-org/storm-spec 153 | [41]: lnpbp-0041.md 154 | [42]: lnpbp-0042.md 155 | [43]: https://lists.linuxfoundation.org/pipermail/bitcoin-dev/2021-February/018381.html 156 | [44]: lnpbp-0044.md 157 | [45]: lnpbp-0045.md 158 | [46]: lnpbp-0046.md 159 | [47]: lnpbp-0047.md 160 | [48]: lnpbp-0048.md 161 | [49]: lnpbp-0049.md 162 | 163 | [50]: lnpbp-0050.md 164 | [51]: lnpbp-0051.md 165 | [52]: lnpbp-0052.md 166 | [53]: lnpbp-0053.md 167 | [54]: lnpbp-0054.md 168 | [55]: lnpbp-0055.md 169 | [56]: lnpbp-0056.md 170 | [57]: lnpbp-0057.md 171 | [58]: https://github.com/pandoracore/typhon-spec 172 | [59]: https://github.com/pandoracore/typhon-spec 173 | 174 | [60]: https://github.com/pandoracore/ibiss-spec 175 | [61]: https://github.com/pandoracore/ibiss-spec 176 | [62]: https://github.com/pandoracore/prometheus-spec 177 | [63]: lnpbp-0063.md 178 | [64]: lnpbp-0064.md 179 | [65]: lnpbp-0065.md 180 | [66]: lnpbp-0066.md 181 | [67]: lnpbp-0067.md 182 | [68]: lnpbp-0068.md 183 | [69]: lnpbp-0069.md 184 | 185 | [70]: lnpbp-0070.md 186 | [71]: lnpbp-0071.md 187 | [72]: lnpbp-0072.md 188 | [73]: lnpbp-0073.md 189 | [74]: lnpbp-0074.md 190 | [75]: lnpbp-0075.md 191 | [76]: lnpbp-0076.md 192 | [77]: lnpbp-0077.md 193 | [78]: lnpbp-0078.md 194 | [79]: lnpbp-0079.md 195 | 196 | [80]: https://github.com/opentimestamps/opentimestamps-server/blob/master/doc/merkle-mountain-range.md 197 | [81]: lnpbp-0081.md 198 | [82]: lnpbp-0082.md 199 | [83]: lnpbp-0083.md 200 | [84]: lnpbp-0084.md 201 | [85]: lnpbp-0085.md 202 | [86]: lnpbp-0086.md 203 | [87]: lnpbp-0087.md 204 | [88]: lnpbp-0088.md 205 | [89]: lnpbp-0089.md 206 | 207 | [90]: lnpbp-0090.md 208 | [91]: lnpbp-0091.md 209 | [92]: lnpbp-0092.md 210 | [93]: lnpbp-0093.md 211 | [94]: lnpbp-0094.md 212 | [95]: lnpbp-0095.md 213 | [96]: lnpbp-0096.md 214 | [97]: lnpbp-0097.md 215 | [98]: lnpbp-0098.md 216 | [99]: lnpbp-0099.md 217 | 218 | [100]: lnpbp-0100.md 219 | 220 | [dlc]: https://github.com/discreetlogcontracts/dlcspecs 221 | [dlc-ln]: https://hackmd.io/@lpQxZaCeTG6OJZI3awxQPQ/LN-DLC 222 | [scriptless]: https://lists.linuxfoundation.org/pipermail/lightning-dev/2019-November/002316.html 223 | [eltoo]: https://lists.linuxfoundation.org/pipermail/bitcoin-dev/2018-April/015907.html 224 | [PTLC]: https://suredbits.com/payment-points-part-2-stuckless-payments/ 225 | -------------------------------------------------------------------------------- /SUMMARY.md: -------------------------------------------------------------------------------- 1 | # Table of contents 2 | 3 | * [List of specifications](README.md) 4 | 5 | ## Commitment schemes 6 | 7 | * [LNPBP-1: Public keys](lnpbp-0001.md) 8 | * [LNPBP-2: Script](lnpbp-0002.md) 9 | * [LNPBP-3: Tx output](lnpbp-0003.md) 10 | * [LNPBP-81: Tagged Merkle trees](lnpbp-0081.md) 11 | * [LNPBP-4: Multi-protocol](lnpbp-0004.md) 12 | * [LNPBP-6: PayTweak](lnpbp-0006.md) 13 | * [LNPBP-12: TapRet](lnpbp-0012.md) 14 | * [LNPBP-8: Single-use-seals](lnpbp-0008.md) 15 | * [LNPBP-10: TxO seals](lnpbp-0010.md) 16 | 17 | ## Bitcoin Protocol 18 | 19 | * [LNPBP-5: Short tx ids](lnpbp-0005.md) 20 | 21 | ## RGB 22 | 23 | * [LNPBP-13: RGB consensus](lnpbp-0013.md) 24 | * [RGB-20: Fungible assets](lnpbp-0020.md) 25 | * [RGB-21: NFT collectibles](lnpbp-0021.md) 26 | * [RGB-22: Digital identity](lnpbp-0022.md) 27 | * [RGB-23: Audit logs](lnpbp-0023.md) 28 | * [RGB-24: Domain names](lnpbp-0024.md) 29 | * [LNPBP-31: Standard contractum lib](lnpbp-0031.md) 30 | * [LNPBP-37: Invoices (rejected)](lnpbp-0037.md) 31 | 32 | ## Lightning network protocol 33 | 34 | * [LNPBP-46: LN derivations](lnpbp-0046.md) 35 | * [LNPBP-50: Bifrost P2P](lnpbp-0050.md) 36 | * [LNPBP-51: Bifrost channels](lnpbp-0051.md) 37 | * [LNPBP-53: Multipeer channels](lnpbp-0053.md) 38 | * [LNPBP-55: Bifrost HTLCs](lnpbp-0055.md) 39 | -------------------------------------------------------------------------------- /assets/lnpbp-0004.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/LNP-BP/LNPBPs/49387be4b301d9eb0de8a0f31c8389bb38a8fbeb/assets/lnpbp-0004.png -------------------------------------------------------------------------------- /assets/lnpbp-layers.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/LNP-BP/LNPBPs/49387be4b301d9eb0de8a0f31c8389bb38a8fbeb/assets/lnpbp-layers.png -------------------------------------------------------------------------------- /lnpbp-0001.md: -------------------------------------------------------------------------------- 1 | ``` 2 | LNPBP: 0001 3 | Vertical: Cryptographic primitives 4 | Title: Key tweaking: collision-resistant elliptic curve-based commitments 5 | Authors: Dr Maxim Orlovsky , 6 | Dr Rene Pickhardt, 7 | Federico Tenga, 8 | Martino Salvetti, 9 | Giacomo Zucco, 10 | Max Hillebrand, 11 | Christophe Diederichs, 12 | Yojoe 13 | Comments-URI: 14 | Status: Proposal 15 | Type: Standards Track 16 | Created: 2019-09-23 17 | Finalized: not yet 18 | License: CC0-1.0 19 | ``` 20 | 21 | - [Abstract](#abstract) 22 | - [Background](#background) 23 | - [Motivation](#motivation) 24 | - [Specification](#specification) 25 | - [Commitment procedure](#commitment-procedure) 26 | - [Verification procedure](#verification-procedure) 27 | - [Reveal procedure](#reveal-procedure) 28 | - [Compatibility](#compatibility) 29 | - [Rationale](#rationale) 30 | - [Commitments with a set of public keys, not a single key](#commitments-with-a-set-of-public-keys-not-a-single-key) 31 | - [Use of HMAC insead of simple hash](#use-of-hmac-insead-of-simple-hash) 32 | - [Public key serialization to 64 byte uncompressed form](#public-key-serialization-to-64-byte-uncompressed-form) 33 | - [Use of protocol tags](#use-of-protocol-tags) 34 | - [Protocol failures](#protocol-failures) 35 | - [Choice of elliptic curve generator point order `n` over field order `p`](#choice-of-elliptic-curve-generator-point-order-n-over-field-order-p) 36 | - [No nonce](#no-nonce) 37 | - [Reference implementation](#reference-implementation) 38 | - [Acknowledgements](#acknowledgements) 39 | - [References](#references) 40 | - [License](#license) 41 | - [Appendix A. Test vectors](#appendix-a-test-vectors) 42 | - [1. Correct test vectors](#1-correct-test-vectors) 43 | - [1.1. Zero-length message](#11-zero-length-message) 44 | - [1.2. Message consisting of a single zero byte](#12-message-consisting-of-a-single-zero-byte) 45 | - [1.3. Message of text string `test`](#13-message-of-text-string-test) 46 | - [1.4. Binary messsage, hex encoding (little-endian byte order)](#14-binary-messsage-hex-encoding-little-endian-byte-order) 47 | - [1.5. Keyset changes](#15-keyset-changes) 48 | - [2. Invalid test vectors](#2-invalid-test-vectors) 49 | - [3. Edge cases: protocol failures](#3-edge-cases-protocol-failures) 50 | 51 | 52 | ## Abstract 53 | 54 | Cryptographic commitments embedded into bitcoin transactions is a widely-used 55 | practice. It's application include timestamping [1], single-use seals [2], 56 | pay-to-contract settlement schemes [3], sidechains [4], blockchain anchoring 57 | [5], Taproot, Graftroot proposals [6, 7, 8], Scriptless scripts [9] and many 58 | others. Nevertheless, existing ways of creating commitments have never been 59 | standardized with best practices and do not commit to the exact protocol or 60 | commitment scheme used. They are also inapplicable to situations where multiple 61 | public keys are present in some output: how to deterministically detect which 62 | key is holding the commitment. 63 | 64 | This work proposes a standardization for cryptographic commitments that utilize 65 | the homomorphic properties of the `Secp256k1` elliptic curve (EC) and allows to 66 | commit to arbitrary data using an EC public key or a set of EC public keys 67 | from the `Secp256k1` curve in a deterministic and safe way. 68 | 69 | 70 | ## Background 71 | 72 | Cryptographic commitments represent a way to commit to some message without 73 | revealing it. The procedure consists of two phases, **commit** and **reveal**. 74 | In the *commit* phase, a party (**committer**), willing to prove its knowledge 75 | of some message, computes a *cryptographic hash function* over that message 76 | producing a message **digest**, which can be provided to other party(ies). In 77 | the *reveal* phase, the *committer* reveals the actual message and each party 78 | accessing it may check that its hash is equal to the originally provided 79 | *digest*. 80 | 81 | Key tweaking is a procedure for creation of a cryptographic commitment to some 82 | **message** using elliptic curve properties. The procedure uses the discrete log 83 | problem (DLP) as a proof of existence & knowledge of certain information about 84 | the message by some party (Alice) without exposing the original message. This is 85 | done by adding to a public key, for which Alice knows the corresponding private 86 | key, a hash of the message multiplied on the generator point `G` of the elliptic 87 | curve. This produces a **tweaked** public key, containing the commitment. At 88 | a later time Alice may prove her past knowledge of the original message (at the 89 | time when the commitment was created) by providing a signature corresponding to 90 | the original public key and the message itself. 91 | 92 | The main advantage of the public key tweak procedure is the fact that a tweaked 93 | key, or a corresponding signature, can't be distinguished from any other public 94 | keys or signatures; this property allows to hide the actual commitment in such 95 | a way that it can only be known to those parties which have knowledge of the 96 | secrets: the original public and/or key pair **and** a message. 97 | 98 | This type of commitment was originally proposed as a part of the *pay to 99 | contract* concept by Ilja Gerhardt and Timo Hanke in [1] and later used by 100 | Eternity Wall [2] for the same purpose. However, these proposals were arguably 101 | vulnerable to length-extension attacks and, more importantly, were not 102 | applicable to scenarios when multiple public keys are used (for instance, 103 | multi-signature bitcoin transaction outputs). These problems were fixed as a 104 | part of the sidechain-design efforts by Blockstream [3], which proposed to 105 | utilize a HMAC function and also introduced a nonce in the concept. 106 | 107 | Here we propose a standardization of the algorithm based on the original 108 | Eternity Wall and Blockstream work, enhanced with Pieter Wuille's Tagged Hashes 109 | procedure, coming from a specification on Schnorr signatures in Bitcoin [4], 110 | also used in the Taproot proposal [5]. This procedure prevents cross-protocol 111 | collisions, such that the original message's byte sequence can't be 112 | reinterpreted under another protocol. 113 | 114 | ## Motivation 115 | 116 | Publication of cryptographic commitments to the Bitcoin blockchain is a widely 117 | used mechanism, allowing timestamping of the commitment: it can be used to prove 118 | the fact that some information was known before a certain period in time without 119 | revealing the actual information. Use of elliptic curve homomorphic properties 120 | allows to perform such commitments without increasing the size of the 121 | transaction, by leveraging existing transaction outputs and not polluting 122 | blockchain space with excessive OP_RETURNs. However, as of today, there is no 123 | single standard for such commitments. While different practices for that purpose 124 | exist (see [1, 2, 3]), they contain multiple collision risks, such as the 125 | possibility of length-extension attacks and cross-protocol replay attacks. Or 126 | they can't be applied in situations where multiple public keys are used ( 127 | multi-signature or custom bitcoin scripts). This standard combines existing best 128 | practices into a single algorithm, that avoids all of those issues. 129 | 130 | 131 | ## Specification 132 | 133 | ### Commitment procedure 134 | 135 | For a given message `msg`, a list of public keys from the `Secp256k1` curve 136 | `P* := {P1, P2, ..., Pn}`, `n > 0`, with a selected original public key `Po` 137 | from this list (`Po ∈ P*`), and a protocol-specific `tag` known to both parties, 138 | the **commit procedure** runs as follows: 139 | 140 | 1. Reduce list `P*` to a set of unique public keys `P`, by removing all 141 | duplicate public keys from the list. 142 | 2. Compute sum `S` of all unique public keys in set `P`; fail the protocol if 143 | an overflow over elliptic curve generator point order happens during the 144 | procedure. 145 | 3. Construct a byte string `lnpbp1_msg`, composed of the original message 146 | prefixed with a single SHA256 hash of `LNPBP1` string and a single SHA256 147 | hash of the protocol-specific `tag`: 148 | `lnpbp1_msg = SHA256("LNPBP1") || SHA256(tag) || msg` 149 | 4. Serialize the aggregated public key `S` into a 64 byte array `S*` of 150 | uncompressed coordinates x and y in big-endian order and use `S*` to 151 | authenticate `lnbp1_msg` via HMAC-SHA256. The resulting value is named 152 | the **tweaking factor** `f`: 153 | `f = HMAC-SHA256(lnpbp1_msg, S*)` 154 | 5. Make sure that the tweaking factor is less than the order `n` of a generator 155 | point of the used elliptic curve, such that no overflow can happen when it is 156 | added to the original public key. If the order is exceeded, fail the protocol 157 | indicating the reason of failure. 158 | 6. Multiply the tweaking factor `f` on the used elliptic curve generator point 159 | `G`: `F = G * f` 160 | 7. Check that the result of step 6 is not equal to the point-at-infinity; 161 | otherwise fail the protocol, indicating the reason of failure, such that 162 | the protocol may be run with another initial public key set `P'`. 163 | 8. Add the two elliptic curve points: the original public key `Po` and the 164 | point `F`, derived from the tweaking-factor. This will result in a tweaked 165 | public key `T`: `T = Po + F`. Check that the result is not equal to the 166 | point-at-infinity of the elliptic curve or fail the protocol otherwise, 167 | indicating the reason of failure, such that the protocol may be run with 168 | another initial public key list `P*'`. 169 | 170 | The final formula for the commitment is: 171 | `T = Po + G * HMAC-SHA256(SHA256("LNPBP1") || SHA256(tag) || msg, S*)` 172 | 173 | ### Verification procedure 174 | 175 | **Verification procedure** for the commitment (i.e. tweaked public key `T`) can 176 | be performed with the provision of the list of public keys `P*`, 177 | the original public key `Po` and the message `msg` 178 | (assuming that the verifying party is aware of the protocol-specific `tag` 179 | and `LNPBP1` tag) and runs as follows: 180 | 181 | 1. Make sure that the provided tweaked public key `T` lies on the elliptic curve 182 | and is not equal to the point at infinity. 183 | 2. Compute 184 | `T' = Po + G * HMAC-SHA256(SHA256("LNPBP1") || SHA256(tag) || msg, S*)` 185 | repeating the *commitment procedure* according to the rules above. 186 | 3. Make sure that `T' = T` and report verification success; otherwise report 187 | verification failure. 188 | 189 | ### Reveal procedure 190 | 191 | Thus, **reveal data** required for the commitment verification constists of: 192 | 193 | 1. Original message `msg` 194 | 2. Tweaked public key value `T` 195 | 3. Original set of public keys `P` and a key `Po` from that set. 196 | 197 | The used protocol tag `tag` must be known to all parties participating in the 198 | protocol. 199 | 200 | 201 | ## Compatibility 202 | 203 | The proposed procedure should be compatible with previously-created 204 | pay-to-contract-style commitments based on SHA256 hashes under the assumption of 205 | SHA256 collision resistance. Utilization of a double tagged hash protocol prefix 206 | guarantees randomness in the first 64 bytes of the resulting tweaking string 207 | `lnpbp1_msg`, reducing probability for these bytes to be interpreted as a 208 | correct message under any of the previous standards. 209 | 210 | The procedure is well compliant with Taproot SegWit v1, since it operates with 211 | a sum of the original public keys, and the Taproot intermediate key is a sum of 212 | all used public keys, so it can represent a correct input for the protocol. 213 | 214 | The tweaked procedure may result in a public key that may, or may not have its 215 | *y* coordinate being a quadratic residue (in terms of BIP-340 [4]). This may 216 | present a compatibility issue for using this scheme in 217 | Taproot/Schnorr-enabled outputs and protocols. Nevertheless, this issue may 218 | be mitigated by running the procedure a second time and replacing the 219 | original public key with its own negation, if the resulting tweaked version 220 | was not square. 221 | 222 | The proposal relies on a tagged hash prefix similar to the one used in 223 | BIP-340, [4], which helps to prevent protocol collisions. 224 | 225 | 226 | ## Rationale 227 | 228 | ### Commitments with a set of public keys, not a single key 229 | 230 | The protocol was designed to support commitments to multiple public keys in 231 | order to be usable with non-P2(W)PK outputs. For instance, with Lightning 232 | network all outputs in the commitment transaction are non-P2WPK, so all existing 233 | key tweaking schemes are not usable within LN structure. 234 | 235 | ### Use of HMAC insead of simple hash 236 | 237 | Reason: prevention of length-extension attacks 238 | 239 | As this protocol aims to be a generic scheme, the message `msg` can be of any 240 | length. If we would just use a simple hash (e.g. SHA256), users of `LNPBP-1` 241 | could **potentially** be vulnerable to length-extension attacks, if they are not 242 | careful. To be on the safe side, we use HMAC-SHA256, which is resistant to 243 | length-extension attacks, but computationally more expensive. However, this 244 | protocol aims to be used in client-side validation applications primarily and 245 | should therefore run many orders of magnitude less often then complete 246 | validatation of all public blockchain data. The computational overhead of HMAC 247 | on a client node is therefore considered negligible, for the targeted use cases. 248 | 249 | ### Public key serialization to 64 byte uncompressed form 250 | 251 | Reason: HMAC needs a byte array as input 252 | 253 | HMAC requires a byte array as input for the `key` argument to authenticate a 254 | message. This `key` is not intended to be an EC key, it can be anything. Its 255 | purpose is to add entropy to the resulting hash value to counter length attacks 256 | on the underlying message. 257 | 258 | We use HMAC's `key` argument for two purposes: 259 | 1. Commit the message `msg` to a specific public key `S`. 260 | 2. As entropy for the security of HMAC-SHA256 against length extension attacks. 261 | 262 | For the serialization of the public key `S`, we rely on the *de facto* standard 263 | format for uncompressed public keys in Bitcoin, which is followed by libraries 264 | like [rust-secp256k1](https://docs.rs/secp256k1/0.20.1/src/secp256k1/key.rs.html#290-306). 265 | However, this results in a 65 byte array with the first byte being the prefix 266 | having the value `0x04`, denoting an uncompressed public key. However, the first 267 | byte doesn't add any entropy and a `key` larger than 64 byte causes HMAC-SH256 268 | to do an additional round of hashing. Therefore, we use `rust-secp256k1`' 269 | s `key.serialize_uncompressed()` function, but strip the first byte from the 270 | resulting value, so we end up with a 64 byte array of: 271 | 272 | - 32 bytes representing the x coordinate in big-endian order, 273 | - followed by 32 bytes representing the y coordinate in big-endian order. 274 | 275 | ### Use of protocol tags 276 | 277 | Reason: prevention of cross-protocol collision attacks 278 | 279 | The use of protocol-specific, double tagged hashes was originally proposed by 280 | Peter Wuille in [4] and [5] in order to prevent potential replay-attacks for 281 | interpreting messages under different protocols. The choice of a duplicate 282 | SHA256 prefix hash was made according to Peter Wuille because it is not yet 283 | used in any existing bitcoin protocol, which increases compatibility and reduces 284 | chances of collisions with existing protocols. 285 | 286 | ### Protocol failures 287 | 288 | The protocol may fail during some of the **commitment** procedure steps: 289 | 290 | * when the *tweaking factor* `f` exceeds the order `n` of the generator 291 | point `G` for the selected elliptic curve. 292 | * when the multiplication of the Secp256k1 generator point `G` on the *tweaking 293 | factor* `f` results in `F` being equal to the point at infinity. 294 | * when the summation of the members of public key set `P` at any stage, or the 295 | addition of the point `F` with the original public key `Po`, results in 296 | the point at infinity. 297 | 298 | The probabilities of these failures are infinitesimal; for instance the 299 | probability of the SHA256 hash value of a random message exceeding `G` order `n` 300 | is `(2^256 - n) / n`, which is many orders of magnitude less than the 301 | probability of a CPU failure. The probability of the second or third failure is 302 | even lower, since the point at infinity may be obtained only if `F` is equal to 303 | `-G` or `-P`, i.e. the probability of private key collision, equal to the 304 | inverse of Secp256k1 curve generator point order `n`. The only reason why this 305 | kind of failure may happen is when the original public key set was forged in a 306 | way that some of its keys are equivalent to the negation of other keys. 307 | 308 | These cases may be ignored by a protocol user -- or, alternatively, in case of 309 | the protocol failure the user may change `P`'s value(s) and re-run the protocol. 310 | 311 | Protocol failures during the verification procedure may happen only during its 312 | repetition of the original commitment. This means that the original commitment 313 | is invalid, since it was not possible to create a commitment with the given 314 | original data. Thus, such failure will simply indicate a negative result of the 315 | verification procedure. 316 | 317 | ### Choice of elliptic curve generator point order `n` over field order `p` 318 | 319 | While it is possible to ignore elliptic curve overflow over its order `n` during 320 | public key addition, since it does not provide a security risk for the 321 | commitment, it was chosen to stick to this scheme because of the following: 322 | 323 | * Current implementation of Secp256k1 library (libsecp256k1) fails on overflow 324 | during key tweaking procedure. Since this library is widely used in the 325 | Bitcoin ecosystem (and Bitcoin Core), it is desirable to maintain LNPBP-1 326 | compatible with this functionality. 327 | * Probability of an overflow is still infinissimal, being comparable to 328 | probability of `3.7*10^-66`, for a tweaking factor not fitting into the 329 | elliptic curve field order `p`. 330 | 331 | ### No nonce 332 | 333 | In certain circumstances a simple hash based commitment might be vulnerable to 334 | brute force vocabulary attacks, if the syntax and semantics of the invoking 335 | protocol are known to the attacker. This is usually countered with adding 336 | additional entropy (e.g. a nonce) to each hash. In our case the public key `S` 337 | already provides enough entropy, which - when added via HMAC-SHA256 to the 338 | whole `msg` – sufficiently counters such vocabulary attacks, preventing an 339 | attacker from successfully guessing the original message, even for short and 340 | standard messages. 341 | 342 | 343 | ## Reference implementation 344 | 345 | ```rust 346 | use std::collections::BTreeSet; 347 | 348 | use bitcoin::hashes::{sha256, Hash, HashEngine, Hmac, HmacEngine}; 349 | use bitcoin::secp256k1; 350 | 351 | lazy_static! { 352 | /// Global Secp256k1 context object 353 | pub static ref SECP256K1: secp256k1::Secp256k1 = 354 | secp256k1::Secp256k1::new(); 355 | } 356 | 357 | lazy_static! { 358 | /// Single SHA256 hash of "LNPBP1" string according to LNPBP-1 acting as a 359 | /// prefix to the message in computing tweaking factor 360 | pub static ref LNPBP1_HASHED_TAG: [u8; 32] = { 361 | sha256::Hash::hash(b"LNPBP1").into_inner() 362 | }; 363 | } 364 | 365 | /// Deterministically-organized set of all public keys used by this mod 366 | /// internally. 367 | type Keyset = BTreeSet; 368 | 369 | /// Errors that may happen during LNPBP-1 commitment procedure or because of 370 | /// incorrect arguments provided to [`commit()`] function. 371 | #[derive(Clone, Copy, PartialEq, Eq, Debug, Display, Error, From)] 372 | #[display(doc_comments)] 373 | pub enum Error { 374 | /// Keyset must include target public key, but no target key found it 375 | /// the provided set. 376 | NotKeysetMember, 377 | 378 | /// Elliptic curve point addition resulted in point in infinity; you 379 | /// must select different source public keys 380 | SumInfiniteResult, 381 | 382 | /// LNPBP-1 commitment either is outside of Secp256k1 order `n` (this event 383 | /// has negligible probability <~2^-64), or, when added to the provided 384 | /// keyset, results in point at infinity. You may try with a different 385 | /// source message or public keys. 386 | InvalidTweak, 387 | } 388 | 389 | /// Function performs commitment procedure according to LNPBP-1. 390 | pub fn commit( 391 | // We automatically reduce set to unique keys by using `BTreeSet` in the 392 | // underlying `Keyset` data type 393 | keyset: &mut Keyset, 394 | target_pubkey: &mut secp256k1::PublicKey, 395 | // We take a hashed version of the protocol tag for computation efficiency 396 | // so it can be used in multiple commitments without hash re-computing 397 | protocol_tag: &sha256::Hash, 398 | message: &impl AsRef<[u8]>, 399 | ) -> Result<[u8; 32], Error> { 400 | if !keyset.remove(target_pubkey) { 401 | return Err(Error::NotKeysetMember); 402 | } 403 | 404 | let pubkey_sum = keyset 405 | .iter() 406 | .try_fold(target_pubkey.clone(), |sum, pubkey| sum.combine(pubkey)) 407 | .map_err(|_| Error::SumInfiniteResult)?; 408 | 409 | let mut hmac_engine = 410 | HmacEngine::::new(&pubkey_sum.serialize_uncompressed()); 411 | 412 | hmac_engine.input(&LNPBP1_HASHED_TAG[..]); 413 | hmac_engine.input(&protocol_tag[..]); 414 | hmac_engine.input(&sha256::Hash::hash(message.as_ref())); 415 | 416 | // Producing and storing tweaking factor in container 417 | let hmac = Hmac::from_engine(hmac_engine); 418 | let tweaking_factor = *hmac.as_inner(); 419 | 420 | // Applying tweaking factor to public key 421 | target_pubkey 422 | .add_exp_assign(&SECP256K1, &tweaking_factor[..]) 423 | .map_err(|_| Error::InvalidTweak)?; 424 | 425 | keyset.insert(target_pubkey.clone()); 426 | 427 | // Returning tweaked public key 428 | Ok(tweaking_factor) 429 | } 430 | 431 | /// Function verifies commitment created according to LNPBP-1. 432 | pub fn verify( 433 | verified_pubkey: secp256k1::PublicKey, 434 | original_keyset: &Keyset, 435 | mut target_pubkey: secp256k1::PublicKey, 436 | protocol_tag: &sha256::Hash, 437 | message: &impl AsRef<[u8]>, 438 | ) -> bool { 439 | match commit( 440 | &mut original_keyset.clone(), 441 | &mut target_pubkey, 442 | protocol_tag, 443 | message, 444 | ) { 445 | // If the commitment function fails, it means that it was not able to 446 | // commit with the provided data, meaning that the commitment was not 447 | // created. Thus, we return that verification have not passed, and not 448 | // a error. 449 | Err(_) => return false, 450 | 451 | // Verification succeeds if the commitment procedure produces public key 452 | // equivalent to the verified one 453 | Ok(_) => target_pubkey == verified_pubkey, 454 | } 455 | } 456 | ``` 457 | 458 | ## Acknowledgements 459 | 460 | Authors would like to thank: 461 | * Alekos Filini for his initial work on the commitment schemes as a part of 462 | early RGB effort [6]; 463 | * ZmnSCPxj for bringing attention to possible Taproot-compatibility issues [7]; 464 | * Peter Wuille for a proposal on the tagged hashes, preventing reply-type of 465 | attacks [5]; 466 | * Authors of Sidechains whitepaper for paying attention to the potential 467 | length-extension attacks and the introduction of HMAC-based commitments to the 468 | original public key [3]; 469 | * Dr Christian Decker for pointing out on Lightning Network incompatibility with 470 | all existing cryptographic commitment schemes. 471 | 472 | 473 | ## References 474 | 475 | 1. Ilja Gerhardt, Timo Hanke. Homomorphic Payment Addresses and the 476 | Pay-to-Contract Protocol. arXiv:1212.3257 \[cs.CR\] 477 | 478 | 2. [Eternity Wall's "sign-to-contract" article](https://blog.eternitywall.com/2018/04/13/sign-to-contract/) 479 | 3. Adam Back, Matt Corallo, Luke Dashjr, et al. Enabling Blockchain Innovations 480 | with Pegged Sidechains (commit5620e43). Appenxix A. 481 | . 482 | 4. Pieter Wuille. Schnorr Signatures for secp256k1. 483 | 484 | 5. Pieter Wuille. Taproot: SegWit version 1 spending rules. 485 | 486 | 6. RGB Protocol Specification, version 0.4. "Commitment Scheme" section. 487 | 488 | 7. 489 | 490 | 491 | ## License 492 | 493 | This document is licensed under the Creative Commons CC0 1.0 Universal license. 494 | 495 | 496 | ## Appendix A. Test vectors 497 | 498 | All tests done with protocol-specific `tag` value equal to `ProtoTag`. Values 499 | for public keys are given in standard compressed pre-Shorr's Bitcoin encoding 500 | format; values for tweaking factors are given in little-endian byte order. 501 | 502 | ### 1. Correct test vectors 503 | 504 | #### 1.1. Zero-length message 505 | 506 | 1) Single public key #1 507 | - Original public key: 508 | `03ab1ac1872a38a2f196bed5a6047f0da2c8130fe8de49fc4d5dfb201f7611d8e2` 509 | - Tweaked public key with the commitment: 510 | `025d69da2890f85928cb492545a13bd6782168b39d52e69fadd1d3fcb3b1bf9268` 511 | - Tweaking factor value: 512 | `9ff4c975950ec102b5eb39df2f976948b2c1a6e3f92ef5bf5af0e1241380dbcf` 513 | 2) Single public key #2 514 | - Original public key: 515 | `039729247032c0dfcf45b4841fcd72f6e9a2422631fc3466cf863e87154754dd40` 516 | - Tweaked public key with the commitment: 517 | `032fdf6c4023453b869294ddd28684f98fcaca604c2cd734c8dd64b8520547b0b4` 518 | - Tweaking factor value: 519 | `11db141cfe0143f60e9e9f9db478630033fc65eb4f682905e9044c87869459a5` 520 | 3) Set of five public keys 521 | - Original public key: 522 | `02383b24fbea14253ac37b0d421263b716a34192516ea0837021a40b5966a06f5e` 523 | - Key set: 524 | * `02383b24fbea14253ac37b0d421263b716a34192516ea0837021a40b5966a06f5e` 525 | * `025b178dfaa49e959033cc2ba8b06d78b8b9242496329a574eb8e2b4fad4f88b6f` 526 | * `03ec8b1cf223dc3cd8eb6d7c5fb11735e983c234b69271a3decad8bbfb2b997994` 527 | * `021ce48f4b53257be01ccb237986c1b9677a9e698fb962b108d6b2fbdc836727d8` 528 | * `0388a0fc8d3ba29a93ad07dbad37a6d4b87f2e2672b15d331d1f6bf4f2c9119ffe` 529 | - Tweaked public key with the commitment: 530 | `03c153beef57c268ee9a2a68940f2aa7b052ce14c676a27cfe5010c53b41476238` 531 | - Tweaking factor value: 532 | `a18417ae90cf36a45311ccc3a911a8ebb1b7afa02c6d79d1d1bd08b2abf67e94` 533 | 4). Set of same five public keys, using different original key from the set 534 | - Original public key: 535 | `025b178dfaa49e959033cc2ba8b06d78b8b9242496329a574eb8e2b4fad4f88b6f` 536 | - Key set: 537 | * `02383b24fbea14253ac37b0d421263b716a34192516ea0837021a40b5966a06f5e` 538 | * `025b178dfaa49e959033cc2ba8b06d78b8b9242496329a574eb8e2b4fad4f88b6f` 539 | * `03ec8b1cf223dc3cd8eb6d7c5fb11735e983c234b69271a3decad8bbfb2b997994` 540 | * `021ce48f4b53257be01ccb237986c1b9677a9e698fb962b108d6b2fbdc836727d8` 541 | * `0388a0fc8d3ba29a93ad07dbad37a6d4b87f2e2672b15d331d1f6bf4f2c9119ffe` 542 | - Tweaked public key with the commitment: 543 | `03a224242255c9a024d4e2723c17faa09082b60bf91cea23ce558c9cff3a9627bf` 544 | - Tweaking factor value: 545 | `a18417ae90cf36a45311ccc3a911a8ebb1b7afa02c6d79d1d1bd08b2abf67e94` 546 | 547 | #### 1.2. Message consisting of a single zero byte 548 | 549 | 1) Single public key #1 550 | - Original public key: 551 | `032564fe9b5beef82d3703a607253f31ef8ea1b365772df434226aee642651b3fa` 552 | - Tweaked public key with the commitment: 553 | `0285f7e0a8cdd801e5fbf84602e84de46a036ba47230b2c37f7767a496aeb4e4c5` 554 | - Tweaking factor value: 555 | `5639647143cb9dc78aa5d251694fcc053f3887cf27b13750f72a42ef04f7bde1` 556 | 2) Single public key #2 557 | - Original public key: 558 | `0289637f97580a796e050791ad5a2f27af1803645d95df021a3c2d82eb8c2ca7ff` 559 | - Tweaked public key with the commitment: 560 | `03fcd2e4c31622fcf9fef43e70dabf1daf8abae5685b15125ba6a0e444783c5f0e` 561 | - Tweaking factor value: 562 | `7551544f39a2c3a4d65c34e5915702a825ccbbb914ac581389cbbd98869b4e48` 563 | 3) Set of five public keys 564 | - Original public key: 565 | `03ff3d6136ffac5b0cbfc6c5c0c30dc01a7ea3d56c20bd3103b178e3d3ae180068` 566 | - Key set: 567 | * `03ff3d6136ffac5b0cbfc6c5c0c30dc01a7ea3d56c20bd3103b178e3d3ae180068` 568 | * `02308138e71be25e092fdc9da03d5357421bc7280356a1381a6186d63a0ca8dd7f` 569 | * `03575fc4e82a6deb65d1e5750c85b6862f6ec009281992e206c0dcc568866a3fb1` 570 | * `0271efa4e26a4179e112860b88fc98658a4bdbc59c7ab6d4f8057c35330c7a89ee` 571 | * `0289637f97580a796e050791ad5a2f27af1803645d95df021a3c2d82eb8c2ca7ff` 572 | - Tweaked public key with the commitment: 573 | `0289d1313a940f7b668804e223662edce2a7138914894607cd4bf641cc584936f3` 574 | - Tweaking factor value: 575 | `87a5728772e0d14c9938c50ab29b215d5a0d9f59be7b40d16cc4bcac22e027b1` 576 | 577 | #### 1.3. Message of text string `test` 578 | 579 | 1) Single public key #1 580 | - Original public key: 581 | `0271efa4e26a4179e112860b88fc98658a4bdbc59c7ab6d4f8057c35330c7a89ee` 582 | - Tweaked public key with the commitment: 583 | `02605b2400618ca83f563e997da456c7ae99df9b38a7939ead5bc8e5b8b29f5d45` 584 | - Tweaking factor value: 585 | `7090ad6b1c6093e025c3b2f1607f9aea65449139a08ee773c61990e9b6e966d3` 586 | 2) Single public key #2 587 | - Original public key: 588 | `039729247032c0dfcf45b4841fcd72f6e9a2422631fc3466cf863e87154754dd40` 589 | - Tweaked public key with the commitment: 590 | `032bf20cd8539c2f3154fbae01e64ea3a492bb2431080c86c3f942571f9635ece7` 591 | - Tweaking factor value: 592 | `214570a96bf958124eea266593fd9daed3ee357283b4f89613f99a5d8ac8910a` 593 | 3) Set of five public keys 594 | - Original public key: 595 | `03f72a42169a0475c4a342f8da97a1c0bce830183efecd0a3d81637b05d7c0d81a` 596 | - Key set: 597 | * `03f72a42169a0475c4a342f8da97a1c0bce830183efecd0a3d81637b05d7c0d81a` 598 | * `02383b24fbea14253ac37b0d421263b716a34192516ea0837021a40b5966a06f5e` 599 | * `025b178dfaa49e959033cc2ba8b06d78b8b9242496329a574eb8e2b4fad4f88b6f` 600 | * `03ec8b1cf223dc3cd8eb6d7c5fb11735e983c234b69271a3decad8bbfb2b997994` 601 | * `03f0d2dd91c4bcb630616ea9e3b2e95ec7f6f431d81bd627b62d04ac81b91af8c7` 602 | - Tweaked public key with the commitment: 603 | `02da1eea3c29872e9d770efe66bfde4ad2b361f0644e81d1b4d95338eb75b813f1` 604 | - Tweaking factor value: 605 | `63ea2d88f3b3969573ef530132989a9281cb499d6bfda4bfc0ade2cbd7bdf26e` 606 | 607 | #### 1.4. Binary messsage, hex encoding (little-endian byte order) 608 | 609 | Original message for the all cases in this section: `[0xde, 0xad, 0xbe, 0xef]` 610 | 611 | 1) Single public key #1 612 | - Original public key: 613 | `0352045bcc58e07124a375ea004b3508ac80e625da2106c74f5cb023498de0545f` 614 | - Tweaked public key with the commitment: 615 | `0357f2619c2805794ef65ab7ea7a349f4c1be4cc3f576584f8270f06e830f33e36` 616 | - Tweaking factor value: 617 | `14703d20ec36407889e5d7546d59edbfac4e69f211759a1bd783aa65ee1ae36c` 618 | 2) Single public key #2 619 | - Original public key: 620 | `02a153dfe913310b0949de7976146349b95a398cb0de1047290b0f975c172ad712` 621 | - Tweaked public key with the commitment: 622 | `0388bcce7da0bc2edd2ff553134c7ae109232f30bda347b39adca6d0d379a86315` 623 | - Tweaking factor value: 624 | `627573dc2a7a57e5fe83f415d5f9d0e9ee78e51fd7990e926f09e9b8fe6a12b3` 625 | 3) Set of five public keys 626 | - Original public key: 627 | `03a9c44838c0ac7417497f770ebd013c91ac715665ec01e740be0e14f44cab2474` 628 | - Key set: 629 | * `03a9c44838c0ac7417497f770ebd013c91ac715665ec01e740be0e14f44cab2474` 630 | * `03ad42e3bd69e30d32d088173e02b9d1cd00e4f7d945aad5c1a6c9439fdc8c5e80` 631 | * `03713e80a43b19d6f7b46ec5a474e86c8f5769f85f4fcb9a0be76d095b1e2b7981` 632 | * `025d9e055d7e7a85f097e981779c6e1c40d74b0563e631128c06623609b99a8f87` 633 | * `0323e518565f25038f16fdf7686ed4dd9a59b02ef95d2d7aa5be948f38701376b7` 634 | - Tweaked public key with the commitment: 635 | `02d739f0fdd7bc395482c52e1ef1547a3c6fc6e2f1393430e74c55624f26023bd7` 636 | - Tweaking factor value: 637 | `d5218633603181303d06320365fc84d06e0c2bb36c0989ee678a57b799f457a7` 638 | 639 | #### 1.5. Keyset changes 640 | 641 | Commitment creation and validation filters repeated keys and does not depend 642 | on the key order (since elliptic curve addition is commutative) 643 | 644 | 1) Set of five public keys containing duplicated keys 645 | - Message (binary string, little-endian byte order): 646 | `[0x00, 0xde, 0xad, 0xbe, 0xef]` 647 | - Original public key: 648 | `025d9e055d7e7a85f097e981779c6e1c40d74b0563e631128c06623609b99a8f87` 649 | - Key set: 650 | * `03a9c44838c0ac7417497f770ebd013c91ac715665ec01e740be0e14f44cab2474` 651 | * `03ad42e3bd69e30d32d088173e02b9d1cd00e4f7d945aad5c1a6c9439fdc8c5e80` 652 | * `03ad42e3bd69e30d32d088173e02b9d1cd00e4f7d945aad5c1a6c9439fdc8c5e80` 653 | * `03713e80a43b19d6f7b46ec5a474e86c8f5769f85f4fcb9a0be76d095b1e2b7981` 654 | * `025d9e055d7e7a85f097e981779c6e1c40d74b0563e631128c06623609b99a8f87` 655 | * `0323e518565f25038f16fdf7686ed4dd9a59b02ef95d2d7aa5be948f38701376b7` 656 | * `025d9e055d7e7a85f097e981779c6e1c40d74b0563e631128c06623609b99a8f87` 657 | - Tweaked public key with the commitment: 658 | `027f07015596c7a3af8a1da9e4fe1de0695278f94278ce01534b7ac7a530b43399` 659 | - Tweaking factor value: 660 | `bc47cf269e70e5e654f3079f7316ddd988c529bf7d8c0efb0ec0759719afaeaa` 661 | 2) Set of five public keys in changed order 662 | - Message (binary string, little-endian byte order): 663 | `[0x00, 0xde, 0xad, 0xbe, 0xef]` 664 | - Original public key: 665 | `025d9e055d7e7a85f097e981779c6e1c40d74b0563e631128c06623609b99a8f87` 666 | - Key set: 667 | * `03713e80a43b19d6f7b46ec5a474e86c8f5769f85f4fcb9a0be76d095b1e2b7981` 668 | * `03a9c44838c0ac7417497f770ebd013c91ac715665ec01e740be0e14f44cab2474` 669 | * `025d9e055d7e7a85f097e981779c6e1c40d74b0563e631128c06623609b99a8f87` 670 | * `0323e518565f25038f16fdf7686ed4dd9a59b02ef95d2d7aa5be948f38701376b7` 671 | * `03ad42e3bd69e30d32d088173e02b9d1cd00e4f7d945aad5c1a6c9439fdc8c5e80` 672 | - Tweaked public key with the commitment: 673 | `027f07015596c7a3af8a1da9e4fe1de0695278f94278ce01534b7ac7a530b43399` 674 | - Tweaking factor value: 675 | `bc47cf269e70e5e654f3079f7316ddd988c529bf7d8c0efb0ec0759719afaeaa` 676 | 677 | ### 2. Invalid test vectors 678 | 679 | All these cases are cases for validation procedure, which must fail. 680 | 681 | 1) Case #1: commitment key created with a different original public key 682 | - Message: zero-length 683 | - Original public key: 684 | `03ab1ac1872a38a2f196bed5a6047f0da2c8130fe8de49fc4d5dfb201f7611d8e2` 685 | - Tweaked public key with the commitment: 686 | `02a8e7b5f006e3c96eb1e336d40a6956dd9c4889dbfb4542b50da0c90cd2ab64fd` 687 | 688 | 2) Case #2: original key and commitment are valid, but the message was different 689 | - Message: `test*` 690 | - Original public key: 691 | `032564fe9b5beef82d3703a607253f31ef8ea1b365772df434226aee642651b3fa` 692 | - Tweaked public key with the commitment: 693 | `0240c2f382fc5335879c3607479c491dbd9bfb47d32c375f7d99e6d210a91f8780` 694 | 695 | 3) Case #3: commitment was created with correct message and original public key, 696 | but using different protocol tag 697 | - Message (binary string, little-endian byte order): 698 | `[0xde, 0xad, 0xbe, 0xef, 0x00]` 699 | - Original public key: 700 | `029a541ac6af794615935c34d088edc824c4433a83bdb5a781030c370111cf5b3a` 701 | - Tweaked public key with the commitment: 702 | `0304d89459380b9d8ff2ebaaf2e20f47ce92dcf0b9dbfde9dbe866513a7819b79c` 703 | 704 | 4) Case #4: one of original public keys is absent 705 | - Message: 706 | `test` 707 | - Original public key: 708 | `03f72a42169a0475c4a342f8da97a1c0bce830183efecd0a3d81637b05d7c0d81a` 709 | - Key set: 710 | * `03f72a42169a0475c4a342f8da97a1c0bce830183efecd0a3d81637b05d7c0d81a` 711 | * `02383b24fbea14253ac37b0d421263b716a34192516ea0837021a40b5966a06f5e` 712 | * `03ec8b1cf223dc3cd8eb6d7c5fb11735e983c234b69271a3decad8bbfb2b997994` 713 | * `03f0d2dd91c4bcb630616ea9e3b2e95ec7f6f431d81bd627b62d04ac81b91af8c7` 714 | - Tweaked public key with the commitment: 715 | `02da1eea3c29872e9d770efe66bfde4ad2b361f0644e81d1b4d95338eb75b813f1` 716 | 717 | 718 | ### 3. Edge cases: protocol failures 719 | 720 | Keyset constructed of a key and it's own negation. 721 | 722 | - Expected result: 723 | must fail commitment procedure with error indicating that the operation 724 | resulted at the point-at-infinity. 725 | - Message: 726 | `test` 727 | - Original public key: 728 | `0218845781f631c48f1c9709e23092067d06837f30aa0cd0544ac887fe91ddd166` 729 | - Key set: 730 | * `0218845781f631c48f1c9709e23092067d06837f30aa0cd0544ac887fe91ddd166` 731 | * `0318845781f631c48f1c9709e23092067d06837f30aa0cd0544ac887fe91ddd166` 732 | -------------------------------------------------------------------------------- /lnpbp-0002.md: -------------------------------------------------------------------------------- 1 | ``` 2 | LNPBP: 0002 3 | Vertical: Bitcoin protocol 4 | Title: Deterministic embedding of cryptographic commitments into bitcoin 5 | transaction output 6 | Authors: Dr Maxim Orlovsky , 7 | Giacomo Zucco, 8 | Martino Salvetti, 9 | Federico Tenga, 10 | Sosthène 11 | Comments-URI: https://github.com/LNP-BP/lnpbps/issues/4 12 | Status: Proposal 13 | Type: Standards Track 14 | Created: 2019-10-27 15 | License: CC0-1.0 16 | ``` 17 | 18 | - [Abstract](#abstract) 19 | - [Background](#background) 20 | - [Motivation](#motivation) 21 | - [Design](#design) 22 | - [Specification](#specification) 23 | - [Commitment procedure](#commitment-procedure) 24 | - [Reveal procedure](#reveal-procedure) 25 | - [Verification procedure](#verification-procedure) 26 | - [Deterministic public key extraction from Bitcoin Script](#deterministic-public-key-extraction-from-bitcoin-script) 27 | - [Compatibility](#compatibility) 28 | - [Rationale](#rationale) 29 | - [Continuing support for P2PK outputs](#continuing-support-for-p2pk-outputs) 30 | - [Support OP_RETURN type of outputs](#support-op_return-type-of-outputs) 31 | - [Unification with OP_RETURN-based commitments](#unification-with-op_return-based-commitments) 32 | - [Custom serialization of public keys in OP_RETURN](#custom-serialization-of-public-keys-in-op_return) 33 | - [Support for pre-SegWit outputs](#support-for-pre-segwit-outputs) 34 | - [Committing to the sum of all public keys present in the script](#committing-to-the-sum-of-all-public-keys-present-in-the-script) 35 | - [Deterministic public key extraction for a Bitcoin script](#deterministic-public-key-extraction-for-a-bitcoin-script) 36 | - [Use of Taproot intermediate public key](#use-of-taproot-intermediate-public-key) 37 | - [Reference implementation](#reference-implementation) 38 | - [Acknowledgements](#acknowledgements) 39 | - [References](#references) 40 | - [License](#license) 41 | - [Appendix A. Test vectors](#appendix-a-test-vectors) 42 | - [1. Correct test vectors](#1-correct-test-vectors) 43 | - [2. Invalid test vectors](#2-invalid-test-vectors) 44 | - [3. Edge cases: protocol failures](#3-edge-cases-protocol-failures) 45 | 46 | 47 | ## Abstract 48 | 49 | The standard defines an algorithm for deterministic embedding and verification 50 | of cryptographic commitments based on elliptic-curve public key tweaking 51 | procedure defined in [LNPBP-1 standard](https://github.com/LNP-BP/LNPBPs/blob/master/lnpbp-0001.md) 52 | inside `scriptPubkey` script for existing types of Bitcoin transaction output. 53 | 54 | 55 | ## Background 56 | 57 | Cryptographic commitments embedded into bitcoin transactions is a widely-used 58 | practice. Its application include timestamping [1], single-use seals [2], 59 | pay-to-contract settlement schemes [3], sidechains [4], blockchain anchoring 60 | [5], Taproot, Graftroot proposals [6, 7, 8], Scriptless scripts [9] and many 61 | others. 62 | 63 | 64 | ## Motivation 65 | 66 | A number of cryptographic commitment (CC) use cases require the commitment to be 67 | present within non-P2(W)PK(H) outputs,which may contain multiple public keys and 68 | need a clear definition of how the public key that contain the commitment can be 69 | found within the bitcoin script itself. For instance, embedding CC into 70 | Lightning Network (LN) payment channel state updates in the current version 71 | requires the modification of an offered HTLC and received HTLC transaction 72 | outputs[10], and these transactions contain only a single P2WSH output. With the 73 | use of `option_anchor_outputs` [11] all outputs in the LN commitment transaction 74 | becomes P2WSH outputs, also leading to a requirement for a standard and secure 75 | way of making CC inside P2(W)SH outputs. 76 | 77 | At the same time, P2(W)SH and other non-standard outputs (like explicit bare 78 | script outputs, including OP_RETURN type) are not trivial to use for CC, since 79 | CC requires deterministic definition of the actual commitment case. Normally, 80 | one of the most secure and standard CC scheme uses homomorphic properties of the 81 | public keys [12]; however multiple public keys may be used within non-P2(W)PK(H) 82 | output. Generally, these outputs present a hash of the actual script, hiding the 83 | used public keys or their hashes. Moreover, it raises the question of how the 84 | public key within Bitcoin Script may be defined/detected, since it is possible 85 | to represent the public key in a number of different ways within bitcoin script 86 | itself (explicitly or by a hash, and it's not trivial to understand where some 87 | hash stands for a public key or other type of preimage data). All this raises a 88 | requirement to define a standard way and some best practices for CC in non-P2(W) 89 | PK(H) outputs. This proposal tries to address the issue by proposing a common 90 | standard on the use of public-key based CC [12] within all possible transaction 91 | output types. 92 | 93 | ## Design 94 | 95 | The protocol requires that exactly one public key of all keys present or 96 | referenced in `scriptPubkey` and `redeemScript` must contain the commitment 97 | (made with LNPBP-1 procedure) to a given message. This commitment is 98 | deterministically singular, i.e. it can be proven that there is no other 99 | alternative message that the given transaction output commits to under this 100 | protocol. The singularity is achieved by committing to the sum of all original 101 | (i.e. before the message commitment procedure) public keys controlling the 102 | spending of a given transaction output. Thus, the given protocol covers all 103 | possible options for `scriptPubkey` transaction output types. 104 | 105 | The commitment consists of the updated `scriptPubkey` value, which may be embed 106 | into the transaction output, and an **extra-transaction proof** (ETP), required 107 | for the verification of the commitment. The structure and information in the 108 | proof depends on the actual `scriptPubkey` type. 109 | 110 | The protocol includes an algorithm for deterministic extraction of public keys 111 | from a given Bitcoin script, based on Miniscript [16]. 112 | 113 | 114 | ## Specification 115 | 116 | ### Commitment procedure 117 | 118 | The **committing party**, having a message `msg`, must: 119 | 1. Collect all public keys instances (named **original public key set**) 120 | related to the given transaction output, defined as: 121 | - a single public key for P2PK, P2PKH, P2WPK, P2WPK/WSH-in-P2SH type 122 | of outputs; 123 | - If `OP_RETURN` `scriptPubkey` is used, it must contain a single public key 124 | serialized in BIP-340 xcoordonly form right after `OP_RETURN` opcode; for 125 | all other forms of `OP_RETURN` data algorithm must fail; 126 | - an internal public key for a Taproot output (P2TR); 127 | - all public keys from a `redeemScript` (for P2(W)SH and P2WSH-in-P2SH, 128 | which in case of SegWit is contained within `witnessScript`) or 129 | `scriptPubkey` (for custom bare script outputs), extracted according to the 130 | [algorithm](#deterministic-public-key-extraction-from-bitcoin-script). 131 | - In case of witness version > 1 the procedure must fail. 132 | Let's call this set of _n_ keys `P`. 133 | 2. Select a single public key `Po` from the set of the original public keys, 134 | which will contain the commitment. It is advised that the corresponding 135 | private key being controlled by the committing party, which will simplify 136 | future spending of the output. 137 | 3. Run [LNPBP-1 commitment procedure](https://github.com/LNP-BP/LNPBPs/blob/master/lnpbp-0001.md#commitment-procedure) 138 | on message `msg`, the set of original public keys `P`, the selected public 139 | key `Po` and a protocol-specific `tag`, provided by the upstream protocol 140 | using this standard. The procedure returns a tweaked public key `T`. 141 | 4. Construct necessary scripts and generate `scriptPubkey` of the required 142 | type. If OP_RETURN `scriptPubkey` format is used, it MUST be serialized 143 | according to the following rules: 144 | - only a single `OP_RETURN` code MUST be present in the `scriptPubkey` and it 145 | MUST be the first byte of it; 146 | - it must be followed by 32-byte push of the public key value `P` from the 147 | step 2 of the algorithm, serialized according to the rules from [15]; 148 | - if the tweaked public key serialized with bitcoin consensus serialization 149 | rules does not start with 0x02 as it's first (least significant) byte, the 150 | procedure must fail; or it may be repeated with a new public key picked at 151 | step 1. 152 | 5. Construct and store an **extra-transaction proof** (ETP), which structure 153 | depends on the generated `scriptPubkey` type: 154 | a) value of `Po`, corresponding to: 155 | * the original intermediary public key for V1 witness Taproot output; 156 | * single original public key used in the tweak procedure before the tweak 157 | was applied; 158 | b) deterministic script reconstruction data, i.e.: 159 | * untweaked `redeemScript` (for P2SH outputs), or `witnessScript` 160 | (for P2WSH SegWit v0 native or P2WSH-in-P2SH SegWit legacy outputs), 161 | constructed using set of the *original public keys*; 162 | * the "taptweak" hash (i.e. the tagged hash of the Merkle root of the 163 | TapScript branches) for v1 witness output (Taproot); 164 | * for other types of outputs no other data are required for the ETP. 165 | 166 | 167 | ### Reveal procedure 168 | 169 | The **reveal protocol** is usually run between the committing and verifying 170 | parties; however it may be used by the committing party to make the proofs 171 | of the commitment public. These proofs include: 172 | * `scriptPubkey` from the transaction output containing the commitment; 173 | * *original message* `msg` to which the *committing party* has committed; 174 | * *extra-transaction proof* (ETP), constructed at the 5th step of the 175 | [commitment protocol](#commitment); 176 | * (optional) proofs that the `scriptPubkey` is a part of a transaction 177 | included into the bitcoin chain containing the largest known amount of work at 178 | depth satisfying a *verifying party* security policy (these proofs may be 179 | reconstructed/verified by the verifying party itself using its trusted Bitcoin 180 | Core server); 181 | 182 | 183 | ### Verification procedure 184 | 185 | The verification process runs by repeating steps of the commitment protocol 186 | using the information provided during the *reveal phase* and verifying the 187 | results for their internal consistency; specifically: 188 | 1. Original public key set reconstruction: 189 | - if *extra-transaction proof* (ETP) provides script data (pt. 5.b from the 190 | commitment procedure) parse it according to deterministic key collection 191 | [algorithm](#deterministic-public-key-extraction-from-bitcoin-script) 192 | and collect all the original public keys from it; fail the verification 193 | procedure if parsing fails; 194 | - otherwise use an original public key provided as a part of ETP as a single- 195 | element set 196 | 2. Run LNPBP-1 verification procedure repeating step 3 from the commitment 197 | procedure, using original public key value from the *extra-transaction proof* 198 | 3. Construct `scriptPubkey'`, matching the type of the `scriptPubkey` in the 199 | transaction and matching *extra-transaction proof* data using the tweaked 200 | version of the public key in the same way as was perfomed at step 4 of the 201 | commitment procedure. If there can be multiple matching `scriptPubkey` types 202 | for a given data, construct a variant for each of them. 203 | 4. Make sure that one of the `scriptPubkey'` values generated at the previous 204 | step, matches byte by byte the `scriptPubkey` provided during the *reveal 205 | phase*; otherwise fail the verification. 206 | 207 | 208 | ### Deterministic public key extraction from Bitcoin Script 209 | 210 | 1. The provided script MUST be parsed with Miniscript [16] parser; if the parser 211 | fails the procedure MUST fail. 212 | 2. Iterate over all branches of the abstract syntax tree generated by the 213 | Miniscript parser, running the following algorithm for each node: 214 | - if a public key hash is met (`pk_h` Miniscript command) and it can't be 215 | resolved against known public keys or other public keys extracted from the 216 | script, fail the procedure; 217 | - if a public key is found (`pk`) add it to the list of the collected public 218 | keys; 219 | - for all other types of Miniscript commands iterate over their branches. 220 | 3. Select unique public keys (i.e. if some public key is repeated in different 221 | parts of the script/in different script branches, pick a single instance of 222 | it). Compressed and uncompressed versions of the same public key must be 223 | treated as the same public key under this procedure. 224 | 4. If no public keys were found fail the procedure; return the collected keys 225 | otherwise. 226 | 227 | By "miniscript" we mean usage of `rust-miniscript` library v2.0.0 (commit 228 | `463fc1eadac2b46de1cd5ae93e8255a2ab34b906`) which may be found at 229 | 230 | 231 | 232 | ## Compatibility 233 | 234 | The proposed cryptographic commitment scheme is fully compatible, and works with 235 | LNPBP-1 standard [12] for constructing cryptographic commitments with a set of 236 | public keys. 237 | 238 | The standard is not compliant with previously used OP_RETURN-based cryptographic 239 | commitments, like OpenTimestamps [1], since it utilises plain value of the 240 | public key with the commitment for the OP_RETURN push data. 241 | 242 | The author is not aware of any P2(W)SH or non-OP_RETURN cryptographic commitment 243 | schemes existing before this proposal, and it is highly probable that the 244 | standard is not compatible with ones if they were existing. 245 | 246 | The proposed standard is compliant with current Taproot proposal [14], since it 247 | can use intermediate Taproot key to store the commitment. 248 | 249 | Standard also should be interoperable with Schnorr's signature proposal [15], 250 | since it uses miniscript supporting detection of public keys serialized with new 251 | BIP-340 rules. 252 | 253 | 254 | ## Rationale 255 | 256 | ### Continuing support for P2PK outputs 257 | 258 | While P2PK outputs are considered obsolete and are vulnerable to a potential 259 | quantum computing attacks, it was decided to include them into the specification 260 | for unification purposes. 261 | 262 | ### Support OP_RETURN type of outputs 263 | 264 | OP_RETURN was originally designed to reduce the size of memory-kept UTXO data; 265 | however it is not recommended to use it since it bloats blockchain space usage. 266 | This protocol provides support for this type of outputs only because some 267 | hardware (like HSM modules or hardware wallets) can't tweak public keys inside 268 | outputs and produce a correct signature after for their spending, and keeping 269 | the commitment in OP_RETURN's can be an only option. For all other cases it is 270 | highly recommended not to use OP_RETURN outputs for the commitments and use 271 | tweaking of other types of outputs instead. 272 | 273 | ### Unification with OP_RETURN-based commitments 274 | 275 | While it is possible to put a deterministic CC commitments into OP_RETURN-based 276 | outputs like with [1], their format was modified for unification purposes with 277 | the rest of the standard. This will help to reduce the verification and 278 | commitment code branching, preventing potential bugs in the implementations. 279 | 280 | ### Custom serialization of public keys in OP_RETURN 281 | 282 | This saves one byte of data per output, which is important in case of blockchain 283 | space. 284 | 285 | While we could pick a new BIP340-based rules for public key serialization [15], 286 | this will require software to support new versions of the secp256k1 libraries 287 | and language-specific wrappers, which may be a big issue for legacy software 288 | usually used by hardware secure modules, which require presence of OP_RETURN's 289 | (see rationale points above). 290 | 291 | ### Support for pre-SegWit outputs 292 | 293 | These types of outputs are still widely used in the industry and it was decided 294 | to continue their support, which may be dropped in a higher-level requirements 295 | by protocols operating on top of LNPBP-2. 296 | 297 | ### Committing to the sum of all public keys present in the script 298 | 299 | Having some of the public keys tweaked with the message digest, and some left 300 | intact will make it impossible to define a simple and deterministic commitment 301 | scheme for an arbitrary script and output type that will prevent any potential 302 | double-commitments. 303 | 304 | ### Deterministic public key extraction for a Bitcoin script 305 | 306 | We use determinism of the proposed Miniscript standard to parse the Bitcoin 307 | script in an implementation-idependet way and in order to avoid the requirement 308 | of the full-fledged Bitcoin Script interpreter for the commitment verification. 309 | 310 | The procedure fails on any public key hash present in the script, which prevents 311 | multiple commitment vulnerability, when different parties may be provided with 312 | different *extra-transaction proof* (ETP) data, such that they will use 313 | different value for the `S` public key matching two partial set of the public 314 | keys (containing and not containing public keys for the hashed values). 315 | 316 | The algorithm does not require that all of the public keys will be used in 317 | signature verification for spending the given transaction output (i.e. public 318 | keys may not be prefixed with `[v]c:` code in Miniscript [16]), so the 319 | committing parties may have a special public key shared across them for 320 | embedding the commitment, without requiring to know the corresponding private 321 | key to spend the output. 322 | 323 | ### Use of Taproot intermediate public key 324 | 325 | With Taproot we can't tweak the public key contained in the `scriptPubkey` 326 | directly since it will invalidate its commitment to the Tapscript and to the 327 | intermediate key, rendering output unspendable. Thus, we put tweak into the 328 | underlying intermediate public key as the only available option. 329 | 330 | 331 | ## Reference implementation 332 | 333 | 334 | 335 | 336 | ## Acknowledgements 337 | 338 | Authors would like to thank: 339 | * Giacomo Zucco and Alekos Filini for their initial work on the commitment 340 | schemes as a part of early RGB effort [13]; 341 | * Dr Christian Decker for pointing out on Lightning Network incompatibility with 342 | all existing cryptographic commitment schemes. 343 | 344 | 345 | ## References 346 | 347 | 1. Peter Todd. OpenTimestamps: Scalable, Trust-Minimized, Distributed 348 | Timestamping with Bitcoin. 349 | 350 | 2. Peter Todd. Preventing Consensus Fraud with Commitments and Single-Use-Seals. 351 | 352 | 3. [Eternity Wall's "sign-to-contract" article](https://blog.eternitywall.com/2018/04/13/sign-to-contract/) 353 | 4. Adam Back, Matt Corallo, Luke Dashjr, et al. Enabling Blockchain Innovations 354 | with Pegged Sidechains (commit5620e43). Appenxix A. 355 | . 356 | 5. 357 | 6. Pieter Wuille. Taproot proposal. 358 | 359 | 7. Gregory Maxwell. Taproot: Privacy preserving switchable scripting. 360 | 361 | 8. Gregory Maxwell. Graftroot: Private and efficient surrogate scripts under the 362 | taproot assumption. 363 | 364 | 9. Andrew Poelstra. Scriptless scripts. 365 | 366 | 10. Lightning Network BOLT-3 standard, version 1.0. Sections ["Offered HTLC 367 | Outputs"] 368 | 369 | and ["Received HTLC Outputs"] 370 | . 371 | 11. [BOLT-3 Lightning network specification](https://github.com/lightningnetwork/lightning-rfc/blob/master/03-transactions.md#to_remote-output) 372 | 12. Maxim Orlovsky, et al. Key tweaking: collision-resistant elliptic 373 | curve-based commitments (LNPBP-1 Standard). 374 | 375 | 13. RGB Protocol Specification, version 0.4. "Commitment Scheme" section. 376 | 377 | 14. Pieter Wuille. Taproot: SegWit version 1 spending rules. 378 | 379 | 15. Pieter Wuille. Schnorr Signatures for secp256k1. 380 | 381 | 16. Pieter Wuille, Andrew Poelsta. Miniscript. 382 | 383 | 384 | ## License 385 | 386 | This document is licensed under the Creative Commons CC0 1.0 Universal license. 387 | 388 | 389 | ## Appendix A. Test vectors 390 | 391 | ### 1. Correct test vectors 392 | 393 | TBD 394 | 395 | ### 2. Invalid test vectors 396 | 397 | TBD 398 | 399 | ### 3. Edge cases: protocol failures 400 | 401 | TBD 402 | -------------------------------------------------------------------------------- /lnpbp-0003.md: -------------------------------------------------------------------------------- 1 | ``` 2 | LNPBP: 0003 3 | Vertical: Bitcoin protocol 4 | Title: Deterministic definition of transaction output containing cryptographic 5 | commitment 6 | Authors: Giacomo Zucco, 7 | Dr Maxim Orlovsky , 8 | Federico Tenga, 9 | Martino Salvetti 10 | Comments-URI: https://github.com/LNP-BP/lnpbps/issues/5 11 | Status: Proposal 12 | Type: Standards Track 13 | Created: 2019-10-27 14 | License: CC0-1.0 15 | ``` 16 | 17 | - [Abstract](#abstract) 18 | - [Background](#background) 19 | - [Motivation](#motivation) 20 | - [Specification](#specification) 21 | - [Compatibility](#compatibility) 22 | - [Rationale](#rationale) 23 | - [Reference implementation](#reference-implementation) 24 | - [Acknowledgements](#acknowledgements) 25 | - [References](#references) 26 | - [License](#license) 27 | - [Test vectors](#test-vectors) 28 | 29 | 30 | ## Abstract 31 | 32 | The standard defines an algorithm for deterministic definition of the 33 | transaction output containing cryptographic commitments made under the standards 34 | LNPBP-1 [1] and LNPBP-2 [2]. 35 | 36 | 37 | ## Background 38 | 39 | Embedding cryptographic commitments into Bitcoin blockchain has become a common 40 | practice [3]. Bitcoin blockchain provides strong guarantees on the underlying 41 | data immutability, presenting a reliable, distributed and censorship-resitent 42 | proof-of-publication [4] medium. While existing standards defines how the 43 | cryptographic commitments can be used with public keys on SECP256k1 elliptic 44 | curve (used by Bitcoin) and embedded within transaction outputs, it still has to 45 | be defined how the interested parties may detect which of a Bitcoin transaction 46 | output contains the commitment, created under some specific protocol, including 47 | those interoperable with LNPBP-1 and LNPBP-2 standards. 48 | 49 | 50 | ## Motivation 51 | 52 | A number of use cases for cryptographic commitments (CC) require some commitment 53 | to be unique. For instance, single-use seals [5] may utilize them to achieve 54 | it's one-time commitment properties, as may be required in some of the 55 | applications [6], [7]. While the deterministic way for embedding into Bitcoin 56 | transactions (like "always use the first output) may be defined on a 57 | per-protocol basis, it seems that some best-practices, defining the best 58 | privacy-preserving and secure algorithm for such deterministic commitments in 59 | Bitcoin transactions may also be useful for the industry. 60 | 61 | Some of the protocols relies on the first OP_RETURN output present in the 62 | transaction to contain the commitment [3]. However, this would not work for 63 | commitments supporting other output types ([2], [8]), and for may introduce 64 | collisions with other protocols using OP_RETURN, like OMNI Layer [9]. 65 | 66 | Static definition of the output containing the commitment will be incompatible 67 | with BIP-69 [10], defining deterministic transaction output ordering and will 68 | not work with current Lightning Network implementation following the same rules 69 | [11]. 70 | 71 | 72 | ## Specification 73 | 74 | Cryptographic commitments under this standard are made according to LNPBP-1 [1] 75 | and LNPBP-2 [2] standards. 76 | 77 | To deterministically define the number of transaction output that contains CC 78 | under some protocol `P`, the committing party "Alice" `A` (which may be 79 | represented by a single person or some m-of-n federation) and the verifying 80 | party "Bob" `B` (which may be represented by a single person or some m-of-n 81 | federation) need to agree on three parameters: 82 | 1. A protocol-defined parameter `s`, acting as a seed for all protocol-wide 83 | commitments, this must be a 8-bit value; 84 | 2. A commitment-specific parameter `c`, which should not be directly reflected 85 | in the transaction, containing the given CC. This parameter under some 86 | circumstances (agreed by the parties beforehand) may be absent. The value of 87 | `c` must be a 8-bit value. 88 | 89 | These two parameters serve as a "salt" for the deterministic procedure, 90 | preventing third-parties from guessing the information of the actual commitment, 91 | thus avoiding possible censorship by the miners and on-chain based transaction 92 | analysis. 93 | 94 | Alice, creating the transaction containing CC, and Bob, verifying it, must use 95 | the following procedure: 96 | 97 | 1. Compute the transaction fee `f`, as a difference between total transaction 98 | output amounts in satoshis and total inputs amounts, in satoshis: 99 | `f = sum(outputs) - sum(inputs)`. 100 | This can be done, for instance, by utilizing data from a partially-singed 101 | bitcoin transaction, or by contacting Electrum Server or Bitcoin Core backend. 102 | It should be noted, that according to Bitcoin consensus rules, this amount 103 | must always be positive and greater than zero(`f > 0`); otherwise it is not a 104 | valid Bitcoin transaction and the protocol must fail. 105 | 2. Compute the adjusted fee `a` as a 32-bit modulo of the potentially-64 bit 106 | number `f`: 107 | `a = f mod 2^32`. 108 | 3. Add to this number a previously-agreed values of `s` and `c` (if `c` was 109 | not defined, use `0` for `c` value by default). This will give a 110 | commitment-factor `x`: 111 | `x = a + s + c`. 112 | Since `s` and `c` is a 8-bit numbers and `a` is a 32-bit number, the result 113 | will fit a 64-bit number without overflow. 114 | 4. Get the number of outputs `n` for the transaction containing the output with 115 | the given cryptographic commitment. 116 | 5. Compute `d` as `d = x mod n`. The `d` will represent an index of the output 117 | which must contain a cryptographic commitment. All other transaction outputs 118 | will not be a valid outputs for a contain cryptographic commitment under the 119 | used protocol. 120 | 121 | 122 | ## Compatibility 123 | 124 | The proposed standard is incompatible with many of existing practices for 125 | definition of the transaction output containing cryptographic commitment, 126 | including OpenTimestamps, which uses first transaction output for storing the 127 | commitment [1] 128 | 129 | Nevertheless, use of protocol-specific pre-defined salt may be utilised as a 130 | flag signalling the support of the current standard, which will help to avoid 131 | possible commitment collisions across different protocols. 132 | 133 | Future SIGHASH_NOINPUT standard BIP-118 [12] may be compatible with this 134 | proposal, since a protocol utilizing the present standard may define that any 135 | transaction commitment with an input signature flag set to SIGHASH_NOINPUT must 136 | default to the zero value of commitment-specific parameter `c`. This will still 137 | preserve the privacy from the onchain analysis tools due to the presence of the 138 | protocol-specific parameter `s`, which will be unknown for any party that does 139 | know which protocol is used by some transaction (given the fact that the used 140 | protocol can't be guessed from the transaction itself). 141 | 142 | 143 | ## Rationale 144 | 145 | The rationale for the technical decisions is provided within the specification 146 | text. 147 | 148 | 149 | ## Reference implementation 150 | 151 | 152 | 153 | 154 | ## Acknowledgements 155 | 156 | Authors would like to thank Giacomo Zucco and Alekos Filini for their initial 157 | work on the commitment schemes as a part of early RGB effort [7]. 158 | 159 | 160 | ## References 161 | 162 | 1. Maxim Orlovsky, et al. Key tweaking: collision-resistant elliptic curve-based 163 | commitments (LNPBP-1 Standard). 164 | 165 | 2. Maxim Orlovsky, et al. Deterministic embedding of elliptic curve-based 166 | commitments into transaction output scriptPubkey (LNPBP-2 standard). 167 | 168 | 3. Peter Todd. OpenTimestamps: Scalable, Trust-Minimized, Distributed 169 | Timestamping with Bitcoin. 170 | 171 | 4. Peter Todd. Setting the record straight on Proof-of-Publication. 172 | 173 | 5. Peter Todd. Preventing Consensus Fraud with Commitments and Single-Use-Seals. 174 | 175 | 6. Peter Todd. Scalable Semi-Trustless Asset Transfer via Single-Use-Seals and 176 | Proof-of-Publication. 177 | 178 | 7. OpenSeals Framework 179 | 8. Omni Protocol Specification (formerly Mastercoin). 180 | 181 | 9. RGB Protocol Specification, version 0.4. 182 | 183 | 10. Lexicographical Indexing of Transaction Inputs and Outputs (BIP-69 standard). 184 | 185 | 11. Lightning Network BOLT-3 standard. 186 | 187 | 12. Christian Decker. SIGHASH_NOINPUT. 188 | 189 | 190 | ## License 191 | 192 | This document is licensed under the Creative Commons CC0 1.0 Universal license. 193 | 194 | 195 | ## Test vectors 196 | 197 | TBD 198 | -------------------------------------------------------------------------------- /lnpbp-0004.md: -------------------------------------------------------------------------------- 1 | ``` 2 | LNPBP: 0004 3 | Vertical: Client-validated data (3) 4 | Title: Multi-message commitment scheme with zero-knowledge provable unique properties 5 | Author: Dr Maxim Orlovsky 6 | Comments-URI: https://github.com/LNP-BP/lnpbps/issues/8 7 | Status: Proposal 8 | Type: Standards Track 9 | Created: 2019-10-28 10 | Finalized: not yet 11 | License: CC0-1.0 12 | ``` 13 | 14 | - [Abstract](#abstract) 15 | - [Background and Motivation](#background-and-motivation) 16 | - [Design](#design) 17 | - [Specification](#specification) 18 | - [Commitment](#commitment) 19 | - [Partial reveal](#partial-reveal) 20 | - [Reveal with full disclosure](#reveal-with-full-disclosure) 21 | - [Per-message verification](#per-message-verification) 22 | - [Verification of the full disclosure](#verification-of-the-full-disclosure) 23 | - [Compatibility](#compatibility) 24 | - [Rationale](#rationale) 25 | - [Maximum buffer size restrictions](#maximum-buffer-size-restrictions) 26 | - [Reference implementation](#reference-implementation) 27 | - [Acknowledgements](#acknowledgements) 28 | - [References](#references) 29 | - [Copyright](#copyright) 30 | - [Test vectors](#test-vectors) 31 | 32 | 33 | ## Abstract 34 | 35 | The standard defines a way to commit to a multiple independent messages with a 36 | single digest such that the fact of each particular commitment, and a protocol 37 | under which the commitment is made may be proven without exposing the 38 | information about the other messages and used protocols. 39 | 40 | 41 | ## Background and Motivation 42 | 43 | LNPBP-3 defines a standard for embedding cryptographic commitment into bitcoin 44 | transaction in a deterministic & provable way [2]. The standard is based on 45 | LNPBP-1 public key tweaking procedure [1], which prevents multiple commitments 46 | inside a tweak. However, this may result in two potential problems. 47 | 48 | First, there could be two different protocols willing to put different 49 | commitments into a single transaction output; and only one of the protocols will 50 | succeed due to the LNPBP-2 & LNPBP-1 design. 51 | 52 | Second, it is possible that some protocol may require committing to a number of 53 | messages within a single transaction and public key with the requirement that 54 | some dedicated information from these messages (like the message type) should be 55 | unique across the whole message set. For instance, this is required for state 56 | updates, where such updates separated into different blocks (messages) and 57 | should be kept private, such that a single party will know information about a 58 | single update and should not be disclosed any information about the rest. 59 | However, in such case, there should be a proof that the other state updates do 60 | not affect the state of the analyzed update, excluding state collisions. In such 61 | a setup, each state may be assigned a unique integer identifier (like 62 | cryptographic digest), and a special form of zero-knowledge proof should be 63 | utilized to proof the fact that all the states are different without exposing 64 | the actual state ids. 65 | 66 | While both cases are impossible at the level of LNPBP-3 & LNPBP-1 standards, the 67 | current proposal defines a procedure for structuring multiple independent 68 | messages in a privacy-preserving (zero-knowledge) way, allowing that some 69 | properties of the committed messages may be proven in a zero-knowledge way, i.e. 70 | without revealing any information about the source messages or the properties 71 | themselves. 72 | 73 | 74 | ## Design 75 | 76 | The protocol follows dea of Bloom filters [5], which are already used for 77 | keeping confidentiality of the information requested from Bitcoin Core by SPV 78 | clients [6]. 79 | 80 | Multiple commitments under different protocols are identified with a unique 81 | per-protocol 256-bit identifiers (like tagged hashes of protocol name and/or 82 | characteristic parameters) and serialized into 256-bit slots within `N * 32` 83 | byte buffer such as `N >> M`, where `M` is the number of the individual 84 | commitments. The rest of the slots is filled with random data deterministically 85 | generated from a single entropy source. The position `n` for a commitment with 86 | the identifier `id` is computed as `n = id mod N`, guaranteeing that no two 87 | commitments under the same protocol with a given `id` may be simultaneously 88 | present. 89 | 90 | ![LNPBP4 visualisation](./assets/lnpbp-0004.png) 91 | 92 | ## Specification 93 | 94 | ### Commitment 95 | 96 | For a given set of `M` messages `msg1`..`msgM` under protocols with 97 | corresponding unique ids `id`..`idM` the commitment procedure runs as follows: 98 | 1. Pick 64 bits of entropy from uniform entropy source (like the same 99 | which is used for generating private keys). This entropy will be 100 | identified with `entropy_seed` hereinafter. 101 | 2. Pick a 16-bit number `N >> M`, for instance `N = M * 2` and allocate `32*N` 102 | byte buffer (such that the maximum buffer length MUST not exceed 2^21, i. 103 | e 2 MB). 104 | 3. For each of the messages: 105 | - create a corresponding cryptographic commitment `cI` according to the 106 | per-message protocol, 107 | - compute `n = idI mod N` (if the protocol identifier is a hash, it should be 108 | converted into unsigned integer of appropriate dimensionality using little- 109 | endian notation), 110 | - if the slot `n` is not used, serialize a `cI` hash into it using 111 | bitcoin-style hash serialization format; 112 | otherwise go to step 3 and generate a new `N' >> N`. 113 | 4. For each of the slots that remain empty (the slot number is represented 114 | by `j`): 115 | - compute SHA256-tagged hash of `seed_entropy || j`, where both values are 116 | serialized as little-endian byte strings (the total length of resulting 117 | byte string for hashing should be 272 bits). The tagged hash procedure 118 | must run according to BIP-340 [4] using UTF-8 representation of 119 | `LNPBP4:entropy` string as the tag. 120 | 5. Compute commitment to the resulting buffer with LNPBP-1 [1], LNPBP-2 [2] or 121 | other protocol using `LNPBP4` as the protocol-specific tag. 122 | 123 | ### Partial reveal 124 | 125 | A party needing to reveal the proofs for the commitment to the message `msgA` 126 | under this scheme and conceal the rest of the messages and protocols 127 | participating in the commitment has to publish the following data: 128 | 1. A source of the message `msgA` and information about its protocol with id 129 | `idA`. 130 | 2. A full byte sequence of the buffer resulting from the step 5 of the 131 | [commitment procedure](#commitment). 132 | 133 | ### Reveal with full disclosure 134 | 135 | A party needing to reveal the proofs for all commitments to all the messages 136 | and prove that there were no other commitments made must publish the 137 | following data: 138 | 1. A source of the messages `msg1`..`msgM` and information about their 139 | protocols with id `id1`..`idM`. 140 | 2. A full byte sequence of the buffer resulting from the step 5 of the 141 | [commitment procedure](#commitment). 142 | 3. An entropy value `entropy_seed` from the step 2 of the 143 | [commitment procedure](#commitment). 144 | 145 | ### Per-message verification 146 | 147 | A party provided with the data from the 148 | [partial reveal procedure](#partial-reveal) and wishing to verify the commitment 149 | to the message MUST use the following procedure: 150 | 1. Compute `n = idA mod N`, where `idA` is the message-specific protocol id 151 | and `N` is the length of the commitment buffer in bytes divided on 32. 152 | 2. Compute commitment to the message by following the procedure from the 153 | step 3 of the [commitment scheme](#commitment) 154 | 3. Verify that the resulting 32-bit commitment is equal to the commitment 155 | stored in `n`'s 32-byte slot of the commitment buffer; fail verification 156 | otherwise. 157 | 158 | ### Verification of the full disclosure 159 | 160 | A party provided with the data from the 161 | [reveal with full disclosure procedure](#reveal-with-full-disclosure) may verify 162 | that the provided commitment buffer contains only commitment to the provided 163 | messages (and no other commitments) by allocating a new empty (all bytes set 164 | to `0x00`) commitment buffer of the same length as the revealed commitment 165 | buffer, and re-running steps 4-6 from the [commitment procedure](#commitment) 166 | . If the new buffer match per-byte the revealed commitment buffer, then the 167 | verification succeeded; otherwise it has failed. 168 | 169 | 170 | ## Compatibility 171 | 172 | TBD 173 | 174 | 175 | ## Rationale 176 | 177 | ### Maximum buffer size restrictions 178 | 179 | The maximum buffer size defines the potential size of the data provided for 180 | client-side-validation, and may represent a form of DoS attack vector, when 181 | the party allocating/creating buffer defines a storage and network data 182 | transfer requirements for all the future verifying parties. From the other 183 | side, the maximum buffer size defines the upper bound for the maximum number 184 | of commitments that may be embedded within a single transaction output. We 185 | have selected a 16-bit limit for the number of slots, limiting the maximum 186 | buffer size to 2 MBs, and maximum theoretical number of simultaneous 187 | commitments under the same transaction output to 2^16. However, in practice, 188 | the latter limit will never be reached, because assuming the uniform 189 | distribution of protocol-specific identifier hashes a committing party will 190 | be able to produce simultaneous commitment under `1^8` different protocols 191 | in average. 192 | 193 | 194 | ## Reference implementation 195 | 196 | Reference implementation can be found inside client-side-validation foundation 197 | rust library and represents integral part of this 199 | standard. 200 | 201 | 202 | ## Acknowledgements 203 | 204 | ## References 205 | 206 | 1. Maxim Orlovsky, et al. Key tweaking: collision-resistant elliptic 207 | curve-based commitments (LNPBP-1 Standard). 208 | 209 | 2. Maxim Orlovsky, et al. Deterministic embedding of LNPBP1-type commitments 210 | into `scriptPubkey` of a transaction output (LNPBP-2 Standard). 211 | 212 | 3. Giacomo Zucco, et al. Deterministic definition of transaction output 213 | containing cryptographic commitment (LNPBP-3 Standard). 214 | 215 | 4. Pieter Wuille, et al. BIP-340: Schnorr Signatures for secp256k1. 216 | 217 | 5. Bloom, Burton H. (1970), "Space/Time Trade-offs in Hash Coding with 218 | Allowable Errors", Communications of the ACM, 13 (7): 422–426, doi:10. 219 | 1145/362686.362692. 220 | 221 | 6. Mike Hearn, Matt Corallo. BIP-37: Connection Bloom filtering. 222 | 223 | 224 | 225 | ## Copyright 226 | 227 | This document is licensed under the Creative Commons CC0 1.0 Universal license. 228 | 229 | 230 | ## Test vectors 231 | 232 | TBD 233 | -------------------------------------------------------------------------------- /lnpbp-0005.md: -------------------------------------------------------------------------------- 1 | ``` 2 | LNPBP: 0005 3 | Vertical: Bitcoin protocol 4 | Title: Universal short Bitcoin identifiers for blocks, transactions and 5 | transaction inputs & outputs 6 | Author: Dr Christian Decker , 7 | Dr Maxim Orlovsky 8 | Comments-URI: https://github.com/LNP-BP/lnpbps/issues/<____> 9 | Status: Proposal 10 | Type: Standards Track 11 | Created: 2020-02-17 12 | License: CC0-1.0 13 | ``` 14 | 15 | - [Abstract](#abstract) 16 | - [Background](#background) 17 | - [Motivation](#motivation) 18 | - [Specification](#specification) 19 | - [Bitwise structure of the identifier](#bitwise-structure-of-the-identifier) 20 | - [Distinguishing different types of identifier](#distinguishing-different-types-of-identifier) 21 | - [Compatibility](#compatibility) 22 | - [Rationale](#rationale) 23 | - [Estimating ranges for bit-based values](#estimating-ranges-for-bit-based-values) 24 | - [Reference implementation](#reference-implementation) 25 | - [Acknowledgements](#acknowledgements) 26 | - [References](#references) 27 | - [Copyright](#copyright) 28 | - [Test vectors](#test-vectors) 29 | 30 | 31 | ## Abstract 32 | 33 | The work introduces short 64-bit identifiers able to uniquely distinguish 34 | bitcoin blocks, transactions, transaction inputs and outputs for both on-chain 35 | transactions and off-chain transactions, representing sufficient collision 36 | resistance for the common tasks of blockchain and transaction data indexing, 37 | search and compact archive storage. This format may be useful for different 38 | Layer 2 and 3 applications, as well as user-based clients and indexing services. 39 | 40 | 41 | ## Background 42 | 43 | Bitcoin transactions are normally identified by 256-bit integers, representing 44 | double SHA256 hashes of the conservative transaction data serialized according 45 | to the original Satoshi Bitcoin client code [1] and SegWit BIP-141 specification 46 | [2]. These identifiers are unique: two distinct transactions has probability of 47 | ~2^256 that their identifiers would collide. While such security is undoubtedly 48 | required to maintain global identifiers for all possible transactions, for the 49 | transactions already included in Bitcoin blockchain it may be unnecessary for 50 | multiple cases. The main drawback of using 256-bit integers is inconveniences 51 | for normal computing tasks: modern CPUs and databases can easily handle up to 52 | 64-bit integers, but not 256-bit. This introduces unnecessary load for indexing 53 | and search tasks; increases storage requirements and network traffic. 54 | 55 | Lightning network protocol (LNP) has introduced the use of short channel 56 | identifiers [3], a 64-bit integers composed of the channel funding transaction 57 | data: 58 | 59 | * block height (occupying the most significant 3 bytes) 60 | * transaction index within the block (the next 3 bytes) 61 | * output index funding the channel (least significant 2 bytes) 62 | 63 | The introduction of this data structure was reasonable, since Lightning network 64 | operates only channels funded with transactions secure from deep re-orgs, thus 65 | introduction of blockchain-based identifiers was safe. 66 | 67 | Here we propose more generic scheme, that follows the design ideas from LNP 68 | extending the concept of short identifiers beyond addressing transaction outputs 69 | only. 70 | 71 | 72 | ## Motivation 73 | 74 | Normally, references to blockchain blocks, transactions, their inputs and 75 | outputs occupy 32 - or up to 37 bytes (in case of inputs/outputs). For the 76 | existing set of transactions residing in blockchain just listing all existing 77 | data will require gigabytes of storage space. Many user applications and 78 | services, However, require cross-referencing and indexing - like `JOIN` SQL 79 | queries connecting different tables (like transactions, outputs and inputs) with 80 | primary/foreign keys, where the keys are 32-byte values. This is both extremely 81 | inefficient in terms of performance and index storage space. While it may be a 82 | normal practice to use incremental 32-bit indexing, the full identifiers still 83 | should be kept, and two different databases created by the same software after 84 | some re-orgs will not match by their indexes. 85 | 86 | Thus, we are proposing a format for 64-bit identifiers, that are both collision- 87 | and reorg-resistant (with ~1/256 probability) and can be used for an efficient 88 | indexing, primary/foreign key values and referencing. 89 | 90 | 91 | ## Specification 92 | 93 | ### Bitwise structure of the identifier 94 | 95 | The identifier is a 64-bit number, where value of the most significant bit 96 | defines format for the rest of the bits. This first bit represents a flag 97 | distinguishing on-chain and off-chain transactions and items. If the flag is 98 | set to 0, the bits MUST have the following meaning: 99 | 100 | ``` 101 | _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ 102 | ^ ^ ^ ^ ^ ^ ^ ^ ^ ^ 103 | | | | | | | | | | | 104 | | +--------------------------------------------------+ +--------------+ +---------------------------------+ | +-------------------------------+ 105 | | Block height, 23 bits BlockHash checksum Transaction position in the block | TxIn/TxOut index, 15 bits 106 | Off-chain flag, set to 0 8 bits 16 bits TxIn/TxOut flag 107 | ``` 108 | 109 | | Bits* | No bits | Possible no of values | Meaning | 110 | |------:|--------:|----------------------:|---------| 111 | | 0 | 1 | 2 | Flag indicating the structure for the rest of bits; MUST be set to 0 for the provided case | 112 | | 1-23 | 23 | 8'388'608 | Block height; sufficient to cover >160 years of blockchain history | 113 | | 24-31 | 8 | 256 | Checksum for block hash value: binary XOR of it's 8 bytes | 114 | | 32-47 | 16 | 65'536 | Transaction position in the block; with 1 MB block size limit sufficient to cover all transactions even if their average size is 15 only | 115 | | 48 | 1 | 2 | Flag indicating whether the next 15 bits represents transaction input (0) or output (1) index | 116 | | 49-63 | 15 | 32'768 | Transaction input or output index (starting from 1) | 117 | 118 | * In "most significant bit goes first" order 119 | 120 | 121 | If the most significant bit of the short identifier is set to 1, the bits MUST 122 | have the following meaning: 123 | 124 | ``` 125 | _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ 126 | ^ ^ ^ ^ ^ ^ 127 | | | | | | | 128 | | +-----------------------------------------------------------------------------------------------------------+ | +-------------------------------+ 129 | | Highest 47 bits from transaction id | TxIn/TxOut index, 15 bits 130 | Off-chain flag, set to 1 TxIn/TxOut flag 131 | ``` 132 | 133 | |Bits* | No bits | Possible no of values | Meaning | 134 | |------:|--------:|----------------------:|---------| 135 | | 0 | 1 | 2 | Flag indicating the structure for the rest of bits; MUST be set to 1 for the provided case | 136 | | 1-47 | 47 | >140 trillions (1.4*10^14) | Highest 47 bits from transaction id | 137 | | 48 | 1 | 2 | Flag indicating whether the next 15 bits represents transaction input (0) or output (1) index | 138 | |49-63 | 15 | 32'768 | Transaction input or output index (starting from 1) | 139 | 140 | * Using big endian (network) byte order 141 | 142 | ### Distinguishing different types of identifier 143 | 144 | The identifier may be used to denote 7 different types of Bitcoin blockchain- 145 | related entities: 146 | 147 | Entity | Kind | Distinguishing factor 148 | -------------------|-----------|----------------------- 149 | Block | On-chain | First bit set to 0, bits 32-63 set to 0 150 | Transaction | On-chain | First bit set to 0, bits 48-63 set to 0 151 | Transaction input | On-chain | First bit set to 0, bit 48 set to 0, at least one of the bits in range of 49-63 is a non-zero 152 | Transaction output | On-chain | First bit set to 0, bit 48 set to 1, at least one of the bits in range of 49-63 is a non-zero 153 | Transaction | Off-chain | First bit set to 1, bits 48-63 set to 0 154 | Transaction input | Off-chain | First bit set to 1, bit 48 set to 0, at least one of the bits in range of 49-63 is a non-zero 155 | Transaction output | Off-chain | First bit set to 1, bit 48 set to 1, at least one of the bits in range of 49-63 is a non-zero 156 | 157 | 158 | It should be noted, that coinbase transactions has the same identifier as the 159 | block itself (since transaction indexes within the block are 0-based, unlike 160 | transaction input and output indexes, which are 1-based): in this regard 161 | coinbase transaction can be seen as a natural part of the block data. 162 | Nevertheless, identifiers for coinbase transaction outputs and inputs are 163 | distinguished from the unique short block identifier. 164 | 165 | 166 | ## Compatibility 167 | 168 | The proposed format is incompatible with previously existing block, transaction, 169 | transaction input and output identifiers, including `short_channel_id` from 170 | Lightning network protocols. 171 | 172 | The format is highly compatible with the requirements of modern databases, 173 | including both SQL and No-SQL databases, as well as generic CPU capabilities and 174 | programming languages, since all of them are able to deal with 64-bit numbers in 175 | highly efficient manner. 176 | 177 | 178 | ## Rationale 179 | 180 | ### Estimating ranges for bit-based values 181 | 182 | The minimum size of transaction input is: 183 | 184 | * 32 bytes reference to txid spent by this input 185 | * 4 bytes for index of transaction output spent by this input, 186 | * 1 byte for variable-length int denoting zero-size `sigScript`, 187 | * 4 bytes for `nSeq`, 188 | 189 | 41 byte in total. 190 | 191 | With 1 MB block size limit and the only one transaction fitting into the block, 192 | it may have at most 2^20 / 41 <= 26'000 transaction inputs; which is lower than 193 | the maximum value of 15-bit number referencing transaction input index (2^15 = 194 | 32'768). 195 | 196 | 197 | The minimum size of transaction output is: 198 | 199 | * 8 bytes for amount (in satoshis) 200 | * 1 byte for variable-length int denoting zero-size `scriptPubkey`, 201 | 202 | for nonce/anyone can spent output, or at least 203 | 204 | * 8 bytes for amount (in satoshis) 205 | * 1 byte for `scriptPubkey` length fields 206 | * 33 bytes for the shortest possible spendable version of `scriptPubkey` 207 | controlled by public key(s): 1 byte SegWit push of `0x01` (for Taproot) 208 | followed by 32-bytes of witness program [2], representing a serialized Taproot 209 | public key according to [5]. 210 | 211 | I.e. 42 bytes in total, meaning that the same equation valid for transaction 212 | inputs above stands for transaction outputs: no meaningful bitcoin transaction 213 | can't hold more than 2^15 outputs with the current validation rules. 214 | 215 | 216 | ## Reference implementation 217 | 218 | 219 | 220 | 221 | ## Acknowledgements 222 | 223 | 224 | 225 | ## References 226 | 227 | 1. 228 | 2. Eric Lombrozo, Johnson Lau, Pieter Wuille. BIP-141: Segregated Witness 229 | (Consensus layer). 230 | 231 | 3. BOLT #7: P2P Node and Channel Discovery. 232 | 233 | 4. Pieter Wuille, Jonas Nick, Anthony Towns. BIP-341 Taproot: SegWit version 1 234 | output spending rules. 235 | 236 | 5. Pieter Wuille, Jonas Nick, Tim Ruffing. BIP-340: Schnorr Signatures for 237 | secp256k1. 238 | 239 | 240 | 241 | ## Copyright 242 | 243 | This document is licensed under the Creative Commons CC0 1.0 Universal license. 244 | 245 | 246 | ## Test vectors 247 | 248 | TBD 249 | -------------------------------------------------------------------------------- /lnpbp-0006.md: -------------------------------------------------------------------------------- 1 | ``` 2 | LNPBP: 0006 3 | Vertical: Bitcoin protocol 4 | Title: Deterministic bitcoin commitments 5 | Author: Dr Maxim Orlovsky 6 | Comments-URI: https://github.com/LNP-BP/lnpbps/pulls/116 7 | Status: Rejected 8 | Type: Standards Track 9 | Created: 2021-11-15 10 | Finalized: not yet 11 | License: CC0-1.0 12 | Related standards: LNPBP-1, 2, 4, 7, 9, 92 13 | ``` 14 | 15 | ## Abstract 16 | 17 | The proposal provides standard mechanism for creating, structuring & verifying 18 | deterministic bitcoin commitments ("anchoring") to multiple extra-transaction 19 | data (client-side-validated etc). 20 | 21 | ## Background 22 | 23 | ## Motivation 24 | 25 | ## Design 26 | 27 | Miltiple protocols may commit to external (non-transaction and non-blockchain) 28 | data by constructing a special data structure called *anchor* and committing 29 | to its content inside transaction input or output. 30 | 31 | 32 | ## Specification 33 | 34 | ### Commitment procedure 35 | 36 | A party needing to commit to multiple data coming from distinct protocols 37 | MUST follow the algorithm: 38 | 1. Construct LNPBP-4 multi-message commitment; 39 | 2. Deterministically define transaction input or output which will contain 40 | the final commitment. This algorithm is not a part of the current 41 | specification and must be defined at upper protocol level (see for instance 42 | LNPBP-10). 43 | 3. Run commitment embedding procedure: 44 | - If commitment will be placed into transaction output, construct 45 | *extra-transaction proof* using procedure from LNPBP-2; fail algorithm 46 | if the LNPBP-2 requirements can't be fulfilled. 47 | - If commitment will be placed into transaction input, construct 48 | *extra-transaction proof* using procedure from LNPBP-92; fail algorithm 49 | if the LNPBP-92 requirements can't be fulfilled. 50 | 4. Construct *anchor* data structure (see below), encode it and persist 51 | the data as long as it will be required to provide proofs of the commitment. 52 | 53 | If algorithm failed the party creating commitment MAY change the structure 54 | of the transaction and try to repeat the commitment procedure. 55 | 56 | ### Verification procedure 57 | 58 | The verification process runs by repeating steps of the commitment protocol 59 | using the information provided during the *reveal phase* and verifying the 60 | result is equal to the provided proofs. If the commitment procedure fails 61 | at any of the steps, the verification procedure MUST also fail. 62 | 63 | ### Anchor structure and serialization 64 | 65 | Anchor consists of the following fields, serialized according to the strict 66 | serialization rules (see LNPBP-7): 67 | 1. `txid`: 32-byte transaction id 68 | 2. `commitment`: a commutment block structure from LNPBP-4 69 | 3. `proof`: a deterministic commitment proof which has the same structure for 70 | both LNPBP-2 and LNPBP-92 commitment: 71 | 1. `original_pubkey`: original 33-byte value of the pubkey before tweak; 72 | for pay-to-signature (LNPBP-92) tweaks this is `R` value generated 73 | from a nonce. BIP-340 keys MUST be encoded as 33 byte value having 74 | first byte `0x02`. 75 | 2. `script_info`: an enum, encoded with a first byte representing enum 76 | variant 77 | - `0x00 = SinglePubkey`: always used by LNPBP-92 and by LNPBP-2 78 | commitments based on P2PK, P2PKH, P2WPKH, legacy SegWit v0 79 | P2WPKH-in-P2SH, P2TR with key spending only (self-tweaked), 80 | OP_RETURN and other bare script outputs. 81 | - `0x01 = LockScript`: a Bitcoin script source which knowledge 82 | is required to satisfy spending for pre-SegWit P2SH, native SegWit v0 83 | P2WSH. The enum variant byte MUST be followed by a strict-encoded 84 | representation of binary script data. This script MUST match 85 | `redeemScript` for P2SH and `witnessScript` for P2WSH. 86 | - `0x02 = WrappedWitnessScript`: Bitcoin script source which knowledge 87 | is required to satisfy spending for legacy (P2SH-wrapped) SegWit v0, 88 | P2WSH-in-P2SH outputs (and, potentially, fututre SegWit versions). 89 | The enum variant byte MUST be followed by a strict-encoded 90 | representation of binary script data. This script MUST match 91 | `witnessScript` for P2WSH; for P2SH wrapped version it also must 92 | be a `witnessScript` and not `redeemScript`. 93 | - `0x03 = TaprootScript`: a Merkle root of the script spending path 94 | of the taproot output or a value of a tweak applied to the internal 95 | taproot key if and only if this tweak is not a self-tweak. Must be 96 | followed by exactly 32 bytes (without length prefix) of the tweak 97 | data in little endinan order. 98 | 99 | The list of `script_info` variants is non-exhaustive. If a future version of 100 | script info variant byte is met the deserialization of anchor data MUST fail 101 | with explicit error and the anchor MUST not be verified. 102 | 103 | If the anchor data does not match the provided script pubkey (for instance, 104 | being encoded as P2WSH-in-P2SH instead of P2WSH) the verifying party MUST 105 | fail verification even if other option is satisfied with other (non-specified) 106 | encoding. 107 | 108 | ### Concealment of the anchor data 109 | 110 | Anchor data contain extra information which is not required for the DBC 111 | validation and represents additional proofs for non-DBC validation procedures. 112 | This information is contained in `commitment` field of the *anchor* data 113 | structure containing LNPBP-4 multi-message commitment entrypy value, used 114 | for proving the absence of some specific protocol within the commitment tree. 115 | This information MAY be discarded for privacy reasons when the *anchor* data 116 | are passed to a third-party with a special *conceal* procedure as described 117 | in LNPBP-4 and LNPBP-9 standards. 118 | 119 | 120 | ## Compatibility 121 | 122 | ## Rationale 123 | 124 | ### Why not to use `0x03` variant for keeping key spend path-only Taproot info 125 | 126 | Using `0x03` variant (`TaprootScript`) for Taproot outputs having no script 127 | path spending conditions (i.e. self-tweaked keys) instead of `0x00` 128 | (`SinglePubkey`) will result in storing additional 32 bytes on the client side 129 | per each output of this type, while providing no privacy gains: a user 130 | hacing access to the anchor data can always make sure that the value of the 131 | script tweak is equal to the self-tweak and still acquire knowledge that 132 | the output does not contain a script path spending condition. 133 | 134 | ### Why not to use single `0x01` variant for all types of scripts 135 | 136 | P2WSH-in-P2SH require its own script info variant (`0x02`, 137 | `WrappedWitnessScript`) since this allows to simplify verification algorithm 138 | by avoiding trying multiple script encodings (native P2SH and legacy 139 | P2WSH-in-P2SH). This does not reduce forward compatibility: we may have 252 140 | more variants for script info value, which is exceeds a possible number of 141 | future bitcoin script pubkey encoding (15 possible future witness values). 142 | 143 | ## Reference implementation 144 | 145 | The reference implementation is version `1.0` of [`bp-dbc` crate](bp-dbc), 146 | which is a part of the [BP Core Library](bp-core) developed and maintained 147 | by LNP/BP Strandards Association. 148 | 149 | If the implementation differs from the spec, the spec has a higher priority. 150 | 151 | ## Acknowledgements 152 | 153 | ## References 154 | 155 | ## Copyright 156 | 157 | This document is licensed under the Creative Commons CC0 1.0 Universal license. 158 | 159 | ## Test vectors 160 | 161 | [bp-dbc]: https://crates.io/crates/bp-dbc 162 | [bp-core]: https://github.com/LNP-BP/bp-core 163 | -------------------------------------------------------------------------------- /lnpbp-0008.md: -------------------------------------------------------------------------------- 1 | ``` 2 | LNPBP: 0008 3 | Vertical: Cryptographic primitives 4 | Title: Single-use-seals 5 | Author: Peter Todd 6 | Comments-URI: https://github.com/LNP-BP/lnpbps/issues/117 7 | Status: Proposal 8 | Type: Standards Track 9 | Created: 2017-12-05 10 | Finalized: 2021-11-16 11 | Based on: https://petertodd.org/2017/scalable-single-use-seal-asset-transfer 12 | License: CC0-1.0 13 | ``` 14 | 15 | - [Abstract](#abstract) 16 | - [Background](#background) 17 | - [Motivation](#motivation) 18 | - [Design](#design) 19 | - [Specification](#specification) 20 | - [Trust](#trust) 21 | - [Reference implementation](#reference-implementation) 22 | - [References](#references) 23 | - [Copyright](#copyright) 24 | 25 | 26 | ## Abstract 27 | 28 | A single-use-seal is an abstract mechanism to prevent double-spends. The 29 | current proposal defines core single-use-seal terminology and procedures 30 | which must be supported and implemented according to this guidelines by 31 | any specific single-use-seal implementation. 32 | 33 | 34 | ## Background 35 | 36 | Concept of single-use-seal was developed as a result of research work on 37 | cryptographic commitments, consensus protocols in distributed systems and 38 | client-side-validation [1, 2, 3, 4]. 39 | 40 | 41 | ## Motivation 42 | 43 | Existing cryptographic commitment primitives does not allow to create 44 | "two-level" commitments, whether at initial stage a commiter commits to 45 | commit to a certain (potentially yet unknown) message in the future, once 46 | and only once. Given a trustless way of performing verification of such 47 | commitments the primitive may be a basic building block for creating 48 | decentralized, private and censorship-resistant state machines and smart 49 | contracting systems which will be protected from "double-spend" attacks. 50 | 51 | 52 | ## Design 53 | 54 | Analogous to the real-world, physical, single-use-seals used to secure shipping 55 | containers, a single-use-seal primitive is a unique object that can be closed 56 | over a message exactly once. In short, a single-use-seal is an abstract 57 | mechanism to prevent double-spends. 58 | 59 | 60 | ## Specification 61 | 62 | For a given data structure $l$ providing *single-use-seal definition* and 63 | a *messag*e $m$ single-use-seal implementation MUST support two fundamental 64 | operations: 65 | 66 | * *Close seal* $l$ over *message* $m$, producing a *witness* $w_l$: 67 | 68 | `Close(`$l$,$m$`)`→$w_l$ 69 | 70 | * *Verify* that the *seal* $l$ was closed over *message* $m$: 71 | 72 | `Verify(`$l$,$w_l$,$m$`)`→`bool` 73 | 74 | A single-use-seal implementation is secure if it is impossible for an attacker 75 | to cause the `Verify` function to return true for two distinct messages $m1$, 76 | $m2$, when applied to the same seal (it is acceptable, although non-ideal, for 77 | there to exist multiple witnesses for the same seal/message pair). 78 | 79 | Practical single-use-seal implementations will also obviously require some way 80 | of generating new single-use-seals. Secondly, authentication is generally 81 | useful. Thus we have: 82 | 83 | * *Generate* a new seal bound to pubkey p: 84 | 85 | `Gen(`$p$`)`→$l$ 86 | 87 | * *Close seal* $l$ over *message* $m$, authenticated by signature $s$ valid for 88 | pubkey $p$: 89 | 90 | `Close(`$l$,$m$,$s$`)`→$w_l$ 91 | 92 | Obviously, in the above, pubkey can be replaced by any cryptographic identity scheme, such as a Bitcoin-style predicate script, zero-knowledge proof, etc. 93 | 94 | * Finally, while some single-use-seal implementations MAY support the ability 95 | to prove that a seal is open, e.g. as of a given block height or point in 96 | time. This however is optional, and as it can be difficult to implement, 97 | it is suggested that seal-using protocols SHOULD avoid depending on this 98 | functionality existing. 99 | 100 | 101 | ## Trust 102 | 103 | An obvious single-use-seal implementation is to simply have a trusted notary, 104 | with each seal committing to that notary’s identity, and witnesses being 105 | cryptographic signatures produced by that notary. A further obvious refinement 106 | is to use disposable keys, with a unique private key being generated by the 107 | notary for each seal, and the private key being securely destroyed when the 108 | seal is closed. 109 | 110 | For a scalable, trust-minimized, single-use-seal implementation we can use a 111 | proof-of-publication ledger, where consensus over the state of the ledger is 112 | achieved in a trust-minimized manner (i.e. Bitcoin blockchain). 113 | 114 | 115 | ## Reference implementation 116 | 117 | The reference implementation is version `1.0` of 118 | [`single_use_seals` crate](single_use_seals), which is a part of the 119 | [client-side-validation library](client_side_validation) developed and 120 | maintained Dr Maxim Orlovsky at LNP/BP Strandards Association. 121 | 122 | If the implementation differs from the spec, the spec has a higher priority. 123 | 124 | 125 | ## References 126 | 127 | 1. Peter Todd. Preventing Consensus Fraud with Commitments and Single-Use-Seals 128 | 129 | 2. Peter Todd. Scalable Semi-Trustless Asset Transfer via Single-Use-Seals and 130 | Proof-of-Publication. 131 | 132 | 3. Peter Todd. Closed Seal Sets and Truth Lists for Better Privacy and 133 | Censorship Resistance. 134 | 135 | 4. Peter Todd. Building Blocks of the State Machine Approach to Consensus. 136 | 137 | 138 | 139 | ## Copyright 140 | 141 | This document is licensed under the Creative Commons CC0 1.0 Universal license. 142 | 143 | [single_use_seals]: https://crates.io/crates/single_use_seals 144 | [client_side_valudation]: https://crates.io/crates/client_side_validation 145 | -------------------------------------------------------------------------------- /lnpbp-0010.md: -------------------------------------------------------------------------------- 1 | # LNPBP-39: TxO seals 2 | 3 | ``` 4 | LNPBP: 0010 5 | Vertical: Bitcoin protocol 6 | Title: Bitcoin transaction output-based single-use-seals 7 | Authors: Dr Maxim Orlovsky , 8 | Peter Todd , 9 | Federico Tenga, 10 | Giacomo Zucco 11 | Comments-URI: 12 | Status: Proposal 13 | Type: Standards Track 14 | Created: 2019-05-12 15 | License: CC0-1.0 16 | ``` 17 | 18 | * [Abstract](#abstract) 19 | * [Background](#background) 20 | * [Motivation](#motivation) 21 | * [Design](#design) 22 | * [Specification](#specification) 23 | * [Terms and definitions](#terms-and-definitions) 24 | * [Seal definition](#seal-definition) 25 | * [Closing seal over a message](#closing-seal-over-a-message) 26 | * [Verification](#verification) 27 | * [Single-use-seal concealment](#single-use-seal-concealment) 28 | * [Strict encoding](#strict-encoding) 29 | * [Privacy considerations](#privacy-considerations) 30 | * [UTXO and TxO ownership](#utxo-and-txo-ownership) 31 | * [Chain analysis](#chain-analysis) 32 | * [Private data](#private-data) 33 | * [Compatibility](#compatibility) 34 | * [Version 1 transactions](#version-1-transactions) 35 | * [Pre-segwit outputs](#pre-segwit-outputs) 36 | * [Segregated witness v0](#segregated-witness-v0) 37 | * [Taproot](#taproot) 38 | * [Future segregated witness variants](#future-segregated-witness-variants) 39 | * [Bitcoin sidechains](#bitcoin-sidechains) 40 | * [Pay-to-address](#pay-to-address) 41 | * [Hardware wallets](#hardware-wallets) 42 | * [Software wallets](#software-wallets) 43 | * [Rationale](#rationale) 44 | * [Representation of transaction output numbers](#representation-of-transaction-output-numbers) 45 | * [Reference implementation](#reference-implementation) 46 | * [Acknowledgements](#acknowledgements) 47 | * [References](#references) 48 | * [Copyright](#copyright) 49 | * [Test vectors](#test-vectors) 50 | 51 | ## Abstract 52 | 53 | The proposal standardises single-use-seal-based cryptographic commitment scheme 54 | utilizing bitcoin blockchain and bitcoin transaction graph as a 55 | proof-of-publication medium, using bitcoin transaction outputs as seal 56 | definitions and spending bitcoin transactions as proofs of seal close and 57 | containers for a commitment to a message over which the seal is closed. 58 | The verification procedure requires storing part of the single-use-seal 59 | witness data on the client side (*extra-transaction proof*). 60 | 61 | ## Background 62 | 63 | Single-use-seal is a cryptographic commitment primitive originally proposed 64 | by Peter Todd in 2016 and standardized as LNPBP-8 standard. However, Here we 65 | define a specific commitment scheme based on that standard using bitcoin 66 | transactions. 67 | 68 | ## Motivation 69 | 70 | ## Design 71 | 72 | Bitcoin transaction output-based single-use-seals (TxOSUS) is a particular application of [single-use-seals](lnpbp-0006.md) to bitcoin transaction graph, either as a part of any bitcoin blockchain (longest PoW chain, federated sidechain etc) or state channel (Lightning network channel and other types of state channels), i.e. in terms of single-use-seals, seal medium is represented by a bitcoin transaction graph. 73 | 74 | The parties running protocol agree on some transaction output in any given bitcoin transaction graph as a place with special meaning ("seal"), and require that a future transaction spending this output ("witness transaction") contained a [deterministic bitcoin commitment](lnpbp-0008.md) to some a message. Any independent party having access to the transaction graph MUST: 75 | 76 | 1. not be able to detect the presence of the commitment in a given transaction graph (_hiding_ property of TxOSUS) even if the original message is known, 77 | 2. being provided information about specific protocol used for message commitments and access to deterministic bitcoin proof data (see [LNPBP-8](lnpbp-0008.md)) be able to verify the commitment such as it will be valid only and only for the message with which the original commitment was created (_verifiably_ property of TxOSUS). 78 | 79 | The defined procedure is not the only way in which bitcoin blockchain or transaction graph can be used as a seal medium for single-use seals (for instance, a seal may be defined as a first time some specific public key appears in the blockchain); however these options are not part of the current standard. 80 | 81 | ## Specification 82 | 83 | ### Terms and definitions 84 | 85 | **Seal** or **defined seal**: Bitcoin transaction outpoint: a combination of transaction identifier (consensus-defined double SHA256 hash of fully-signed valid bitcoin transaction) and transaction output number. Transaction output number MUST be represented as a 32-bit unsigned integer[1](lnpbp-0039.md#Representation-of-transaction-output-numbers). 86 | 87 | **Witness transaction**: transaction spending an output specified by a given seal. 88 | 89 | **Closed seal**: a seal for which a transaction spending output matching seal definition is known. This transaction MAY be part of longest block chain, or MAY not be a part of it (existing only within a Lightning network channel or as a part of any other off-chain transaction graph). It's up to particular implementation to decide whether such transaction (named **witness transaction**) should be considered valid or not; however this rules MUST require that the witness transaction MUST be a valid bitcoin transaction (i.e. it can be validated with libbitcoinconsensus or Bitcoin Core instance). 90 | 91 | ### Seal definition 92 | 93 | Defined seal consists of 256-bit consensus-defined double SHA-256 hash of a fully-signed valid bitcoin transaction and 32-bit transaction output index. 94 | 95 | Seal MUST be considered defined only and only all of transaction data are known, the transaction is fully signed and both transaction structure and signatures validated with bitcoin consensus rules using libbitcoinconsensus or Bitcoin Core. 96 | 97 | NP: Parties participating the protocol MUST agree on an implementatio-specific entropy used in deterministic bitcoin commiemtnes as required by [LNPBP-8](lnpbp-0008.md) and [LNPBP-3](lnpbp-0003.md) protocols. 98 | 99 | ### Closing seal over a message 100 | 101 | 1. Fully sign the transaction containing output acting as a defined seal. 102 | 2. Construct a transaction spending the transaction output defined by the seal. The transaction may have any number 103 | 3. Create a commitment to the message and embed it into the unsigned witness transaction with the deterministic bitcoin commitment embed procedure as defined in [LNPBP-8](lnpbp-0008.md), store the proof. 104 | 4. Fully sign the witness transaction. 105 | 106 | NB: Transactions and proof MUST be persisted for further verification procedure. 107 | 108 | ### Verification 109 | 110 | A party verifying that the seal is indeed closed over a message MUST run the following procedure: 111 | 112 | 1. Make sure that the seal definition is fully known, otherwise fail the verification. 113 | 2. Verify transaction containing the defined seal: 114 | * the transaction MUST be a valid bitcoin transaction; 115 | * the transaction MUST contain all transaction data required for it's verification; 116 | * bitcoin-defined consensus transaction identifier MUST correspond to the transaction identifier provided as a part of seal definition; 117 | * transaction output number contained in the seal definition MUST be present in transaction (i.e. transaction MUST contain exactly that numbers or more of trsansaciton outputs); 118 | * the transaction MUST be fully-signed for all of its inputs; 119 | * the transaction MUST signatures pass validation with bitcoin consensus rules using libbitcoinconsensus or Bitcoin Core. If any of these conditions are not met, fail the verification. 120 | 3. Verify the witness transaction spending the transaction output defined as the seal subjected to the current verification procedure: 121 | * the transaction MUST be a valid bitcoin transaction; 122 | * the transaction MUST contain all transaction data required for it's verification; 123 | * the transaction MUST spend transaction output defined as the seal verified by the current procedure; 124 | * bitcoin-defined consensus transaction identifier MUST correspond to the transaction identifier provided as a part of seal definition; 125 | * transaction output number contained in the seal definition MUST be present in transaction (i.e. transaction MUST contain exactly that numbers or more of trsansaciton outputs); 126 | * the transaction MUST be fully-signed for all of its inputs; 127 | * the transaction MUST signatures pass validation with bitcoin consensus rules using libbitcoinconsensus or Bitcoin Core. If any of these conditions are not met, fail the verification. 128 | 4. Verify the deterministic bitcoin commitment to the given message with the provided deterministic bitcoin commitment proof according to the [LNPBP-8](lnpbp-0008.md) procedure; fail the verification if this procedure fails. 129 | 130 | ### Single-use-seal concealment 131 | 132 | ### Strict encoding 133 | 134 | Any implementation of the standard MUST follow [strict encoding](../lnpbp-0007.md) rules, in particular 135 | 136 | Defined seal MUST be serialized as fixed-length 36 byte-long structure: 137 | 138 | * 32 bytes of transaction identifier encoded according to bitcoin transaction identifier consensus serialization rules in little-endian format 139 | * 4 bytes of transaction output in little-endian format 140 | 141 | Deterministic bitcoin commitment proofs MUST be serialized using strict encoding rules defined in [...]. 142 | 143 | There are no specific requirements to the message encoding or content; they MAY be defined as a part of other protocols using the current standard. 144 | 145 | Bitcoin transactions and their parts, when needed, MUST be serialized according to bitcoin consensus serialization rules (which MAY differ from strict encoding requirements). 146 | 147 | ## Privacy considerations 148 | 149 | ### UTXO and TxO ownership 150 | 151 | ### Chain analysis 152 | 153 | ### Private data 154 | 155 | ## Compatibility 156 | 157 | ### Version 1 transactions 158 | 159 | ### Pre-segwit outputs 160 | 161 | ### Segregated witness v0 162 | 163 | ### Taproot 164 | 165 | ### Future segregated witness variants 166 | 167 | ### Bitcoin sidechains 168 | 169 | ### Pay-to-address 170 | 171 | ### Hardware wallets 172 | 173 | ### Software wallets 174 | 175 | ## Rationale 176 | 177 | ### Representation of transaction output numbers 178 | 179 | While bitcoin normally uses VarInt to represent the number of transaction outputs that may be contained in a given transaction, it uses 32-bit unsigned integers to reference specific transaction output from other's transaction input. Even while with the current current block size limit the maximum number of transaction outputs that may be contained within a transaction is still below 2^16, we stick to the internal bitcoin transaction limits, which, in this case, is defined by transaction input structure (it's impossible to spend transaction output with index number >2^32). 180 | 181 | ## Reference implementation 182 | 183 | [https://github.com/LNP-BP/rust-lnpbp/tree/develop/src/bp/seals](https://github.com/LNP-BP/rust-lnpbp/tree/develop/src/bp/seals) 184 | 185 | ## Acknowledgements 186 | 187 | ## References 188 | 189 | ## Copyright 190 | 191 | This document is licensed under the Creative Commons CC0 1.0 Universal license. 192 | 193 | ## Test vectors 194 | -------------------------------------------------------------------------------- /lnpbp-0012.md: -------------------------------------------------------------------------------- 1 | ``` 2 | LNPBP: 0012 3 | Vertical: Bitcoin protocol 4 | Title: Tapret: taproot-based OP_RETURN deterministic bitcoin commitments 5 | Author: Dr Maxim Orlovsky , 6 | Peter Todd 7 | Comments-URI: https://github.com/LNP-BP/discussions 8 | Status: Draft 9 | Type: Standards Track 10 | Created: 2022-04-01 11 | Finalized: not yet 12 | License: CC0-1.0 13 | Related standards: LNPBP-4, BIP-341 14 | ``` 15 | 16 | - [Abstract](#abstract) 17 | - [Background](#background) 18 | - [Motivation](#motivation) 19 | - [Design](#design) 20 | - [Specification](#specification) 21 | - [Compatibility](#compatibility) 22 | - [Rationale](#rationale) 23 | - [Reference implementation](#reference-implementation) 24 | - [Acknowledgements](#acknowledgements) 25 | - [References](#references) 26 | - [Copyright](#copyright) 27 | - [Test vectors](#test-vectors) 28 | 29 | ## Abstract 30 | 31 | The proposal provides standard mechanism for creating, structuring & verifying 32 | deterministic bitcoin commitments, which puts the commitment in a leaf tapscript 33 | with `OP_RETURN` opcode in the taproot script tree. 34 | 35 | ## Background 36 | 37 | TBD 38 | 39 | ## Motivation 40 | 41 | TBD 42 | 43 | ## Design 44 | 45 | Tapret commitment is structured as an `OP_RETURN`-based script, containing the 46 | commitment to the LNPBP-4 message, constructed under multiple protocols. The 47 | commitment script (**tapret leaf script**) always consists of 48 | [64 bytes][why-64-bytes]. 49 | 50 | The leaf with the tapret leaf script is always put into the same depth of the 51 | taproot script tree, and this [depth is 1][why-depth-1] (in 0-based indexing of 52 | depth levels, where depth 0 corresponds to the merkle tree root). The commitment 53 | is always put into the rightmost node of the tree by using consensus ordering 54 | of the nodes, as it is defined in BIP-341 merkle path construction 55 | (lexicographic ordering). This precise definition of the possible place of the 56 | commitment allows to prove the uniqueness of the commitment, i.e. the absence of 57 | any alternative tapret commitment in the same tree. 58 | 59 | If at depth 7 in the rightmost position of the tree another taproot node is 60 | present (either leaf script or branch), an additional branch node is created 61 | with both tapret leaf script and the parent of the rightmost depth-7 node 62 | becoming its children. This new branch node is added instead of the original 63 | parent at depth 6, efficiently shifting the previous subtree from that position 64 | one level down. 65 | 66 | If the original taproot script tree does not have depth 7 nodes on its 67 | right-side (in terms of consensus lexicographic ordering of each branch child 68 | hashes), a subtree (**tapret subtree**) consisting of repeated tapret script 69 | leaves is created and inserted at the depth of the last node of the tree on the 70 | right-side merkle path. The height of the subtree is selected to put the taproot 71 | script leaves at depth 7. 72 | 73 | Since addition of the new node will change the merkle hashes of all its parents, 74 | and the merkle hash value is used in the lexicographic ordering of the tree, 75 | this operation with `1 - 1/(2 ^ 7) = 99.22%` probability will make just inserted 76 | tapret subtree merkle root to be non-rightmost node of the modified tree. Since 77 | the deterministic nature of the tapret commitments requires ability to prove the 78 | absence of any alternative commitment in the same tree, two components are used 79 | to keep the determinism of the commitment position and ability to prove its 80 | uniqueness. 81 | 82 | First, a special one-byte variable (nonce) is added to the taproot leaf script, 83 | which allows "mining" the hash value in a way that the added subtree will 84 | appear at the right-side of the tree. At depth 7 there might be only 2^7=128 85 | possible tree position, and 256 iterations (per one nonce value) should be 86 | enough to solve the issue. 87 | 88 | Second, if it was not possible to solve the issue with the nonce, a special 89 | **uniqueness proof** is produced, which ensures that none of the nodes at 90 | depth 7 on the right side of the tree does not contain alternative commitment. 91 | This proof includes leaf script (for leaf nodes) or two child node hashes 92 | (for branch nodes) for each of the nodes right to the tapret leaf script. 93 | 94 | The tapret commitment is put into a transaction output `scriptPubkey` as a 95 | modified BIP-341 output key value, which is produced from the same internal key 96 | and new merkle root of the taproot script tree containing the embedded tapret 97 | commitment. The number of the transaction output with the commitment, if 98 | multiple taproot outputs are present in the same transaction, must be 99 | deterministically defined by an upper-level protocol using the present tapret 100 | commitment scheme. 101 | 102 | Internal key value, merkle proof and uniqueness proof are combined to construct 103 | **tapret proof**, passed to the validators as off-chain data for 104 | client-side validation. 105 | 106 | 107 | ## Specification 108 | 109 | ### Tapret proof 110 | 111 | Tapret proof must consist of the following data, serialized exactly in the 112 | given order: 113 | 1. 32 bytes: internal key value, representing x-only public key serialized 114 | according to BIP-341; 115 | 2. 1 byte: **nonce value** used in constructing tapret script; 116 | 3. 1 byte: number `n` of merkle proof elements (see below), must be in range 117 | `0..=7`, otherwise the proof must be considered invalid; 118 | 4. `n*32` bytes: sequence of **merkle proof** elements, ordered by their depth 119 | in the tree. Each of the elements consists of 32 bytes representing hash of 120 | the taproot script tree hashing partner; 121 | 5. 1 byte: number `u` of uniqueness proof elements (see below), must be less or 122 | equal to `2^(n+1) - 2`, otherwise the proof must be considered invalid; 123 | 6. sequence of `m` **uniqueness proofs**, each consisting of: 124 | 6.1. 1 byte: proof type, either `0x00`, `0x01` or `0x02`. The proof type 125 | defines length of the proof data and their semantic meaning: 126 | 6.1. the proof type `0x00` (called `empty`) means that node is absent at the 127 | depth 7. The proof type is followed by one byte indicating the depth of 128 | the last script leaf present in the tree, followed by the structure 129 | described in pt. 6.3. below; 130 | 6.2. for the proof type `0x01` (called `branch`) two 32-byte hash values 131 | are given; these hash values represents hashes of taproot script 132 | tree nodes; 133 | 6.3. for the proof type `0x02` (called `leaf`) a following structure is used: 134 | 6.3.1. 1 byte containing script leaf version, 135 | 6.3.2. 2 bytes containing script length `l` in little endian encoding, 136 | 6.3.3. `l` bytes of raw leaf script data. 137 | 138 | 139 | ### Tapret verification 140 | 141 | First, a **tapret script leaf** is constructed. The version of the script must 142 | be `0xC0` (tapscript) and the script must be equal to the byte sequence (in hex) 143 | `FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF016A20` 144 | followed by a 32-byte serialization of LNPBP-4 multiprotocol commitment. 145 | The provided byte sequence represent tapscript consisting of 28 146 | `OP_INVALIDOPCODE`, followed by `OP_PUSHBYTES_1`, nonce byte (taken from tapret 147 | proof), `OP_RETURN` and `OP_PUSHBYTES_32` op-codes[^why-64-bytes]. 148 | 149 | Then, **tapret subtree** is constructed from the *tapret script leaves*. The 150 | tree should be a valid taproot script tree under BIP-341 standard, consisting of 151 | `8-n` depth levels, where at depth = 7 (for zero-based depth indexing, 152 | representing merkle root level) the subtree must contain `2^(7-n)` *tapret 153 | script leaves*. For the edge case of `n=7` the subtree must consist of a single 154 | *tapret script leaf* which `TapLeaf`-tagged hash will be the hash of the subtree 155 | merkle root. 156 | 157 | The merkle root hash of the *tapret subtree* is used together with the provided 158 | node hash partner values from the perkle proof data of the tapret proof to 159 | receive the final merkle tree root value. Combined with the value of the 160 | internal key from the tapret proof according to BIP-341 algorithm it must 161 | produce exactly the same output key value as present in the `scriptPubkey` of 162 | the transaction output containing the commitment; otherwise validation procedure 163 | fails. 164 | 165 | Finally, the validity of the uniqueness proof must be checked. The uniqueness 166 | proof data are used to reconstruct each and all the right-side merkle tree 167 | hashing partners, which must match the exact number and values of the hasing 168 | partners from the merkle proof, which values were grater than the value of the 169 | parent of the tapret leaf script at that depth. If this procedure fails, the 170 | validation procedure must fail. 171 | 172 | 173 | ### Tapret construction 174 | 175 | TBD 176 | 177 | ## Compatibility 178 | 179 | TBD 180 | 181 | ## Reference implementation 182 | 183 | 184 | 185 | ## Rationale 186 | 187 | ### Tapret proof size estimation 188 | 189 | Due to the use of nonce "mining" mechanism, in the most of cases the proof size 190 | should not exceed 290 bytes. Since the most of the taproot script trees will not 191 | have a depth more than 1 or 2, the actual size in these cases will be 66 or 98 192 | bytes. 193 | 194 | ### Why 64 byte tapscript 195 | 196 | This allows distinguishing of tapret leaf script from a data used in production 197 | of taproot branch hash, such that the proof of the absence of an alternative 198 | tapret commitment can be validated by simple comparison of the first of the 199 | child node hashes to the tapret leaf script prefix. 200 | 201 | ### Why script depth 1 202 | 203 | This helps to keep client-side-validated proof size smaller. 204 | 205 | 206 | ## Acknowledgements 207 | 208 | TBD 209 | 210 | ## References 211 | 212 | TBD 213 | 214 | ## Copyright 215 | 216 | This document is licensed under the Creative Commons CC0 1.0 Universal license. 217 | 218 | ## Test vectors 219 | 220 | TBD 221 | 222 | [why-64-bytes]: #why-64-byte-tapscript 223 | [why-depth-1]: #why-script-depth-1 224 | -------------------------------------------------------------------------------- /lnpbp-0037.md: -------------------------------------------------------------------------------- 1 | ``` 2 | LNPBP: 0037 3 | Vertical: Smart contracts 4 | Title: Invoicing formats for RGB-20 fungible assets schema 5 | Authors: Alekos Filini 6 | Comments-URI: hhttps://github.com/LNP-BP/LNPBPs/pull/23 7 | Status: Rejected 8 | Type: Standards Track 9 | Created: 2020-04-02 10 | License: CC0-1.0 11 | ``` 12 | 13 | > Note: This standard has been superseded by [LNPBP-38 Universal LNP/BP invoices](https://github.com/LNP-BP/invoices) due to incompatibility with Lightning, Coinjoin, and consignment metadata. 14 | 15 | - [Abstract](#abstract) 16 | - [Background](#background) 17 | - [Motivation](#motivation) 18 | - [Specification](#specification) 19 | - ["On-Chain" Addresses](#on-chain-addresses) 20 | - [UTXO-based addresses](#utxo-based-addresses) 21 | - [Extended Variant](#extended-variant) 22 | - [Short Variant](#short-variant) 23 | - [Lightning Invoices](#lightning-invoices) 24 | - [Compatibility](#compatibility) 25 | - [Rationale](#rationale) 26 | - [UTXO-based addresses](#utxo-based-addresses-1) 27 | - [Reference implementation](#reference-implementation) 28 | - [Acknowledgements](#acknowledgements) 29 | - [References](#references) 30 | - [Copyright](#copyright) 31 | - [Test vectors](#test-vectors) 32 | 33 | 34 | ## Abstract 35 | 36 | This work proposes a way to levearge existing standards on Bitcoin and the Lightning Network to embed 37 | extra details related to assets and other protocol-specific informations into payment URIs and Lightning invoices. 38 | 39 | 40 | ## Background 41 | 42 | Bitcoin addresses by themselves sometimes are not enough to convey all the necessary informations about a payment. A 43 | merchant might want to get paid a specific amount, or in the case of Lightning they might want to ask the payer to 44 | use a specific route over the nodes graph. For this reason, standards have been developed to encode these extra 45 | details in a way that could be easily encoded as a text string or in a QR code. 46 | 47 | Specifically, BIP-21[1] describes a way to create a "payment URI" given a Bitcoin address and some extra customizable 48 | parameters like an amount, while BOLT-11[3] describes a way to encode a large number of fields into single, relatively 49 | long, strings of text, normally called "invoices". 50 | 51 | This standard builds on top of them to extend their capabilities to multiasset protocols. 52 | 53 | 54 | ## Motivation 55 | 56 | Multiasset protocols generally needs to embed more informations into a payment URI or invoice, compared to Bitcoin: above 57 | everything some kind of asset identifier, which is implicit in Bitcoin invoices because it's the only asset that is 58 | natively part of the network. 59 | 60 | Other more complex protocols like RGB also need extra parameters to help payer and payee connect to each other and 61 | exchange the client-validated part of the data. 62 | 63 | ## Specification 64 | 65 | ### "On-Chain" Addresses 66 | 67 | Given a Bitcoin address and an `asset-identifier`, the payment invoice is generated by following the procedure 68 | describted by BIP-21[1], with the following changes: 69 | 70 | 1. The URI prefix MUST be unique and represent the asset protocol, like `rgb`. 71 | 2. The `asset-identifier` MUST be present, and it should be encoded as a Base58[5] string **without** checksum. 72 | 73 | Optionally, like in any normal BIP-21 URIs, an `amount` field can be added. If present, the `amount` MUST be encoded 74 | as a floating-point number with the precision factor already applied, if the assets protocol supports it. 75 | 76 | Any other protocol-specific field can be added as described in BIP-21, with or without the `req-` prefix depending on 77 | whether or not the field should be considered "required". 78 | 79 | Specifically, the RGB protocol defines an extra field `req-endpoint` that indicates where the sender is supposed to 80 | upload the client validated history of the tokens. It should be equal to a V2 or V3 Tor onion endpoint, optionally 81 | followed by an explicit port if the listening server is running on a non-standard port. 82 | 83 | #### UTXO-based addresses 84 | 85 | Assets protocols that support a "send-to-existing-utxo" feature, can replace the Bitcoin address with a representation 86 | of said UTXO. For this purpose, this standard also defines a new type of address encoded in two possible ways: 87 | 88 | ##### Extended Variant 89 | 90 | 1. Encode the `txid` in the network binary format (reverse of the hex string usually displayed) in a temporary buffer. 91 | 2. Append the `vout` encoded as a 32 bit long unsigned big endian integer. 92 | 3. Encode the 36-byte long buffer as a Bech32 address, as specified in BIP-173[2], using the human-redable part of 93 | the network where the UTXO is defined and a witness version of `0`. 94 | 95 | ##### Short Variant 96 | 97 | 1. Generate the LNPBP-0005[4] identifier for the UTXO and represent it as a 64 bit long unsigned big endian. 98 | integer in a temporary buffer. 99 | 2. Encode the 8-byte long buffer as a Bech32 address, as specified in BIP-173[2], using the human-redable part of 100 | the network where the UTXO is defined and a witness version of `0`. 101 | 102 | ### Lightning Invoices 103 | 104 | Assets-aware Lightning network invoices should be generated like any normal BOLT-11[3] invoice, with the following 105 | changes: 106 | 107 | 1. The human readable part MUST be `ln + `. 108 | 2. An extra tagged field with type `a` MUST be present, and MUST be set to the binary representation of the 109 | `asset-identifier` 110 | 3. Optional fallback addresses (`f` fields) MAY be present and they MAY contain UTXO-based addresses, if the assets 111 | protocol supports them. Any other field that would normally be required by the specific asset protocol in its 112 | "On-Chain Addresses" MUST also be added with a unique field type defined by the protocol. 113 | 114 | Specifically, the RGB protocol requires an extra field tagged with `e` (endpoint) if at least one `f` field is present, 115 | serialized in a string as described in the "On-Chain Address" part of this standard. Multiple `e` fields MAY be 116 | specified in an implied preferred order. 117 | 118 | 119 | ## Compatibility 120 | 121 | This protocol is somewhat a generalization of the Bitcoin and Lightning counterparty, and while it tries to be very 122 | similar both implementation-wise and end-result-wise (to look more familiar to people already using the existing 123 | protocols), some changes make it incompatible with existing standards. This acts as an extra precaution to avoid loss 124 | of funds from people that might mistake a Bitcoin URI with an asset-enabled one. 125 | 126 | 127 | ## Rationale 128 | 129 | ### UTXO-based addresses 130 | 131 | UTXO-based addresses are encoded exactly like standard Bech32 addresses with witness version of 0 (more commonly known 132 | as P2WPKH and P2WSH), however this proposal doesn't conflict in any way with them because, because neither of them has 133 | the same length as one of the existing type of addresses. From BIP-173[2]: 134 | 135 | > Decoders SHOULD enforce known-length restrictions on witness programs. For example, BIP141 specifies If the version 136 | > byte is 0, but the witness program is neither 20 nor 32 bytes, the script must fail. 137 | 138 | Introducing this new types of addresses of length 36 and 8 is in fact safer than bumping the version number and 139 | potentially have a conflict with a future upgrade of Bitcoin. 140 | 141 | ## Reference implementation 142 | 143 | 144 | ## Acknowledgements 145 | 146 | * Dr Maxim Orlovsky and Giacomo Zucco for the extensive conversation that led to this proposal. 147 | 148 | 149 | ## References 150 | 151 | 1. Nils Schneider, Matt Corallo. BIP-21: URI Scheme. 152 | 2. Pieter Wuille, Greg Maxwell. BIP-173: Base32 address format for native v0-16 witness outputs. 153 | 154 | 3. BOLT#11: Invoice Protocol for Lightning Payments 155 | 156 | 4. Dr Christian Decker, Dr Maxim Orlovsky. LNPBP-5: Universal short Bitcoin identifiers for blocks, transactions 157 | and transaction inputs & outputs. 158 | 5. Base58 Encoding Format. 159 | 160 | 161 | ## Copyright 162 | 163 | This document is licensed under the Creative Commons CC0 1.0 Universal license. 164 | 165 | 166 | ## Test vectors 167 | 168 | TBD 169 | -------------------------------------------------------------------------------- /lnpbp-0046.md: -------------------------------------------------------------------------------- 1 | ``` 2 | LNPBP: 0046 3 | Vertical: Lightning network protocol 4 | Title: Deterministic derivation paths for LNP 5 | Author: Dr Maxim Orlovsky , 6 | Comments-URI: https://github.com/LNP-BP/LNPBPs/pull/120 7 | Status: Draft 8 | Type: Standards Track 9 | Created: 2021-12-07 10 | Finalized: not yet 11 | Based on: BIP-32, BIP-43, BOLT-3 12 | License: CC0-1.0 13 | ``` 14 | 15 | - [Abstract](#abstract) 16 | - [Background](#background) 17 | - [Motivation](#motivation) 18 | - [Design](#design) 19 | - [Specification](#specification) 20 | - [Compatibility](#compatibility) 21 | - [c-Lightning](#c-lightning) 22 | - [LND](#lnd) 23 | - [Eclair](#eclair) 24 | - [LNP Node](#lnp-node) 25 | - [Electrum](#electrum) 26 | - [Rationale](#rationale) 27 | - [Choice of `9735h` for BIP-43 purpose](#choice-of-9735h-for-bip-43-purpose) 28 | - [Use of channel ids for channel basepoint derivation](#use-of-channel-ids-for-channel-basepoint-derivation) 29 | - [Selection of bits for channel basepoint](#selection-of-bits-for-channel-basepoint) 30 | - [Use of unhardeded derivation between basepoints](#use-of-unhardeded-derivation-between-basepoints) 31 | - [Shutdown key derived from funding wallet](#shutdown-key-derived-from-funding-wallet) 32 | - [Using unhardened indexes for per-commitment points](#using-unhardened-indexes-for-per-commitment-points) 33 | - [Reference implementation](#reference-implementation) 34 | - [Acknowledgements](#acknowledgements) 35 | - [References](#references) 36 | - [Copyright](#copyright) 37 | - [Test vectors](#test-vectors) 38 | 39 | 40 | ## Abstract 41 | 42 | The proposal standardizes derivation paths used by lightning nodes, for both 43 | BOLT-compatible and Bifrost networks. 44 | 45 | 46 | ## Background 47 | 48 | BOLT-3 define a number of "basepoints" - public and private keys used 49 | in channel transaction construction and the rules for derivation of the 50 | specific keys for each of the transactions out of the basepoint set. 51 | 52 | This proposal fills in the gap of how these basepoints may be deterministically 53 | derived from a single extended key. 54 | 55 | 56 | ## Motivation 57 | 58 | A standard for deterministic derivation of keys used in channel transaction 59 | construction will allow users to always recover the whole information out of a 60 | seed phrase independently from a specific node implementation used for channel 61 | creation. 62 | 63 | 64 | ## Design 65 | 66 | We define a **extended lightning key** as an extended master private key used for 67 | all derivations of channel basepoints, funding wallet and **node key**. This key is 68 | derivable from the extended master key / seed phrase using a specific derivation 69 | path purpose value `9735'`. 70 | 71 | 72 | ## Specification 73 | 74 | **Extended lightning key** should be derived from a extended master key using 75 | the following derivation path: 76 | 77 | `m/9735'/` 78 | 79 | where `9735'` is a BIP-43 purpose field reserved for this standard. 80 | 81 | **Node key** is derived from the *extended lightning key* using 82 | `/chain'/0'/node_index'` derivation, where `chain'` is a hardened index 83 | specifying blockchain operated by the node, and `node_index'` is a hardened 84 | incremental index for the node among all nodes managed by a seed owner. 85 | 86 | **Channel basepoint** is derived from the *extended lightning key* using 87 | `/chain'/1'/ln_ver'/channel'` derivation, where: 88 | - `channel'` is a hardened index constructed from the *initial channel id* 89 | most significant bits starting from 1 to 32 using zero-based indexing. 90 | For BOLT-defined lightning channels *initial channel id* is the temporary 91 | channel id value; for Bifrost channel it is the channel id value. 92 | - `ln_ver'` is a hardened index set to `0'` for BOLT-defined lightning channels 93 | and `1'` for Bifrost channels. 94 | 95 | Derivation paths for the base points are the following: 96 | 97 | Basepoint name | Derivation suffix | Full derivation path 98 | -------------- | ------------------------------------------- 99 | Funding | `/0` | `m/9735'/chain'/1'/ln_ver'/channel'/0` 100 | Payment | `/1` | `m/9735'/chain'/1'/ln_ver'/channel'/1` 101 | Delayed | `/2` | `m/9735'/chain'/1'/ln_ver'/channel'/2` 102 | Revocation | `/3` | `m/9735'/chain'/1'/ln_ver'/channel'/3` 103 | Per-commitment | `/4/*` | `m/9735'/chain'/1'/ln_ver'/channel'/4/0` 104 | HTLC | `/5` | `m/9735'/chain'/1'/ln_ver'/channel'/5` 105 | PTLC | `/6` | `m/9735'/chain'/1'/ln_ver'/channel'/6` 106 | 107 | **Funding wallet** used for keeping funds by a lightning node for 108 | constructing funding transactions is derived with 109 | `/chain'/2'/case/index` path, where `case` is an equivalent of `change` field 110 | with RGB extensions (see ___) and `index` is a sequential index number. 111 | 112 | Example of extended keys used by lightning node #0 on bitcoin network 113 | for a BOLT-defined channel with temporary channel id 114 | `2938ce5c0cae4b2af072065dc7dcea68de5e3de0c936742e27e045c8650c6a79`: 115 | 116 | Extended keys | Derivation 117 | ------------------------ | ----------- 118 | Lightning key | `m/9735'/` 119 | Node key | `m/9735'/0'/0'/0'` 120 | Channel basepoint | `m/9735'/0'/1'/0'/691588700'` (index equals to `0x2938ce5c`) 121 | Per-commitment points | `m/9735'/0'/1'/0'/691588700'/4/` 122 | Funding wallet | `m/9735'/0'/2'/0/*` 123 | Funding wallet change | `m/9735'/0'/2'/1/*` 124 | Shutdown | `m/9735'/0'/2'/2/*` 125 | Funding wallet RGB20 | `m/9735'/0'/2'/200/*` 126 | RGB20 change | `m/9735'/0'/2'/201/*` 127 | Shutdown RGB20 | `m/9735'/0'/2'/202/*` 128 | 129 | Please note that the channel shutdown key is derived from a funding wallet - 130 | and not from a channel basepoint. 131 | 132 | 133 | ## Compatibility 134 | 135 | TBD: investigate derivation paths used by specific lightning nodes 136 | 137 | ### c-Lightning 138 | 139 | ### LND 140 | 141 | ### Eclair 142 | 143 | ### LNP Node 144 | 145 | LNP Node is fully compatible with the standard 146 | 147 | ### Electrum 148 | 149 | 150 | ## Rationale 151 | 152 | ### Choice of `9735h` for BIP-43 purpose 153 | 154 | BIP-43 defines that new purposes must be created with new BIPs and their 155 | hardened index representations must match that BIP number. Since we this 156 | standard is created before BIP proposal for a new purpose, we need to 157 | choose some large number which will not be used by BIPs in a foreseable 158 | future. `9735` is the unicode character value for lightning (☇) also used 159 | as a port number in lightning network. 160 | 161 | ### Use of channel ids for channel basepoint derivation 162 | 163 | Channels may be created asynchronously and it is hard to get sequential 164 | numbering within the lightning node. Also, if the node data are lost, it will 165 | be hard to guess which channel had which sequence index. Thus, the only way to 166 | get a channel-specific derivation index is to use some of channel id bits. 167 | 168 | We can't use channel funding transaction id since it will be known only upon 169 | key derivation. 170 | 171 | ### Selection of bits for channel basepoint 172 | 173 | We can use only 31 bits, since the most significant bit of derivation index is 174 | occupied by hardering flag (see BIP-32). We start with the second most 175 | significant channel bit to make it easy visually compare index with channel id 176 | without any bit shifts. 177 | 178 | ### Use of unhardeded derivation between basepoints 179 | 180 | Each channel is derived with hardened derivation, which allows to separate 181 | node from channels: if a node-level extended public – or even extended private 182 | key is leaked, it still be impossible to guess from the key information which 183 | channels ere created or closed with that node. From the other hand, if one 184 | needs to disclose the full information about the channel transaction it will 185 | be sufficient to have a single extended public key for **channel basepoint** 186 | to derive all other public keys any channel transaction. 187 | 188 | ### Shutdown key derived from funding wallet 189 | 190 | Funding wallet may be a separate process - or separate cold wallet, isolated 191 | from the rest of the lightning node. Deriving shutdown key from funding wallet 192 | allows it to use funds from closed channels for funding new channels without 193 | the need for additional interactivity with the lightning node. 194 | 195 | ### Using unhardened indexes for per-commitment points 196 | 197 | This allows user to reconstruct channel history without the need to access channel 198 | extended private key. 199 | 200 | 201 | ## Reference implementation 202 | 203 | The reference implementation of this derivation standard is done in a 204 | [LNP Core Library](https://github.com/LNP-BP/lnp-core) as a part of 205 | `legacy::channel::Keyset`, `bifrost::channel::Keyset` and `NodeAccount` 206 | structures. 207 | 208 | 209 | ## Acknowledgements 210 | 211 | 212 | ## References 213 | 214 | 215 | ## Copyright 216 | 217 | This document is licensed under the Creative Commons CC0 1.0 Universal license. 218 | 219 | 220 | ## Test vectors 221 | 222 | -------------------------------------------------------------------------------- /lnpbp-0050.md: -------------------------------------------------------------------------------- 1 | ``` 2 | LNPBP: 0050 3 | Vertical: Lightning network protocol 4 | Title: Bifrost: generalized Lightning network protocol core 5 | Author: Dr Maxim Orlovsky 6 | Comments-URI: https://github.com/LNP-BP/lnpbps/pulls/97 7 | Status: Draft 8 | Type: Standards Track 9 | Created: 2021-11-01 10 | Finalized: not yet 11 | License: CC0-1.0 12 | ``` 13 | 14 | - [Abstract](#abstract) 15 | - [Background](#background) 16 | - [Motivation](#motivation) 17 | - [Design](#design) 18 | - [Specification](#specification) 19 | - [Announcing Bifrost connectivity](#announcing-bifrost-connectivity) 20 | - [Bifrost URLs](#bifrost-urls) 21 | - [Bifrost initiation from legacy Lightning messaging](#bifrost-initiation-from-legacy-lightning-messaging) 22 | - [Establishing connection](#establishing-connection) 23 | - [Compatibility](#compatibility) 24 | - [Channels](#channels) 25 | - [Invoices](#invoices) 26 | - [Rationale](#rationale) 27 | - [Use of dedicated port](#use-of-dedicated-port) 28 | - [Why URL uses plus instead of at symbol](#why-url-uses-plus-instead-of-at-symbol) 29 | - [Using local features](#using-local-features) 30 | - [Feature bit selection](#feature-bit-selection) 31 | - [Reference implementation](#reference-implementation) 32 | - [Acknowledgements](#acknowledgements) 33 | - [References](#references) 34 | - [Copyright](#copyright) 35 | - [Test vectors](#test-vectors) 36 | 37 | ## Abstract 38 | 39 | 40 | ## Background 41 | 42 | 43 | ## Motivation 44 | 45 | Extending existing lightning network messaging system, defined as part of 46 | multiple BOLTs, is hard. The first problem is the necessity to introduce changes 47 | to multiple independent standards for each atomic feature; making review and 48 | acceptance process very time-consuming. Next, it is hard to implement these 49 | features one by one, since they are defined in different places. Finally, there 50 | is no place to put feature-specific test vectors in the existing BOLT structure. 51 | 52 | The second problem is separation of new and not yet well tested/experimental 53 | functionality from the well-tested existing lightning network core. The 54 | separation of experimental protocols and existing tested core functionality is 55 | good from the security point of view. 56 | 57 | The third reason is the fact that Lightning network was designed as a payment 58 | network and for payment purposes. At the same time, it is possible to create 59 | much more advanced forms of non-payment state channels basing on bitcoin 60 | transactions (useful for storage and different forms of financial smart 61 | contracts), or use lightning network for non-payment data communication (like 62 | messaging or DEX). These extensions when put into existing LN spec framework, 63 | not suited for such extensibility, will require constant introduction of 64 | multiple hacks or complete refactoring of the BOLT specifications. 65 | 66 | Finally, some of lightning network design decisions were proven to be 67 | non-efficient in context of more broad applications, for instance use of BigInt 68 | encoding is not advised for client-side-validated data […]. It will be 69 | impossible to fix such issues without introducing new network communication 70 | protocol. 71 | 72 | Bifrost is a proposed new set of standards, defined as a part of LNPBP standards 73 | suite, that includes extensible core networking protocol (LNPBP-50, this 74 | specification), and specific extensions for different forms of state channel 75 | management and network data communications. Current standard is built on top of 76 | other LNPBP standards (like strict encoding), BIPs (partially signed bitcoin 77 | transactions), parts of BOLT standards (Noise_XK protocol), extracted as a 78 | separate LNPBP standards, and puts them into a single well-abstracted protocol 79 | suite. 80 | 81 | 82 | ## Design 83 | 84 | Design goals: 85 | 1. Extensibility, including 86 | - support for non-payment / custom lightning channels 87 | - support for non-payment network messaging & communications 88 | - support for arbitrary extension of channel transaction structure 89 | (combining different types of channels) 90 | - support for custom / new route discovery mechanisms 91 | 2. Maximal use of existing LNPBP standards, in particular 92 | - LNPBP-7 commitments for structural and hierarchical data […] 93 | - LNPBP-9 client-side-validation […] 94 | - LNPBP-15 Noise_XK handshake & network encryption (BOLT-8 extract) […] 95 | - LNPBP-18 Native message framing (BOLT-8 extract) […] 96 | - LNPBP-16 handshake over WebSockets […] 97 | 3. Privacy: improved re-use of onion messaging from Lightning network 98 | 99 | 100 | ## Specification 101 | 102 | Bifrost operates using TCP connection, on top of LNPBP-15 (session & encryption 103 | layer) and LNPBP-18 (message framing layer) as application protocol. Default 104 | port for Bifrost connection is 9913 (see [rationale](#use-of-dedicated-port)). 105 | 106 | All message fields are encoded with strict encoding instead of other types of 107 | encoding used in BOLTs / legacy Lightning network. 108 | 109 | ### Announcing Bifrost connectivity 110 | 111 | Support for Bifrost protocol can be announced as a part of local features flag 112 | ([see why not global](#using-local-features)) in legacy lightning network `init` 113 | message, inside `node_announcement`, `channel_announcement` and `channel_update` 114 | messages (`INC` context in terms of BOLT-9). Bifrost feature flags should not be 115 | used with BOLT-11 invoices; instead, all Bifrost channels MUST use LNPBP-38 116 | invoicing. 117 | 118 | Since BOLT-9 provides no ability to add arbitrary feature flags from outside of 119 | the BOLT-defined protocol scope, this feature will be a non-standard. We reserve 120 | flag number 255/256 for it (see [rationale](#feature-bit-selection)). 121 | 122 | 123 | ### Bifrost URLs 124 | 125 | Bifrost URLs are designed to be compliant with RFC 3986 [1] and consists of 126 | `bifrost` as *scheme name*, *authority* in form of node public key, combined 127 | with optional network address details, channel id as a *path* and feature 128 | parameters and route suggestion as *query*, where both *path* and *query* parts 129 | are optional (emphasized words stand for RFC 3986-defined terms): 130 | 131 | `://[/][?]` => 132 | `bifrost://[/][? | ]` 133 | 134 | Host part MUST always include node public key, optionally followed by either 135 | IPv4, IPv6 or ONION v3 Tor address. IPv4 and IPv6 addresses may include optional 136 | port number, which becomes mandatory if a non-standard Bifrost port is used. The 137 | address, if present, MUST be separated from the public key by `+` symbol (see 138 | [rationale](#why-URL-uses-plus-instead-of-at-symbol)). 139 | 140 | `bifrost://[+ [:] | ]/[][? | ]` 141 | 142 | Example: 143 | 144 | - Node with a known IPv4 address operating non-standard port: 145 | `bifrost://02b39e7040cd9233e1cf86823ea321c1c799534c622c9e8b563a689409962657c7+124.155.54.210:9935` 146 | 147 | - Node with Onion v3 address and path suggestion: 148 | `bifrost://02b39e7040cd9233e1cf86823ea321c1c799534c622c9e8b563a689409962657c7+worldehc62cgugrgj7oc76tcna45fme47oqjrei4d4aa7xorw7fyvcyd/?` 149 | 150 | 151 | ### Bifrost initiation from legacy Lightning messaging 152 | 153 | Two nodes connected via Lightning network may send each other specific message 154 | indicating intent to open Bifrost connection. The message uses onion routing, 155 | enabling NAT bypassing, such that a party without NAT may “hole punch” NAT of 156 | another party by asking to establish Bifrost connection to its explicit IP 157 | address. 158 | 159 | ### Establishing connection 160 | 161 | 162 | 163 | 164 | ## Compatibility 165 | 166 | ### Channels 167 | 168 | Bifrost may be used to operate channels created using legacy Lightning network 169 | protocols – until there are changes into the channel structure which make them 170 | incompatible with existing BOLT specifications. Also, channels created with 171 | Bifrost can be accessed via legacy lightning network until they become 172 | incompatible (in their structure) with BOLT specifications. 173 | 174 | Thus, to prevent undefined behavior, it is advised that nodes will maintain each 175 | channel either under legacy LN or under Bifrost using the following rules: 176 | 177 | 1. If the channel was created in legacy LN it can be moved into Bifrost once and 178 | only once – and a dedicated gossip `channel_update` message must be published 179 | to the legacy LN with Bifrost even flag set. 180 | 181 | 2. If the channel was created in Bifrost network, it MAY be announced in the 182 | legacy LN only with odd (required) Bifrost flag set. 183 | 184 | 3. Bifrost channels can’t be operated using legacy LN messaging; a node 185 | receiving message referencing to a Bifrost server over the legacy LN MUST 186 | respond with `error` message. 187 | 188 | 4. Legacy LN channels MUST not be operated from Bifrost network before their 189 | movement according to the pt. 1. A node receiving Bifrost message for legacy 190 | LN channel MUST respond with `error` message. 191 | 192 | In order to enable fallback for Bifrost-managed channels in case of bugs 193 | discovered in Bifrost, the following rules SHOULD be supported by Lightning 194 | node implementations, but SHOULD not be used until a fallback scenario: 195 | 196 | 5. Bifrost channels which maintain BOLT compatibility can be moved back into 197 | legacy Lightning network by properly announcing removal of the channel in 198 | Bifrost network – and publishing `channel_announcement` (for previously 199 | non-announced channels) or `channel_update` gossip messages with all Bifrost 200 | feature flags removed 201 | 202 | ### Invoices 203 | 204 | All bifrost-operated channels MUST use LNPBP-38 invoices. BOLT-11 invoices MUST 205 | NOT be created for any channel which was moved into Bifrost network. 206 | 207 | 208 | ## Rationale 209 | 210 | ### Use of dedicated port 211 | 212 | Bifrost requires use of a non-LN port to enable simultaneous and independent 213 | operations of lightning nodes using both legacy LN messages and Bifrost 214 | messages. 215 | 216 | ### Why URL uses plus instead of at symbol 217 | 218 | While at* symbol (`@`) is broadly used in legacy Lightning node addresses 219 | (`@[:]` form), it can’t be used as a proper part of Bifrost 220 | URL since in RFC 3986 it is reserved as a separator for optional username prefix 221 | before mandatory host name part – while pubkey is not optional in Bifrost and 222 | host is optional. Thus, we replace `@` usage with `+`, since `+` is allowed in 223 | RFC 3986 as a separator in host name part of authority field and it semantically 224 | defines “additional information”, which is a network address of the node for a 225 | given public key. 226 | 227 | ### Using local features 228 | 229 | Bifrost support is specified in the local features field of the `init` message 230 | since it is against BOLT-9 to use feature bits greater than 13 in the global 231 | features field. 232 | 233 | ### Feature bit selection 234 | 235 | Bits 255/256 are the largest bit numbers which may be stored by a 32-byte value. 236 | It is still far enough from the current used feature bits in BOLT-9 (26/27), 237 | allowing another 5 to 10 years without the risk of the conflict (until Bifrost 238 | will be recognized) and at the same time does not over-enlarges the size of the 239 | feature flag field in `init` and other messages. 240 | 241 | 242 | ## Reference implementation 243 | 244 | The current Bifrost reference implementation is provided by [`LNP Core 245 | Library`](https://github.com/LNP-BP/lnp-core) and [`LNP 246 | Node`](https://github.com/LNP-BP/lnp-node) 247 | 248 | ## Acknowledgements 249 | 250 | The authors are thankful to Giacomo Zucco, Christian Decker and Martin 251 | Habovštiak for multiple discussions and ideas which led to the creation and 252 | shaping of this specification. 253 | 254 | 255 | ## References 256 | 257 | 1. RFC 3986. Uniform Resource Identifier (URI): Generic Syntax. https://www.rfc-editor.org/rfc/rfc3986#section-3.1 258 | 259 | ## Copyright 260 | 261 | This document is licensed under the Creative Commons CC0 1.0 Universal license. 262 | 263 | 264 | ## Test vectors 265 | 266 | TBD 267 | -------------------------------------------------------------------------------- /lnpbp-0051.md: -------------------------------------------------------------------------------- 1 | ``` 2 | LNPBP: 0051 3 | Vertical: Lightning network protocol 4 | Title: Bifrost: channel management protocol 5 | Author: Dr Maxim Orlovsky 6 | Comments-URI: https://github.com/LNP-BP/lnpbps/pulls/97 7 | Status: Draft 8 | Type: Standards Track 9 | Created: 2021-11-01 10 | Finalized: not yet 11 | License: CC0-1.0 12 | ``` 13 | 14 | - [Abstract](#abstract) 15 | - [Background](#background) 16 | - [Motivation](#motivation) 17 | - [Design](#design) 18 | - [Specification](#specification) 19 | - [Bifrost transaction requirements](#bifrost-transaction-requirements) 20 | - [Channel coordination](#channel-coordination) 21 | - [Channel workflows](#channel-workflows) 22 | - [Channel creation workflow](#channel-creation-workflow) 23 | - [Compatibility](#compatibility) 24 | - [Rationale](#rationale) 25 | - [Reference implementation](#reference-implementation) 26 | - [Acknowledgements](#acknowledgements) 27 | - [References](#references) 28 | - [Copyright](#copyright) 29 | - [Test vectors](#test-vectors) 30 | 31 | 32 | ## Abstract 33 | 34 | ## Background 35 | 36 | ## Motivation 37 | 38 | ## Design 39 | 40 | ## Specification 41 | 42 | ### Bifrost transaction requirements 43 | 44 | Bifrost requires all off-chain transactions always be of version 2. Transaction 45 | outputs which are internal to the channel (i.e. spend by other offchain 46 | transactions participating in channel) MUST use v1 witness P2TR outputs (or 47 | later witness versions). The scripts in taproot key path spends MUST be 48 | miniscript-compatible. 49 | 50 | For on-chain funding transactions and funding outputs of channel level 1 this 51 | requirement is released to witness v0 or above. The reason for lower requirement 52 | is the interoperability with the legacy lightning network, allowing migration of 53 | existing channels opened in legacy network to Bifrost. 54 | 55 | There is no specific requirements for outputs which are not internal for the 56 | channel. 57 | 58 | ### Channel coordination 59 | 60 | For channel operations we assume that any channel may be a multi-peer channel. 61 | Thus, for channel updates it is required that all parties cooperate and sign the 62 | latest version of updated channel transactions. This is achieved by introducing 63 | concept of *channel coordinator*. Channel coordinator is the lightning node that 64 | has originally proposed channel. It is responsible for orchestrating message 65 | flow between all nodes which are the parts of the channel and keeping them 66 | up-to-date. Also, the channel coordinator is the only party required to have 67 | direct connections with other channel participants – and each of channel 68 | participants is required to be connected at least to the channel coordinator. 69 | 70 | If a multiple nested channels are present, for all higher-level channels channel 71 | coordinator MUST be the same as channel coordinator for the base (level 1) 72 | channel; the list of participants for the nested channels MUST be a subset of 73 | the participants of the topmost level 1 channel. 74 | 75 | 76 | #### Channel workflows 77 | 78 | There are following workflows affecting channel status / existence. Each of 79 | these workflows represent a set of P2P messages exchanged by channel peers. 80 | 81 | - Channel creation 82 | - Moving channel from legacy to Bifrost LN 83 | - Removing channel from Bifrost to legacy LN 84 | - Changing channel status (pausing etc) 85 | - Upgrading channel to support more protocols 86 | - Downgrading channel by removing specific protocol 87 | - Cooperatively closing channel 88 | 89 | Workflow can be initiated only by a *channel coordinator*, and specific P2P 90 | messages inside the workflow can be sent either from the *channel coordinator* 91 | to a peer – or, in response, from a peer to the *channel coordinator*. 92 | 93 | Normal channel operations are covered by application-specific business logic and 94 | messages and are not part of any listed channel workflow. Unlike workflows, they 95 | may be initiated by any of the channel peers sending message to the channel 96 | coordinator, however whenever they involve other peers or external channels, 97 | after being initiated they must be coordinated by the channel coordinator. 98 | 99 | ## Channel creation workflow 100 | 101 | Considering generic case of multi-peer channel setup channel creation workflow 102 | is organized with the following algorithm: 103 | 104 | 1. First, all parties agree on the structure of the *funding transaction* 105 | and overall transaction graph within the channel – simultaneously signing 106 | *refund transaction* (which, upon channel creation, will become first 107 | version of the channel *commitment transaction*). This is done using 108 | `ProposeChannel` requests sent by the *channel coordinator* to each of 109 | the peers, replying with either `AcceptChannel` (containing updated 110 | transaction graph with signed refund transaction) or `Error`. 111 | peers must wait for `CHANNEL_CREATION_TIMEOUT` period and discard all 112 | provisional channel data from their memory. 113 | 114 | 2. Once the refund transaction is fully signed – implying that the 115 | transaction graph if agreed between participants – channel coordinator 116 | starts next phase, where the funding transaction gets fully signed. 117 | Coordinator sends `FinalizeChannel` message to each of the peers and 118 | collects signatures, publishing the final transaction either to bitcoin 119 | blockchain (for level 1 channels) or updating the state of the top-level 120 | channel (for nested channels above level 1). Peers track upper level 121 | channel or blockchain to detect funding transaction, and upon transaction 122 | mining starts operate channel in active mode, not requiring any other 123 | messages from the channel coordinator (NB: this differs from the legacy 124 | LN channel creation workflow). 125 | 126 | 3. Replacing funding by fee (RBF): channel coordinator SHOULD initiate RBF 127 | subworkflow for level 1 channels if the funding transaction was not mined 128 | after reasonable amount of time, which should be less than 129 | `ChannelParams::funding_timeout`. With RGB subworkflow coordinator 130 | updates funding transaction – and propagates it with `FinalizeChannel` 131 | request, collecting new signatures (peers MUST reset their funding 132 | timeout counters). 133 | 134 | 4. Cancelling channel creation: if any of the peer nodes replied with 135 | `Error` on any of the channel construction requests within the channel 136 | creation workflow – or if the coordinator detected incorrect reply, 137 | channel coordinator MUST abandon channel creation – and MUST forward 138 | `Error` message to all other peers. A peer posting `Error` MUST 139 | provide a valid error code and a message explaining the cause of the 140 | error. The coordinator SHOULD also send `Error` message to peers if 141 | any of the stages of transaction construction workflow has stuck 142 | without a reply from a peer for over `ChannelParams::peer_timeout` 143 | time. 144 | 145 | 5. Timeouts: the coordinator SHOULD send `Error` message to peers if any 146 | of the peers at any stage of transaction construction workflow has stuck 147 | without a reply for over `ChannelParams::peer_timeout` time. 148 | The peers should abandon channel and clear all information about it from 149 | the memory regardless whether they have received `Error` message from 150 | the coordinator after `ChannelParams::peer_timeout`` * 2` time before 151 | `ChannelFinalized` – and if they has not received new 152 | `FinalizeChannel` request from the coordinator after 153 | `ChannelParams::funding_timeout` time (see pt 3 for RBF subworkflow). 154 | 155 | ``` 156 | Channel coordinator Peer 1 Peer 2 157 | | | | 158 | (enters ChannelProposed state) | | 159 | | | | 160 | | --(1)- ProposeChannel ------> | | 161 | | | | 162 | | --(1)------------ ProposeChannel --------------> | 163 | | | | 164 | | (enter ChannelProposed state) 165 | | | | 166 | | <-(2)------------- AcceptChannel --------------- | 167 | | | | 168 | | <-(2)-- AcceptChannel ------- | | 169 | | | | 170 | (enters ChannelAccepted state) (enter ChannelAccepted state) 171 | | | | 172 | | --(3)- FinalizeChannel -----> | | 173 | | | | 174 | | --(3)------------ FinalizeChannel -------------> | 175 | | | | 176 | | <-(4)-- FinalizeChannel ----- | | 177 | | | | 178 | | <-(4)------------- FinalizeChannel ------------- | 179 | | | | 180 | (enters ChannelFinalized state) (enter ChannelFinalized state) 181 | | | | 182 | (await funding transaction mining or entering the valid super-channel state) 183 | | | | 184 | (enters ChannelActive state) (enter ChannelActive state) 185 | | | | 186 | ``` 187 | 188 | During channel construction workflow channels are identified by 189 | `ChannelId`, which is constructed as a tagged SHA-256 hash 190 | (using `bifrost:channel-proposal` as tag) of the strict-serialized 191 | `ChannelParams` data and coordinator node public key. 192 | 193 | ## Compatibility 194 | 195 | ## Rationale 196 | 197 | ## Reference implementation 198 | 199 | ## Acknowledgements 200 | 201 | ## References 202 | 203 | ## Copyright 204 | 205 | This document is licensed under the Creative Commons CC0 1.0 Universal license. 206 | 207 | ## Test vectors 208 | -------------------------------------------------------------------------------- /lnpbp-0053.md: -------------------------------------------------------------------------------- 1 | ``` 2 | LNPBP: 0053 3 | Layer: OSI Application (i7) 4 | Vertical: Lightning network protocol 5 | Title: Muli-peer payment channels for Bifrost 6 | Author: Dr Maxim Orlovsky 7 | Comments-URI: https://github.com/LNP-BP/lnpbps/pulls/97 8 | Status: Draft 9 | Type: Standards Track 10 | Created: 2021-11-14 11 | Finalized: not yet 12 | License: CC0-1.0 13 | ``` 14 | 15 | ## Abstract 16 | 17 | This specification proposes a batch of improvements for lightning payment 18 | channels: (1) generalization of channels to have an arbitrary number of 19 | participants (multi-peer channels), (2) abstraction from specific peyment 20 | routing syncrhronization algorithm (HTLC, PTLC), (3) ability to extend 21 | and change channel parameters and structure on-the-go, (4) use of Schnorr 22 | signatures, MuSig, Taproot and miniscript-based descriptors. It achieves 23 | this properties by leveraging Bifrost protocol, specifically LNPBP-50 and 24 | LNPBP-51 standards. 25 | 26 | ## Background 27 | 28 | Lightning network enables scalable and more private bitcoin payments by 29 | using pre-signed off-chain transactions, composing so-called state channels. 30 | Still, existing lightning network, defined by a set of BOLT standards, has 31 | multiple limitations. LNP/BP standards LNPBP-50, 51, 52 proposed an extended 32 | version of the lightning network called Bifrost. It is a part of more general 33 | Lightning network protocol and allows creation of more complex, functional 34 | and secure forms of payment channels, which is the aim of this proposal. 35 | 36 | 37 | ## Motivation 38 | 39 | Current standards defining lightning network (BOLTs) were created in the 40 | eraly SegWit era. They were created to cover single use case (unilaterally 41 | funded dual party payment channels) with a very restricted functionality 42 | (no channel splits, channel factories, nested channels, extensions for 43 | channel structure etc). Since LN launch a multiple enhancemend had been 44 | deployed on Bitcoin maiinnet, including Shnorr signatures, unlocking 45 | more compact multisigs (with MuSig scheme), scriptless scripts & adaptor 46 | signatures, enabling alternative payment routing synchronization 47 | mechanism (PTLC), replacing vulnerable HTLC; Taproot, enabling stronger 48 | privacy properties and more compact witnesses; client-side-validation 49 | applications, including RGB smart contracts; different complex Bitcoin 50 | finance applications (BiFi), like descrete log contracts, lightspeed protocol 51 | and many others. The current standard is aiming at generalizing concept 52 | of lightning payment channels as a part of LNP (lightning network protocol) 53 | family of standards, leveraging new set of functionality offered by 54 | Bifrost protocol. 55 | 56 | 57 | ## Design 58 | 59 | First, we separate the core of the payment channel operations from other 60 | channel-related protocols, like payment routing. This enables us real-time 61 | upgradability and composability for channel structure and use of different 62 | protocols within the scope of the same channel (like HTLC, PTLC etc). 63 | 64 | Second, we update channel transactions to use Taproot, Schnorr signatures, 65 | MuSig, TapScript – and enable sign-to-contract and pay-to-contract commitments 66 | required for client-side-validation (like RGB smart contracts). 67 | 68 | Third, we generalize the structure of payment channel transactions for an 69 | arbitrary number of participants. 70 | 71 | Finally, we re-define a set of messages controlling channel creation and 72 | oprations using channel proposals, strict encoding and other advancements 73 | brought by un underlying Bifrost protocol (LNPBP-50 and 51). 74 | 75 | 76 | ## Specification 77 | 78 | ### Funding transaction 79 | 80 | Transaction containing multiple inputs, each of which MUST signal S2C commitment type. 81 | 82 | Output descriptor: `tr(musig(KEY_LOCAL_FUNDING, KEY_REMOTE_1_FUNDING, KEY_REMOTE_2_FUDING, ...))` 83 | 84 | 85 | ### Commitment transaction 86 | 87 | Input: 88 | - Spends funding output 89 | - nSeq: `0x80800000 + COMMITMENT_NO & 0xFFFF` (signals S2C DBC) 90 | - Witness stack: 91 | - `KEY_LOCAL_FUNDING + KEY_REMOTE_1_FUNDING + KEY_REMOTE_2_FUNDING + ...` 92 | - `MUSIG*(KEY_LOCAL_FUNDING + KEY_REMOTE_1_FUNDING + KEY_REMOTE_2_FUNDING + ...)` 93 | where * denotes optional presence of sign-to-contract commitment 94 | 95 | Outputs: 96 | - `to_local`: `tr(KEY_REVOCATION, and_v(v:pk(KEY_LOCAL),older(SELF_DELAY)))` 97 | * `KEY_LOCAL`: proposed by the local node 98 | * `SELF_DELAY`: proposed by the remote node, may be rejected by local 99 | - `to_remote_n`: `tr(KEY_UNSPENDABLE, and_v(v:pk(KEY_REMOTE_N),older(REMOTE_N_DELAY))` 100 | * `KEY_REMOTE_N`: propsed by the remote node N 101 | * `KEY_UNSPENDABLE`: a deterministically-unspendable key computed as `KEY_REMOTE_N + SHA256T("lnpbp53:unspendable", KEY_REMOTE_N) * G` 102 | * `REMOTE_N_DELAY`: proposed by the channel coordinator, may be rejected by remote node N 103 | - `anchor`: `tr(KEY_UNSPENDABLE, {v:pk(KEY_LOCAL), v:pk(KEY_REMOTE_N)})` 104 | * The ooutput must contain a fixed amount of satoshis above dust limit proposed by 105 | the node adding this output to the channel proposal 106 | 107 | ### Messaging 108 | 109 | TBD 110 | 111 | 112 | ## Compatibility 113 | 114 | ### Upgrade 115 | 116 | Any legacy lightning network channel can be upgraded into Bifrost channel using 117 | `UPGRADE` Bifrost message. 118 | 119 | ### Downgrade 120 | 121 | Channel may be downgraded from Bifrost to legacy Lightning network if and only if 122 | - Channel is a 2-peer channel 123 | - It contains only HTLC extensions and no other types of extensions 124 | - It is not used in creation of other channels 125 | - It originates from an on-chain funding transaction 126 | - It does not contain RGB assets or other protocols requiring use of 127 | deterministic bitcoin commitments or single-use-seals 128 | 129 | Bifrost channel breaking one of these requirements may be made downgradable by 130 | removing channel protocols until all of the the requirements are met. 131 | 132 | Channel resulting from downgrade will always use `anchor_output` BOLT-9 feature 133 | flag. 134 | 135 | ## Rationale 136 | 137 | ### Funding transaction inputs use sign-to-contract scheme 138 | 139 | With pay-to-contract commitments if any of channel participants have the same 140 | RGB asset or other P2C-committed protocol data they will be required to merge 141 | their state transitions, expose the private asset data for all other 142 | participants and exchange full RGB consignments before signing funding 143 | transaction. This creates significant privacy leak, more attach vectors and 144 | requires much more complex protocol design. 145 | 146 | ### Channel downgrade 147 | 148 | Bifrost is a highly experimental protocol. Ability to downgrade channel to 149 | legacy stable lightning network provides a failback mechanism for cases 150 | when an attack on Bifrost channels was discovered and participating parties 151 | do not want to close the channel. 152 | 153 | 154 | ## Reference implementation 155 | 156 | ## Acknowledgements 157 | 158 | ## References 159 | 160 | ## Copyright 161 | 162 | This document is licensed under the Creative Commons CC0 1.0 Universal license. 163 | 164 | ## Test vectors 165 | -------------------------------------------------------------------------------- /lnpbp-0055.md: -------------------------------------------------------------------------------- 1 | ``` 2 | LNPBP: 0055 3 | Layer: OSI Application (i7) 4 | Vertical: Lightning network protocol 5 | Title: HTLC channel synchronization in Bifrost 6 | Author: Dr Maxim Orlovsky 7 | Comments-URI: https://github.com/LNP-BP/lnpbps/pulls/97 8 | Status: Draft 9 | Type: Standards Track 10 | Created: 2021-11-14 11 | Finalized: not yet 12 | License: CC0-1.0 13 | ``` 14 | 15 | ## Abstract 16 | 17 | This document specifies upgrade of BOLT-1, 3, 4 and 5-based routed payments in 18 | legacy network and covers payment routing via HTLC-based channel synchronization 19 | in Bifrost using Taproot, TapScript and miniscript-based bitcoin output 20 | descriptors. 21 | 22 | ## Background 23 | 24 | HTLC (hash-time-locked contracts) are used for coordination of state update between 25 | multiple UTXO-based channels. This was the first mechanism proposed for payment 26 | routing in the original lightning network. 27 | 28 | ## Motivation 29 | 30 | Legacy lightning network uses pre-Taproot scripts and non-Schnorr signatures, which 31 | reduces its privacy and requires more onchain space, especially in cases of non- 32 | cooperative channel closings. 33 | 34 | ## Design 35 | 36 | ## Specification 37 | 38 | ### Messaging 39 | 40 | HTLC-based payment coordination is performed by using onion message transport from 41 | LNPBP-52. This specification defines the following message types embedded as onion 42 | payloads: 43 | 44 | `HTLC_ADD` 45 | 46 | `HTLC_EXPIRE` 47 | 48 | `HTLC_FULFILL` 49 | 50 | `HTLC_MALFORMED` 51 | 52 | It also re-uses `SIG_UPDATE` and `REVOKE` messages from the core Bifrost protocol 53 | (LNPBP-50). 54 | 55 | ### Transactions 56 | 57 | Each HTLC contract adds an output to the *commitment transaction*. The output 58 | depends on whether this is an offered HTLC or received one. 59 | 60 | #### Offered HTLC outputs 61 | 62 | 72 | ``` 73 | tr(KEY_REVOCATION, { 74 | and_v( 75 | v:milti_a(2, KEY_HTLC_REMOTE, KEY_HTLC_LOCAL), 76 | older(SELF_DELAY)), 77 | and_v( 78 | and_v( 79 | v:pk(KEY_HTLC_REMOTE), 80 | v:hash160(HASH)), 81 | older(SELF_DELAY)) 82 | }) 83 | ``` 84 | 85 | #### Received HTLC outputs 86 | 87 | 99 | ``` 100 | tr(KEY_REVOCATION, { 101 | and_v( 102 | and_v( 103 | v:multi_a(2, KEY_HTLC_LOCAL, KEY_HTLC_REMOTE), 104 | after(CLTV_EXPIRE)), 105 | older(SELF_DELAY), 106 | and_v( 107 | and_v( 108 | v:multi_a(2, KEY_HTLC_LOCAL, KEY_HTLC_REMOTE), 109 | v:hash160(HASH)), 110 | older(SELF_DELAY) 111 | }) 112 | ``` 113 | 114 | These outputs are constructed after BOLT-3 with `option_anchors` (see rationale). 115 | 116 | #### HTLC spending transactions 117 | 118 | The input of *HTLC spending transactions* spends *offered HTLC* (for *HTLC timeout transaction*) or *received HTLC* (for *HTLC success transaction*) output from the commitment transaction. 119 | 120 | - nLockTime: 121 | - 0 for HTLC-success 122 | - `CLTV_EXPIRY` for HTLC-timeout 123 | - Input: 124 | - nSeq: `SELF_DELAY` (must be even to use P2C deterministic bitcoin commitments) 125 | - control block: `0xC0/0xC1 ` 126 | - rest of witness stack for *HTLC-success*: 127 | - `KEY_HTLC_LOCAL` 128 | - `SIG(KEY_HTLC_LOCAL)` 129 | - `KEY_HTLC_REMOTE` 130 | - `SIG(KEY_HTLC_REMOTE)` 131 | - `HASH_PREIMAGE` 132 | - rest of witness stack for *HTLC-timeout*: 133 | - `KEY_HTLC_REMOTE` 134 | - `SIG(KEY_HTLC_REMOTE)` 135 | - `KEY_HTLC_LOCAL` 136 | - `SIG(KEY_HTLC_LOCAL)` 137 | - Output descriptor: 138 | ``` 139 | tr(KEY_REVOCATION*, and_v( 140 | v:pk(KEY_LOCAL_DELAYED), 141 | older(SELF_DELAY) 142 | )) 143 | ``` 144 | (* denotes that the internal taproot key `KEY_REVOCATION` may be tweaked with 145 | pay-to-contract commitment) 146 | 147 | #### On-chain protocol 148 | 149 | TBD 150 | 151 | ## Compatibility 152 | 153 | ## Rationale 154 | 155 | ### Use of `OP_CHECKSIGADD` 156 | 157 | There are multiple ways to create multisig scheme in Taproot & TapScript [1]. 158 | In script-path spending leafs we choose to use `OP_CHECKSIGADD`-based scripts, 159 | defined by miniscript `multi_a` descriptors. This allows to avoid multiple 160 | interactive communications required for composinng aggregated MuSig signatures. 161 | The downside of this approach is a large witness stack size (and higher 162 | transaction cost), which may be mitigated by adopting PTLC-based scriptless- 163 | script contracts [2]. 164 | 165 | ### Use of `option_anchors` 166 | 167 | HTLC construction in Bifrost always requires use of equivalent of legacy BOLT-9 168 | "anchored outputs" option. This addresses a vulnerability caused by the absence 169 | of self-delay seqnence lock, where local party had an incentive to non-cooperatively 170 | close the channel in order to instantly get access to the local funds. 171 | 172 | 173 | ## Reference implementation 174 | 175 | ## Acknowledgements 176 | 177 | ## References 178 | 179 | 1. 180 | 2. LNPBP-0056 181 | 182 | ## Copyright 183 | 184 | This document is licensed under the Creative Commons CC0 1.0 Universal license. 185 | 186 | ## Test vectors 187 | -------------------------------------------------------------------------------- /lnpbp-0081.md: -------------------------------------------------------------------------------- 1 | ``` 2 | LNPBP: 0081 3 | Vertical: Cryptographic primitives 4 | Title: Tagged merkle trees for client-side-validation 5 | Author: Dr Maxim Orlovsky , 6 | Peter Todd 7 | Comments-URI: https://github.com/LNP-BP/lnpbps/issues/<____> 8 | Status: Draft 9 | Type: Standards Track 10 | Created: 2021-05-11 11 | License: CC0-1.0 12 | ``` 13 | 14 | - [Abstract](#abstract) 15 | - [Background](#background) 16 | - [Motivation](#motivation) 17 | - [Design](#design) 18 | - [Specification](#specification) 19 | - [Compatibility](#compatibility) 20 | - [Rationale](#rationale) 21 | - [Reference implementation](#reference-implementation) 22 | - [Acknowledgements](#acknowledgements) 23 | - [References](#references) 24 | - [Copyright](#copyright) 25 | - [Test vectors](#test-vectors) 26 | 27 | 28 | ## Abstract 29 | 30 | ## Background 31 | 32 | ## Motivation 33 | 34 | Problems with modern merkle trees: 35 | - Depth extension attack: no commitment to the tree depth 36 | 37 | ## Design 38 | 39 | Based on bitcoin merklization with following modifications: 40 | - Tagged hashing for source data 41 | - Tagged hashing of each tree object 42 | - Commitments to depth, width and height of the tree 43 | - Custom placeholders for empty objects 44 | - Restricting tree source to 2^16 elements (height is always <=16) 45 | 46 | ## Specification 47 | 48 | Merkle node is represented by a single SHA256 hash over the following data, 49 | serialized as a byte stream without any separators: 50 | - branch type (byte) 51 | - tag (128-bit number) 52 | - depth (byte) 53 | - width (4 bytes, little-endian) 54 | - child node 1 (32 bytes) 55 | - child node 2 (32 bytes) 56 | 57 | If one or both of the child nodes are absent, a constant consisting of 16 `0xFF` 58 | bytes is used. 59 | 60 | The root is produced via `CommitmentId` procedure 61 | 62 | ## Compatibility 63 | 64 | ## Rationale 65 | 66 | ## Reference implementation 67 | 68 | 69 | 70 | ## Acknowledgements 71 | 72 | ## References 73 | 74 | ## Copyright 75 | 76 | This document is licensed under the Creative Commons CC0 1.0 Universal license. 77 | 78 | ## Test vectors 79 | -------------------------------------------------------------------------------- /lnpbp-template.md: -------------------------------------------------------------------------------- 1 | ``` 2 | LNPBP: 3 | Vertical: 4 | Title: 5 | Author: 6 | Comments-URI: https://github.com/LNP-BP/lnpbps/issues/<____> 7 | Status: Draft 8 | Type: Standards Track 9 | Created: 10 | Finalized: not yet 11 | Based on: 12 | License: CC0-1.0 13 | ``` 14 | 15 | - [Abstract](#abstract) 16 | - [Background](#background) 17 | - [Motivation](#motivation) 18 | - [Design](#design) 19 | - [Specification](#specification) 20 | - [Compatibility](#compatibility) 21 | - [Rationale](#rationale) 22 | - [Reference implementation](#reference-implementation) 23 | - [Acknowledgements](#acknowledgements) 24 | - [References](#references) 25 | - [Copyright](#copyright) 26 | - [Test vectors](#test-vectors) 27 | 28 | 29 | ## Abstract 30 | 31 | 32 | ## Background 33 | 34 | 35 | ## Motivation 36 | 37 | 38 | ## Design 39 | 40 | 41 | ## Specification 42 | 43 | 44 | ## Compatibility 45 | 46 | 47 | ## Rationale 48 | 49 | 50 | ## Reference implementation 51 | 52 | 53 | ## Acknowledgements 54 | 55 | 56 | ## References 57 | 58 | 59 | ## Copyright 60 | 61 | This document is licensed under the Creative Commons CC0 1.0 Universal license. 62 | 63 | 64 | ## Test vectors 65 | 66 | --------------------------------------------------------------------------------