forked from bitcoin/bitcoin
-
Notifications
You must be signed in to change notification settings - Fork 11
WIP: implemented encrypted backup BIP-xxxx #109
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Draft
Sjors
wants to merge
12
commits into
master
Choose a base branch
from
wip-encrypted-backup
base: master
Could not load branches
Branch not found: {{ refName }}
Loading
Could not load tags
Nothing to show
Loading
Are you sure you want to change the base?
Some commits from the old base branch may be removed from the timeline,
and old review comments may become outdated.
Draft
Conversation
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Add helper methods to AEADChaCha20Poly1305 for converting between
the internal Nonce96 type ({uint32_t, uint64_t}) and a 12-byte
array representation (big-endian).
RFC8439 defines the nonce as 96 opaque bits, but our implementation
splits it. These helpers make it convenient to work with byte-based
nonce representations.
BIP-380 specifies that descriptors can use either ' or h as the hardened indicator. ParseHDKeypath only supported the former. This prepares for using ParseHDKeypath with paths extracted from descriptors which typically use 'h' for shell-escaping convenience.
Introduces WalletDescriptorInfo struct and DescriptorInfoToUniValue() helper to avoid code duplication when serializing descriptor metadata to UniValue. Refactors listdescriptors RPC to use the new helper.
26aae5f to
695d392
Compare
Add functions for normalizing public keys to x-only format as specified in BIP-xxxx (Bitcoin Encrypted Backup). These primitives form the foundation for the encryption scheme. Functions added: - NormalizeToXOnly(): Convert CPubKey or CExtPubKey to 32-byte x-only format - IsNUMSPoint(): Check if a key is the BIP341 unspendable NUMS point - ExtractKeysFromDescriptor(): Extract and normalize all keys from a descriptor Includes test vectors from the BIP specification.
Add functions to compute the decryption secret and individual secrets as specified in BIP-xxxx. The decryption secret is derived from sorted public keys, and individual secrets allow any keyholder to decrypt. Functions added: - ComputeDecryptionSecret(): Hash sorted keys to derive decryption secret - ComputeIndividualSecret(): Hash a single key to derive its individual secret - ComputeAllIndividualSecrets(): Compute XOR'd secrets for all keys Includes test vectors from the BIP specification.
Add functions for encoding/decoding derivation paths as specified in BIP-xxxx: - ParseDerivationPath: parse m/44'/0'/0' style strings - EncodeDerivationPaths: encode to binary format (count + path lengths + BE child indices) - DecodeDerivationPaths: decode from binary format Includes test vectors from the BIP specification.
Add functions for encoding/decoding individual secrets as specified in BIP-xxxx:
- EncodeIndividualSecrets: encode sorted secrets to binary format
- DecodeIndividualSecrets: decode from binary format
Individual secrets allow any keyholder to derive the decryption secret using:
decryption_secret = ci XOR sha256("BIP_XXXX_INDIVIDUAL_SECRET" || pi)
Includes test vectors from the BIP specification.
Add functions for encoding/decoding content type metadata as specified in BIP-xxxx: - EncodeContent: encode BIP_NUMBER or VENDOR_SPECIFIC content types - DecodeContent: decode content type from binary format Content types define what kind of data is in the encrypted payload: - BIP_NUMBER: references a BIP specification (e.g., 380 for descriptors) - VENDOR_SPECIFIC: application-defined content with length prefix Includes test vectors from the BIP specification.
Add the complete encryption and encoding layer for BIP-xxxx encrypted backups: Encryption: - EncryptChaCha20Poly1305: encrypt with ChaCha20-Poly1305 AEAD - DecryptChaCha20Poly1305: decrypt and verify authentication tag Backup creation and encoding: - CreateEncryptedBackup: create backup from descriptor and plaintext - EncodeEncryptedBackup: encode to binary format - EncodeEncryptedBackupBase64: encode to base64 string - DecodeEncryptedBackup: decode from binary format - DecodeEncryptedBackupBase64: decode from base64 string Decryption: - DecryptBackupWithKey: attempt decryption using a single public key - DecryptBackupWithDescriptor: try all keys from a descriptor The format uses 6-byte magic "BIPXXX", version byte, derivation paths, individual secrets (ci values for key recovery), and ChaCha20-Poly1305 encrypted payload containing content type metadata and user data.
Adds two new commands to bitcoin-wallet tool: encryptbackup: Creates an encrypted backup of all wallet descriptors. Outputs base64-encoded backup to stdout. Requires: -wallet=<name> decryptbackup: Decrypts a backup using a provided extended public key (xpub/tpub). Reads base64 backup from stdin, outputs JSON to stdout. Requires: -pubkey=<xpub> The output is compatible with the importdescriptors RPC. The decryption only requires an xpub that was used in the original wallet. In a recovery scenario, the user derives this from their seed phrase at a known derivation path (e.g., m/84'/0'/0'). Includes functional test demonstrating the full roundtrip.
Display unencrypted metadata from a BIP-xxxx encrypted backup: - Format version - Number of recipients - Encryption algorithm - Derivation paths (if present)
To include derivation path in backup header.
695d392 to
90fe3c7
Compare
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
Implements bitcoin/bips#1951
DO NOT USE YET
Backups generated with this code are guaranteed to be useless, because the BIP number hasn't been assigned yet - which is part of the encryption scheme.
The spec is also not final yet and will probably be adjusted. I'm not going to implement backward compatibility until the spec is final.
Even if the BIP is final, there's no guarantee this will ever make it into Bitcoin Core, so you may to use an alternative implementation.
It's also entirely vibe coded. Despite much back and forth with Claude Opus 4.5, I have not yet thoroughly reviewed every commit it wrote.