diff --git a/bip-0138.md b/bip-0138.md index 2aa276ba..8d5e36ba 100644 --- a/bip-0138.md +++ b/bip-0138.md @@ -266,17 +266,17 @@ Implementations MUST reject empty payloads. `CIPHERTEXT` is the encrypted data resulting from encryption of `PAYLOAD` with algorithm defined in `ENCRYPTION` where `PAYLOAD` is encoded following this format: -`CONTENT` `LENGTH` `PLAINTEXT` (`PADDING`) +`CONTENT` `LENGTH` `PLAINTEXT` (`CONTENT` `LENGTH` `PLAINTEXT` ...) (`PADDING`) `LENGTH`: variable-length integer representing the length of `PLAINTEXT` in bytes. It MUST be present. `PLAINTEXT`: the `LENGTH` bytes of payload data. -`PADDING`: OPTIONAL bytes after `PLAINTEXT`, up to the end of the decrypted `PAYLOAD`. -Parsers MUST consume exactly `LENGTH` bytes of `PLAINTEXT` and MUST ignore everything after -it. These bytes are reserved for size padding (see Padding) and/or vendor-specific data, -the same way trailing bytes after `CIPHERTEXT` are reserved and ignored. +`PADDING`: OPTIONAL bytes after the final `PLAINTEXT`, up to the end of the decrypted +`PAYLOAD`. Parsers MUST consume exactly `LENGTH` bytes of each `PLAINTEXT`. The padding +bytes are reserved for size padding (see Padding) and/or vendor-specific data, the same +way trailing bytes after `CIPHERTEXT` are reserved and ignored. #### Padding @@ -307,14 +307,16 @@ All variable-length integers are encoded as #### Content -`CONTENT` is a variable length field defining the type of `PLAINTEXT` being encrypted, -it follows this format: +`CONTENT` is a variable length field defining the type of the `PLAINTEXT` that follows +it. It follows this format: `TYPE` (`LENGTH`) `DATA` -`CONTENT` is a single `TYPE (LENGTH) DATA` triple, one blob describing `PLAINTEXT`. -It is not a sequence of entries; it is immediately followed by the payload `LENGTH` -and `PLAINTEXT`. +A `PAYLOAD` carries one or more `CONTENT LENGTH PLAINTEXT` items, each `CONTENT` +describing the `PLAINTEXT` immediately following it. The sequence ends at the first +`TYPE` byte equal to `0x00`, or at the end of the `PAYLOAD`, whichever comes first; all +remaining bytes are `PADDING`. A `PAYLOAD` MUST contain at least one item (see +[Payload Size Limits](#payload-size-limits)). `TYPE`: 1-byte unsigned integer identifying how to interpret `DATA`. @@ -340,8 +342,8 @@ For all `TYPE` values except `0x01`, parsers MUST reject `CONTENT` if `LENGTH` e the remaining payload bytes. For an unknown `TYPE` less than `0x80`, parsers MUST consume its `LENGTH` bytes of -`DATA`, treat the content type as unknown, and continue with the payload `LENGTH` -and `PLAINTEXT`. +`DATA`, treat the content type as unknown, consume the following payload `LENGTH` and +`PLAINTEXT`, and continue with the next item. For an unknown `TYPE` greater than or equal to `0x80`, parsers MUST reject the payload.[^type-upgrade] @@ -480,7 +482,7 @@ The version field enables possible future enhancements: ### Implementation -- Rust [implementation](https://github.com/pythcoiner/bitcoin-encrypted-backup) +- Rust [implementation](https://github.com/pythcoiner/bip138) ### Test Vectors @@ -498,7 +500,8 @@ contains test vectors for generation of encryption secret. contains test vectors for ciphertexts generated using CHACHA20-POLY1305. [encrypted_backup.json](./bip-0138/test_vectors/encrypted_backup.json) contains test vectors for generation of complete encrypted backups, including -BIP380 and BIP388 content. +BIP380 and BIP388 content, a multi-content payload, and an all-zero-nonce backup +that parsers MUST reject. [bip380_descriptor_backup.json](./bip-0138/test_vectors/bip380_descriptor_backup.json) contains test vectors for BIP380 descriptor backup documents. [bip388.json](./bip-0138/test_vectors/bip388.json) diff --git a/bip-0138/test_vectors/encrypted_backup.json b/bip-0138/test_vectors/encrypted_backup.json index e752d01e..1908e1cc 100644 --- a/bip-0138/test_vectors/encrypted_backup.json +++ b/bip-0138/test_vectors/encrypted_backup.json @@ -80,5 +80,42 @@ "nonce": "000000000000000000000388", "expected": "424950313338010104800000308000000080000000800000020263f5769bbb36d77fc5d3251700590c087013ca44284850e88f379f2519190f97e5b4cabf8bdb9a04a92fc3e104dd2d8a2cb8e5ea886e143236dd4b04619e796d01000000000000000000000388fd5d011def7dae872431f1fa0df78989f7e5087cd0cb112a69bc211d3346b1031c5d1e8702197712ac46597e05d80421fda7e60d09f3ba2178bd770c904bf840d3d779565fbd0668a989934483820c4c828f32ffe5fc1ce55bbfe287a6d4eb4461e4da1b6a6f22cc0932773c84f07d879b1ed8035831e2a358101be023ea2efb7c70411f757c42715f4e5f7eff416a456a5dadf1b980480e22a7b66726ebc84afe04acdfbf47c6b41c2bb39c5a069a93dba0de4ea9bc192f938f968c9fa2afc26025dd577461b73bad0870e97d7519945ced9d73500c7ece85696d98f223350cd6a337cb74feeeea8d5144ee94553dc54a46e43f67fa48f11c7746e006aac4478fa0c484f041be451548152a1f11f632a9d966de62e3cd80ed9885117e5901042974c80d3f95a13c1cfe2157f2bfb80bea7b3bc0a71127d8daa6a75d3cc517ef934dd9af4b504600c5ce223ba9538c9bc0472aa3832571b1486e2f51b40a5351", "expected_base64": "QklQMTM4AQEEgAAAMIAAAACAAAAAgAAAAgJj9XabuzbXf8XTJRcAWQwIcBPKRChIUOiPN58lGRkPl+W0yr+L25oEqS/D4QTdLYosuOXqiG4UMjbdSwRhnnltAQAAAAAAAAAAAAADiP1dAR3vfa6HJDHx+g33iYn35Qh80MsRKmm8IR0zRrEDHF0ehwIZdxKsRll+BdgEIf2n5g0J87oheL13DJBL+EDT13lWX70GaKmJk0SDggxMgo8y/+X8HOVbv+KHptTrRGHk2htqbyLMCTJ3PITwfYebHtgDWDHio1gQG+Aj6i77fHBBH3V8QnFfTl9+/0FqRWpdrfG5gEgOIqe2ZybryEr+BKzfv0fGtBwrs5xaBpqT26DeTqm8GS+Tj5aMn6KvwmAl3Vd0Ybc7rQhw6X11GZRc7Z1zUAx+zoVpbZjyIzUM1qM3y3T+7uqNUUTulFU9xUpG5D9n+kjxHHdG4AaqxEePoMSE8EG+RRVIFSofEfYyqdlm3mLjzYDtmIURflkBBCl0yA0/laE8HP4hV/K/uAvqezvApxEn2Nqmp108xRfvk03Zr0tQRgDFziI7qVOMm8BHKqODJXGxSG4vUbQKU1E=" + }, + { + "description": "Two content items in one payload (BIP380 descriptor + BIP329 labels)", + "version": 1, + "encryption": 1, + "content": "01017c", + "keys": [ + "02e6642fd69bd211f93f7f1f36ca51a26a5290eb2dd1b0d8279a87bb0d480c8443", + "0384526253c27c7aef56c7b71a5cd25bebb66dddda437826defc5b2568bde81f07" + ], + "derivation_paths": [], + "plaintext": "wsh(or_d(pk([9d69155f/48'/1'/0'/2']tpubDDxT9mkZzWwkKwpGT5fY6iiM9muYTPkTx6Eig8dpHR7TChuGGCWYAHVmpW1ciido5RiFWwjzYsF1GZHkEHg2nrYp3zNtx3QQRkznyLhQ77x/<0;1>/*),and_v(v:pkh([9d69155f/48'/1'/0'/2']tpubDDxT9mkZzWwkKwpGT5fY6iiM9muYTPkTx6Eig8dpHR7TChuGGCWYAHVmpW1ciido5RiFWwjzYsF1GZHkEHg2nrYp3zNtx3QQRkznyLhQ77x/<2;3>/*),older(52596))))#gx5f42wh", + "nonce": "0c0d0e0f101112131415161a", + "expected": "424950313338010002b8c6ce74f81b0ffe7d7511824e75f95114f9b140e57bb570e5c5d807f0a5e96fb8e749fceb0dd84d20a75af4dbd6d585d89c54053f6313ac6592cbfe8c1bdd4f010c0d0e0f101112131415161afde201d35ed73109113688c5cc808c44e3e4a6837adf0ee8c9339947e176418c41f16e92c36b395a07e036117df93fda41bf3b1bacae6cb0fe1cf2c07f519fff3a96b95540de161c48cd8ee6485a1b5477c18d038257af7bacedc36ef0cea2f0661c2267b0d72cf8273f32d734046eb8fbfe75a47619a7d5c12b95e9ec6a49b0a031ccdbfaa6bd201ddf94cb3979ceae1390af41baaedeba38dfcf078c97c33404f0833d36a750e1ebac14d2139719c35aacfa025cde5a19f776d8e1d1367764700f8e8bc3ae99d08fbffaa322abe1e69f2839f8840cdffbcfed9544e4fde1dac882bee1e0d34367f63fc5eec38540f0b3683cd79dbe67eab0ddd52765edf6de7f24adb3e9df8e7b9bf793863f60dfa6fd39aed67eac5d4f774069af6ff436bd85affb199846c55e7d2063d950182b60886f8d65c890d0a4ff6253a8ed0963a052c46ed858dcdefe3e929d970e97d7b65b9843caf94a5649bd8547f5a976cc40b7356dfb6cf3df6b87267ca83d15a2d11cd8e918f2a2b17bb717b33f55a78fd5a6a01cd11d39b54af2734066be57977fb140db2944bf612ce63fa2dc7ae841f47f930637eaaacc96bf5a9cf82483f0aba57dafb79319631a3b954c0a05731607c29290b5c9487def5371585671f4ae6ab0e8cdb51423faf15de6ca34430d21581de9cfe36e", + "extra": [ + { + "content": "010149", + "plaintext": "{\"type\": \"tx\", \"ref\": \"f4184fc596403b9d638783cf57adfe4c75c605f6356fbc91338530e9831e9e16\", \"label\": \"multi content demo\"}" + } + ], + "expected_base64": "QklQMTM4AQACuMbOdPgbD/59dRGCTnX5URT5sUDle7Vw5cXYB/Cl6W+450n86w3YTSCnWvTb1tWF2JxUBT9jE6xlksv+jBvdTwEMDQ4PEBESExQVFhr94gHTXtcxCRE2iMXMgIxE4+Smg3rfDujJM5lH4XZBjEHxbpLDazlaB+A2EX35P9pBvzsbrK5ssP4c8sB/UZ//Opa5VUDeFhxIzY7mSFobVHfBjQOCV697rO3DbvDOovBmHCJnsNcs+Cc/Mtc0BG64+/51pHYZp9XBK5Xp7GpJsKAxzNv6pr0gHd+Uyzl5zq4TkK9Buq7eujjfzweMl8M0BPCDPTanUOHrrBTSE5cZw1qs+gJc3loZ93bY4dE2d2RwD46Lw66Z0I+/+qMiq+Hmnyg5+IQM3/vP7ZVE5P3h2siCvuHg00Nn9j/F7sOFQPCzaDzXnb5n6rDd1Sdl7fbefySts+nfjnub95OGP2Dfpv05rtZ+rF1Pd0Bpr2/0Nr2Fr/sZmEbFXn0gY9lQGCtgiG+NZciQ0KT/YlOo7QljoFLEbthY3N7+PpKdlw6X17ZbmEPK+UpWSb2FR/WpdsxAtzVt+2zz32uHJnyoPRWi0RzY6RjyorF7txezP1Wnj9WmoBzRHTm1SvJzQGa+V5d/sUDbKUS/YSzmP6LceuhB9H+TBjfqqsyWv1qc+CSD8Kulfa+3kxljGjuVTAoFcxYHwpKQtclIfe9TcVhWcfSuarDozbUUI/rxXebKNEMNIVgd6c/jbg==" + }, + { + "description": "All-zero nonce MUST be rejected", + "version": 1, + "encryption": 1, + "content": "01017c", + "keys": [ + "02e6642fd69bd211f93f7f1f36ca51a26a5290eb2dd1b0d8279a87bb0d480c8443", + "0384526253c27c7aef56c7b71a5cd25bebb66dddda437826defc5b2568bde81f07" + ], + "derivation_paths": [], + "plaintext": "wsh(or_d(pk([9d69155f/48'/1'/0'/2']tpubDDxT9mkZzWwkKwpGT5fY6iiM9muYTPkTx6Eig8dpHR7TChuGGCWYAHVmpW1ciido5RiFWwjzYsF1GZHkEHg2nrYp3zNtx3QQRkznyLhQ77x/<0;1>/*),and_v(v:pkh([9d69155f/48'/1'/0'/2']tpubDDxT9mkZzWwkKwpGT5fY6iiM9muYTPkTx6Eig8dpHR7TChuGGCWYAHVmpW1ciido5RiFWwjzYsF1GZHkEHg2nrYp3zNtx3QQRkznyLhQ77x/<2;3>/*),older(52596))))#gx5f42wh", + "nonce": "000000000000000000000000", + "expected": "424950313338010002b8c6ce74f81b0ffe7d7511824e75f95114f9b140e57bb570e5c5d807f0a5e96fb8e749fceb0dd84d20a75af4dbd6d585d89c54053f6313ac6592cbfe8c1bdd4f01000000000000000000000000fd66010d8538e52c03d7069660ca0fc3e961eb7d2ae284498ba1358b7476c09d44bfa60e1963f0271eaf66e816348f001fa4ee1d0fd11e24e93ed12ee288371ce6ca8629b70692e36a43d7647cb340f8f22c6ef4aeb8968f16920ddd2f11f450f7d2420f210f55204d4c40eb8306c02ec8e30c2fd13a15ba0999ad4831a9be7754eab3ddf4f5e71301b89a881a279cf262556708697b8e3da7236872270d3f8d62b6d56e4065835df66277f30177566c233764417eb7d2de6cf5f293321d80c6328c261d0f2d06c9fbd6fd29cd059e0db61d6e1b60951605f40f93c239b643da049186fcc5811bd116808d8bdd8beaefc0d4124088dcd00261c396eb3f27ed254ff91c4457a1c817c53004ea0e764309149044d4e8f92d2ee688619fc44a67a096bdd6c978411d6c103b634896e080cb3dba6f66f0fe580cdb9f944457c65312f449d82c2b1bc86ac972df641ae93ff2d1ea2d9ae64abdce2dd452bf2fc37a5f493dd1704f91a2c765", + "valid": false, + "expected_base64": "QklQMTM4AQACuMbOdPgbD/59dRGCTnX5URT5sUDle7Vw5cXYB/Cl6W+450n86w3YTSCnWvTb1tWF2JxUBT9jE6xlksv+jBvdTwEAAAAAAAAAAAAAAAD9ZgENhTjlLAPXBpZgyg/D6WHrfSrihEmLoTWLdHbAnUS/pg4ZY/AnHq9m6BY0jwAfpO4dD9EeJOk+0S7iiDcc5sqGKbcGkuNqQ9dkfLNA+PIsbvSuuJaPFpIN3S8R9FD30kIPIQ9VIE1MQOuDBsAuyOMML9E6FboJma1IMam+d1Tqs9309ecTAbiaiBonnPJiVWcIaXuOPacjaHInDT+NYrbVbkBlg132YnfzAXdWbCM3ZEF+t9LebPXykzIdgMYyjCYdDy0GyfvW/SnNBZ4Nth1uG2CVFgX0D5PCObZD2gSRhvzFgRvRFoCNi92L6u/A1BJAiNzQAmHDlus/J+0lT/kcRFehyBfFMATqDnZDCRSQRNTo+S0u5ohhn8RKZ6CWvdbJeEEdbBA7Y0iW4IDLPbpvZvD+WAzbn5REV8ZTEvRJ2CwrG8hqyXLfZBrpP/LR6i2a5kq9zi3UUr8vw3pfST3RcE+Rosdl" } ]