This is a bip for encrypted backup, an encryption scheme for bitcoin wallet related metadata.
Mailing list post: https://groups.google.com/g/bitcoindev/c/5NgJbpVDgEc
This is a bip for encrypted backup, an encryption scheme for bitcoin wallet related metadata.
Mailing list post: https://groups.google.com/g/bitcoindev/c/5NgJbpVDgEc
0@@ -0,0 +1,268 @@
1+```
2+BIP: ?
3+Layer: Applications
4+Title: Bitcoin Encrypted Backup
How about: Compact encryption scheme for non-seed wallet data
Or some other wording to make it clear this isn’t for storing keys.
24+lexicographically‑sorted public keys inside the descriptor or policy, so any party
25+who already holds one of those keys can later decrypt the backup without extra secrets
26+or round‑trips. The format uses AES-GCM-256 with a 96‑bit random nonce and a 128‑bit
27+authentication tag to provide confidentiality and integrity.
28+While initially designed for descriptors and policies, the same scheme encrypts labels
29+and backup metadata, allowing a uniform, vendor‑neutral, and future‑extensible backup format.
48+1. **Descriptors are hard to store offline.**
49+ Descriptor string representation can be far longer than a 12/24-word seed phrase.
50+Paper, steel, and other long-term analog media quickly become impractical for such
51+lengths, or error-prone to transcribe.
52+
53+2. **Online redundancy carries risk.**
59+
60+These constraints lead to an acute need for an **encrypted**, and
61+ideally compact backup format that:
62+
63+* can be **safely stored in multiple places**, including untrusted on-line services,
64+* can be **decrypt only by intended holders** of specified public keys,
60+These constraints lead to an acute need for an **encrypted**, and
61+ideally compact backup format that:
62+
63+* can be **safely stored in multiple places**, including untrusted on-line services,
64+* can be **decrypt only by intended holders** of specified public keys,
65+* and keeps both **keys and plaintext** hidden from any party who lacks the
33+This BIP is licensed under the BSD 2-Clause License.
34+Redistribution and use in source and binary forms, with or without modification, are
35+permitted provided that the above copyright notice and this permission notice appear
36+in all copies.
37+
38+### Motivation
111+This specification applies to creating, encrypting and decrypting a *Bitcoin Encrypted Backup*
112+of **public-key-only wallet material**, namely:
113+
114+- a **descriptor** (BIP-0380)
115+- a **wallet policy** (BIP-0388)
116+- **BIP-329 labels** (JSONL)
115+- a **wallet policy** (BIP-0388)
116+- **BIP-329 labels** (JSONL)
117+- **wallet-wide JSON backup metadata**
118+
119+All four payloads are encrypted under the same key derivation rules detailed below.
120+The scheme is **not** intended for descriptors or policies that contain private keys,
127+
128+### Secret generation
129+
130+* Let `p_1`, `p_2`, .., `p_n` be the public keys in the descriptor/wallet policy, in
131+increasing lexicographical order.
132+* let `secret` = sha256("BEB_DECRYPTION_SECRET" ‖ `p1` ‖ `p2` ‖ ... ‖ `pn`)
BEB
I would suggest BIP_XXX
(replaced with the BIP number once assigned).
BIPxxxx
at first, but changes it to BEB
then, as we are very likely to ship a feature using this scheme in Liana v13 (so likely before this get assigned a BIP #)…
16+### Abstract
17+
18+This BIP defines a compact encryption scheme for **wallet descriptors** (BIP-0380),
19+**wallet policies** (BIP-0388), **labels** (BIP-0329), and
20+**wallet backup metadata** (json). The encrypted output—called a
21+*bitcoin encrypted backup* (BEB), enables users to outsource long‑term storage to
128+### Secret generation
129+
130+* Let `p_1`, `p_2`, .., `p_n` be the public keys in the descriptor/wallet policy, in
131+increasing lexicographical order.
132+* let `secret` = sha256("BEB_DECRYPTION_SECRET" ‖ `p1` ‖ `p2` ‖ ... ‖ `pn`)
133+* let `si` = sha256("BEB_INDIVIDUAL_SECRET" ‖ `pi`)
s_i
201+`COUNT`: 1-byte unsigned integer (1–255) indicating how many secrets are included.
202+`INDIVIDUAL_SECRET`: 32-byte serialization of the derived individual secret.
203+
204+#### Content
205+
206+`CONTENT`: 1-byte unsigned integer identifying what has been encrypted.
and then allow for multiple content entries
hum, no strong opinion on this, but if the purpose is to have a single encrypted file containing descriptor(380 or 388) + labels + wallet metadata then it should fit into 0x04 Wallet Backup
(yeah I’ll have to write a formal spec)
209+|:-------|:---------------------------------------|
210+| 0x00 | Undefined |
211+| 0x01 | BIP-0380 Descriptor (string) |
212+| 0x02 | BIP-0388 Wallet policy (string) |
213+| 0x03 | BIP-0329 Labels (JSONL) |
214+| 0x04 | Wallet backup (JSON) |
Maybe point out that unlisted types should still be decrypted and that new types may be added to the BIP.
That said, a more generic approach would be to allow a bit more space for the type. E.g. a ~4 digit number that must represent a BIP number. Or a short string like “BIP-0329”. Both avoid the need to maintain a central register.
Also, if you allow multiple pieces of content in a single encrypted blob, it’s useful to have a padding type.
251+### Future Extensions
252+
253+The version field enables possible future enhancements:
254+
255+- Additional encryption algorithms
256+- Support for threshold-based decryption
hide the number of participants
hum, the number of participant can also be hidden (derivation path are optionals) and one can also add fake ones, how do you think we can enhance this further?
c_i
shares, so it would be a more complicated overhaul. I don’t think it’s urgent.
Open questions
- Deterministic nonce: Currently the nonce is generated randomly. Is it safe to produce a deterministic nonce, e.g.
hash("NONCE" || plaintext || key_1 || … || key_n)
, or are there known security concerns with this approach?
In general nonce reuse is unsafe because if you make multiple backups over time, e.g. as you add more transaction labels, you would be reusing the nonce with different message. By including the plaintext
in the nonce, you do address that concern.
However it still seems unwise to mess with cryptographic standards. It doesn’t seem worth the risk for saving 32 bytes on something that’s going to be at least a few hundred bytes for a typical multisig.
15+
16+### Abstract
17+
18+This BIP defines a compact encryption scheme for **wallet descriptors** (BIP-0380),
19+**wallet policies** (BIP-0388), **labels** (BIP-0329), and
20+**wallet backup metadata** (json). The payload must not contains any private key material.
contain
, not contains
Hi @pythcoiner,
By coincidence, two weeks ago I started working on a proposal for a “Standard Encrypted Wallet Payload” to be placed inside an “Encrypted Envelope”. The “Wallet Payload” contains descriptors and metadata but can also act as a full wallet backup including transactions, UTXOs and addresses. The proposal is very much a work in progress.
I only just found this discussion so am reading through it to compare it to my proposal. The descriptor backup in the “Wallet Payload” of my proposal seems to have some overlap with the BIP proposed here. If there is too much overlap I may reconsider progressing with my proposal.
As mentioned, my proposal is very much a work in progress but the wallet payload proposal can be found here:
https://gist.github.com/KeysSoze/7109a7f0455897b1930f851bde6337e3
Maybe jump to the test vector section to see what a basic backup of a descriptor and some meta data would look like prior to encryption.
https://gist.github.com/KeysSoze/7109a7f0455897b1930f851bde6337e3#test-vectors
As my proposal is designed to be modular and extensible the encryption envelopes may be extended to offer Multiparty Encryption and Authentication. See:
I have already started documenting an encryption envelope that uses AES-256-GCM and password protection:
https://gist.github.com/KeysSoze/866d009ccd082edf6802df240154b20d
I have not written a reference implementation yet but there are well established python and Rust libraries for CBOR and COSE that should make implementing the BIPs relatively simple.