mirror of
https://github.com/bitcoin/bips.git
synced 2026-10-19 19:29:18 +00:00
Merge pull request #1951 from pythcoiner/encrypted_descriptor
BIP138: Compact Encryption Scheme for Non-seed Wallet Data
This commit is contained in:
@@ -827,6 +827,13 @@ users (see also: [https://en.bitcoin.it/wiki/Economic_majority economic majority
|
||||
| Christopher Gilliard
|
||||
| Specification
|
||||
| Deployed
|
||||
|-
|
||||
| [[bip-0138.md|138]]
|
||||
| Applications
|
||||
| Compact Encryption Scheme for Non-seed Wallet Data
|
||||
| Pyth
|
||||
| Specification
|
||||
| Draft
|
||||
|- style="background-color: #ffcfcf"
|
||||
| [[bip-0140.mediawiki|140]]
|
||||
| Consensus (soft fork)
|
||||
|
||||
619
bip-0138.md
Normal file
619
bip-0138.md
Normal file
@@ -0,0 +1,619 @@
|
||||
```
|
||||
BIP: 138
|
||||
Layer: Applications
|
||||
Title: Compact Encryption Scheme for Non-seed Wallet Data
|
||||
Authors: Pyth <pythcoiner@wizardsardine.com>
|
||||
Status: Draft
|
||||
Type: Specification
|
||||
Assigned: 2026-05-11
|
||||
License: BSD-2-Clause
|
||||
Discussion: https://delvingbitcoin.org/t/a-simple-backup-scheme-for-wallet-accounts/1607
|
||||
https://groups.google.com/g/bitcoindev/c/5NgJbpVDgEc/m/TtGK9sF9BgAJ
|
||||
https://github.com/bitcoin/bips/pull/1951
|
||||
Requires: 32, 340, 380, 388, 389
|
||||
```
|
||||
|
||||
## Introduction
|
||||
|
||||
### Abstract
|
||||
|
||||
This BIP defines a compact encryption scheme for **output script descriptors** (BIP-0380),
|
||||
**wallet policies** (BIP-0388), and other wallet metadata.
|
||||
The payload must not contain any private key material.
|
||||
|
||||
Users can store encrypted backups on untrusted media or cloud services without leaking
|
||||
addresses, script structures, or cosigner counts. The encryption key derives from the
|
||||
lexicographically-sorted public keys in the descriptor, allowing any keyholder to decrypt
|
||||
without additional secrets.
|
||||
|
||||
Though designed for descriptors and policies, the scheme works equally well for labels
|
||||
and backup metadata.
|
||||
|
||||
### Copyright
|
||||
|
||||
This BIP is licensed under the BSD 2-Clause License.
|
||||
Redistribution and use in source and binary forms, with or without modification, are
|
||||
permitted provided that the above copyright notice and this permission notice appear
|
||||
in all copies.
|
||||
|
||||
### Motivation
|
||||
|
||||
Losing the **wallet descriptor** (or **wallet policy**) is almost as catastrophic as
|
||||
losing the seed itself. The seed lets you sign, but the descriptor maps you to your coins.
|
||||
For multisig or miniscript wallets, keys alone are insufficient: without the descriptor, you
|
||||
can't reconstruct the script.
|
||||
|
||||
Multisig setups can be designed to retain access to coins even if one of the
|
||||
seeds is lost, for example a 3-of-3 MuSig2 keypath with a script path that lets
|
||||
2-of-3 recover. But when one seed is lost, its public key may also be lost,
|
||||
rendering the coins inaccessible. This risk is not intuitive.
|
||||
|
||||
Offline storage of descriptors has two practical obstacles:
|
||||
|
||||
1. **Descriptors are hard to store offline.**
|
||||
Descriptors can be much longer than a 12/24-word seed. Paper and steel backups
|
||||
become impractical or error-prone, while USB sticks and other offline digital
|
||||
storage solutions degrade over time and are unlikely to survive flood or fire.
|
||||
|
||||
2. **Online redundancy carries privacy risk.**
|
||||
Phones and cloud storage solve the length problem but expose your wallet
|
||||
structure. Plaintext descriptors leak your pubkeys and script details.
|
||||
Cloud storage is often unencrypted, and even cloud encryption could be compromised,
|
||||
depending on (often opaque) implementation details. Its security also reduces to
|
||||
that of the weakest device with cloud access. Each copy increases the attack surface.
|
||||
|
||||
This BIP therefore proposes an **encrypted**, compact backup format that:
|
||||
|
||||
* can be **safely stored in multiple places**, including untrusted online services,
|
||||
* can be **decrypted only by intended holders** of specified _public_ keys,
|
||||
|
||||
See the original [Delving post](https://delvingbitcoin.org/t/a-simple-backup-scheme-for-wallet-accounts/1607/31)
|
||||
for more background.
|
||||
|
||||
### Expected properties
|
||||
|
||||
* **Encrypted**: safe to store with untrusted cloud providers or backup services
|
||||
* **Access controlled**:
|
||||
* only designated cosigners can decrypt, using their xpub
|
||||
* can't be decrypted using public keys revealed on chain
|
||||
* **Easy to implement**:
|
||||
* it should not require any sophisticated tools/libraries
|
||||
* it should not require access to private key material, which secure signing systems may not yield
|
||||
* **Vendor-neutral**: works with any hardware signer
|
||||
|
||||
### Scope
|
||||
|
||||
This proposal targets output script descriptors (BIP-0380) and policies (BIP-0388), but the
|
||||
scheme also works for labels (BIP-0329) and other wallet metadata like
|
||||
wallet backup metadata (BIP-0139).
|
||||
|
||||
Private key material MUST be removed before encrypting any payload.
|
||||
This is because the use of _public key_ material for decryption makes the
|
||||
scheme unsuitable for storing private key material.
|
||||
|
||||
## Specification
|
||||
|
||||
Note: in the following sections, the operator ⊕ refers to the bitwise XOR operation.
|
||||
|
||||
### Secret generation
|
||||
|
||||
- Let $p_1, p_2, \dots, p_n$, be the public keys in the descriptor/wallet policy, in
|
||||
increasing lexicographical order. The scheme is defined for any $n \geq 1$,
|
||||
in particular it supports single-signature descriptors ($n = 1$). Each $p_i$
|
||||
is the x-only-normalized root public key of one *allowed* key expression
|
||||
(see [Descriptor key requirements](#descriptor-key-requirements)).
|
||||
- Let $s$ = tagged_hash("BIP138_DECRYPTION_SECRET", $p_1$ | $p_2$ | ... | $p_n$)
|
||||
- Let $s_i$ = tagged_hash("BIP138_INDIVIDUAL_SECRET", $p_i$)
|
||||
- Let $c_i$ = $s$ ⊕ $s_i$
|
||||
|
||||
where tagged_hash(tag, m) = sha256(sha256(tag) | sha256(tag) | m) is the tagged
|
||||
hash construction from [BIP340](bip-0340.mediawiki#design).
|
||||
|
||||
Because $s$ and $s_i$ use distinct domain-separation tags, $s \neq s_i$ and
|
||||
therefore $c_i$ is never the all-zero string.
|
||||
|
||||
Keys published on chain are already kept out of $\{p_1, \dots, p_n\}$ by the
|
||||
[Descriptor key requirements](#descriptor-key-requirements).
|
||||
Implementations MUST exclude the key with x coordinate
|
||||
`50929b74c1a04954b78b4b6035e97a5e078a5a0f28ec96d547bfee9ace803ac0` (the BIP341 NUMS
|
||||
point). Applications MAY exclude any further key they know to be public.
|
||||
|
||||
Applications that exclude keys beyond the NUMS point SHOULD document which keys they
|
||||
exclude, so that users know which keys cannot open the backup. A cosigner holding an
|
||||
excluded key will simply fail to decrypt, while the cosigners holding the keys that
|
||||
remain in $\{p_1, \dots, p_n\}$ can still decrypt the backup.
|
||||
|
||||
**Note:** A key is *publicly known* when a third party can learn it without the wallet
|
||||
owner disclosing it. There is no registry of such keys. In practice they come from two
|
||||
sources: the blockchain, and well-known constants.
|
||||
|
||||
**Warning:** An xpub can be known to a third party without ever appearing on chain.
|
||||
Some single-signature wallets, such as the Ledger and Trezor desktop apps, send the
|
||||
BIP44/49/84/86 account xpub to a server, the server then derive every key from
|
||||
that xpub. For a single-signature descriptor this leaks little the server does not
|
||||
already know, but reusing such an xpub as a key of a multisig descriptor lets that
|
||||
server decrypt every backup of the multisig. Users SHOULD build a multisig from
|
||||
accounts whose xpub was never sent to such a server, such as BIP48 or BIP87 accounts.
|
||||
|
||||
### Descriptor key requirements
|
||||
|
||||
Only key expressions of the extended-public-key type with a trailing
|
||||
derivation step or wildcard contribute to $\{p_1, \dots, p_n\}$. Without
|
||||
that derivation, the xpub's root pubkey, used to seed $s$, would also be
|
||||
the on-chain pubkey of every spend, so observing one spend would let
|
||||
anyone recompute $s$ and decrypt the backup.[^trailing-derivation] The
|
||||
rule generalizes to any network prefix (`xpub`/`tpub`/`Vpub`/...).
|
||||
|
||||
[^trailing-derivation]: **Why require trailing derivation?**
|
||||
Any trailing derivation step, or the implicit child derivation forced by
|
||||
a wildcard, breaks the identity between the xpub root pubkey and the
|
||||
on-chain pubkey. Fixed-derivation expressions like `xpub.../0/5` are
|
||||
allowed because the on-chain key (`xpub/0/5`) already differs from the
|
||||
encryption seed (the xpub root). Literal pubkeys and bare xpubs are
|
||||
disallowed for the same reason: the literal value is exactly what goes
|
||||
on-chain, so $s$ would become recoverable from a single observed spend.
|
||||
|
||||
Allowed forms (origin information `[...]` is optional and orthogonal):
|
||||
|
||||
| Form | Example |
|
||||
|-------------------------------------------------------------|-------------------|
|
||||
| `<xpub>/<path>` (fixed derivation, no wildcard) | `xpub.../0/5` |
|
||||
| `<xpub>/*` (wildcard only) | `xpub.../*` |
|
||||
| `<xpub>/<path>/*` (fixed derivation followed by a wildcard) | `xpub.../0/*` |
|
||||
| `<xpub>/<a;b;...>` (multipath, no wildcard) | `xpub.../<0;1>` |
|
||||
| `<xpub>/<a;b;...>/*` (multipath followed by a wildcard) | `xpub.../<0;1>/*` |
|
||||
|
||||
Implementations:
|
||||
|
||||
- MUST exclude every other form (literal pubkeys, bare xpubs, ...) from
|
||||
$\{p_1, \dots, p_n\}$.
|
||||
- MUST refuse to encode a backup if the resulting set is empty.
|
||||
- MUST make the user aware of each excluded expression, since the
|
||||
cosigner holding that key will be unable to decrypt the backup with
|
||||
their key.
|
||||
|
||||
### Key Normalization
|
||||
|
||||
For each allowed expression, take the root extended public key (ignoring
|
||||
origin information, the trailing derivation path, the wildcard, and any
|
||||
multipath specifiers) and extract its x-coordinate. The result is the
|
||||
32-byte **x-only public key** $p_i$.[^x-only]
|
||||
|
||||
[^x-only]: **Why x-only keys?**
|
||||
X-only public keys are 32 bytes, a natural size for cryptographic operations.
|
||||
This format is also used in BIP340 (Schnorr signatures) and BIP341 (Taproot).
|
||||
|
||||
### Encryption
|
||||
|
||||
The format uses CHACHA20_POLY1305 (RFC 8439) as the encryption algorithm,
|
||||
with a 96-bit random nonce and a 128-bit authentication tag to provide confidentiality
|
||||
and integrity.[^chacha-default]
|
||||
|
||||
[^chacha-default]: **Why CHACHA20-POLY1305 ?**
|
||||
ChaCha20-Poly1305 is already used in Bitcoin Core (e.g., BIP324) and is widely
|
||||
available in cryptographic libraries. It performs well in software without
|
||||
hardware acceleration, making it suitable for hardware wallets and embedded devices.
|
||||
|
||||
* let $nonce$ = random(96 bits)
|
||||
* let $ciphertext$ = encrypt($payload$, $secret$, $nonce$)
|
||||
|
||||
The $nonce$ MUST NOT be all zero. If the random source yields an all-zero nonce,
|
||||
the encoder MUST generate a new one.
|
||||
|
||||
### Decryption
|
||||
|
||||
In order to decrypt the payload of a backup, the owner of a certain public key p
|
||||
computes:
|
||||
|
||||
* let $s_i$ = tagged_hash("BIP138_INDIVIDUAL_SECRET", $p$)
|
||||
* for each `individual_secret_i` generate `reconstructed_secret_i` =
|
||||
`individual_secret_i` ⊕ `si`
|
||||
* for each `reconstructed_secret_i` process $payload$ =
|
||||
decrypt($ciphertext$, $secret$, $nonce$)
|
||||
|
||||
Decryption will succeed if and only if **p** was one of the keys in the
|
||||
descriptor/wallet policy.
|
||||
|
||||
### Encoding
|
||||
|
||||
The encrypted backup must be encoded as follows:
|
||||
|
||||
`MAGIC` `VERSION` `DERIVATION_PATHS` `INDIVIDUAL_SECRETS` `ENCRYPTION`
|
||||
`ENCRYPTED_PAYLOAD`
|
||||
|
||||
#### Magic
|
||||
|
||||
`MAGIC`: 6 bytes which are ASCII/UTF-8 representation of **BIP138**.
|
||||
|
||||
#### Version
|
||||
|
||||
`VERSION`: 1 byte unsigned integer representing the format version. The current
|
||||
specification defines version `0x01`.
|
||||
|
||||
#### Derivation Paths
|
||||
|
||||
Derivation paths are optional; they can be useful to simplify the recovery process
|
||||
if one has used a non-common derivation path to derive his key.[^derivation-optional]
|
||||
|
||||
All implementations that can fetch xpubs from a signing device SHOULD try the following
|
||||
common paths automatically:
|
||||
|
||||
- `m/44h/<coin>h/{0..9}h`
|
||||
- `m/49h/<coin>h/{0..9}h`
|
||||
- `m/84h/<coin>h/{0..9}h`
|
||||
- `m/86h/<coin>h/{0..9}h`
|
||||
- `m/87h/<coin>h/{0..9}h`
|
||||
- `m/48h/<coin>h/{0..9}h/1h`
|
||||
- `m/48h/<coin>h/{0..9}h/2h`
|
||||
|
||||
`<coin>` is the BIP44 coin type of the network being recovered: `0` for mainnet
|
||||
and `1` for test networks. `{0..9}h` covers accounts 0 through 9.
|
||||
|
||||
Some signing devices can fail or require confirmation when fetching xpubs for
|
||||
some of these paths. This list is not exhaustive: an implementation MAY treat a
|
||||
path as allowed to fail for any device it supports, in particular
|
||||
`m/87h/<coin>h/{0..9}h`, which is widely under-supported. Implementations SHOULD
|
||||
at least classify these:[^common-derivation-paths]
|
||||
|
||||
- BitBox02: `m/44h/<coin>h/{0..9}h`, `m/87h/<coin>h/{0..9}h`
|
||||
- Ledger: `m/87h/<coin>h/{0..9}h`
|
||||
|
||||
If fetching an xpub for one of these common paths fails or times out and
|
||||
decryption fails, implementations SHOULD warn the user.
|
||||
|
||||
[^derivation-optional]: **Why are derivation paths optional?**
|
||||
When standard derivation paths are used, they are easily discoverable, making
|
||||
them straightforward to brute-force. Omitting them enhances privacy by reducing
|
||||
the information shared publicly about the descriptor scheme.
|
||||
|
||||
[^common-derivation-paths]: **Why this restricted list?**
|
||||
The list covers common account paths for the network being recovered, accounts 0
|
||||
through 9. Some signing devices reject or display some of these paths before
|
||||
exporting an xpub, so implementations should treat the listed paths for that
|
||||
device as optional rather than aborting recovery.
|
||||
|
||||
`DERIVATION_PATH` follows this format:
|
||||
|
||||
`COUNT`
|
||||
`CHILD_COUNT` `CHILD` `...` `CHILD`
|
||||
`...`
|
||||
`CHILD_COUNT` `CHILD` `...` `CHILD`
|
||||
|
||||
`COUNT`: 1-byte unsigned integer (0–255) indicating how many derivation paths are
|
||||
included.
|
||||
`CHILD_COUNT`: 1-byte unsigned integer (1–255) indicating how many children are in
|
||||
the current path.
|
||||
`CHILD`: 4-byte big-endian unsigned integer representing a child index per BIP-32.
|
||||
|
||||
The derivation-path vector SHOULD be encoded in lexicographic order. This avoids
|
||||
leaking information through implementation-specific ordering. The vector SHOULD NOT
|
||||
contain duplicates. Implementations SHOULD deduplicate paths during encoding or
|
||||
parsing.
|
||||
|
||||
#### Individual Secrets
|
||||
|
||||
At least one individual secret must be supplied.[^no-fingerprints]
|
||||
|
||||
[^no-fingerprints]: **Why no fingerprints in plaintext encoding?**
|
||||
Including fingerprints would leak direct information about the descriptor
|
||||
participants, which compromises privacy.
|
||||
|
||||
The `INDIVIDUAL_SECRETS` section follows this format:
|
||||
|
||||
`COUNT`
|
||||
`INDIVIDUAL_SECRET`
|
||||
`INDIVIDUAL_SECRET`
|
||||
|
||||
`COUNT`: 1-byte unsigned integer (1–255) indicating how many secrets are included.
|
||||
`INDIVIDUAL_SECRET`: 32-byte serialization of the derived individual secret.
|
||||
|
||||
The individual secrets vector SHOULD be encoded in lexicographic order. This avoids
|
||||
leaking information through implementation-specific ordering. The vector SHOULD NOT
|
||||
contain duplicates. Implementations SHOULD deduplicate secrets during encoding or
|
||||
parsing.
|
||||
|
||||
Encoders SHOULD append random decoy `INDIVIDUAL_SECRET` entries to hide the exact
|
||||
number of real decryption keys. The total count SHOULD be rounded up to the
|
||||
smallest bucket greater than or equal to the real count, starting at 5 and doubling
|
||||
for each following bucket: 5, 10, 20, and so on. The bucket sequence saturates at
|
||||
the 255 `COUNT` limit: when the smallest fitting bucket would exceed 255, encoders
|
||||
SHOULD pad to 255 instead. Decoders do not distinguish real
|
||||
entries from decoys; they try each entry until one decrypts the payload.
|
||||
|
||||
#### Encryption
|
||||
|
||||
`ENCRYPTION`: 1-byte unsigned integer identifying the encryption algorithm.
|
||||
|
||||
| Value | Definition |
|
||||
|:-------|:---------------------------------------|
|
||||
| 0x00 | Reserved |
|
||||
| 0x01 | CHACHA20_POLY1305 |
|
||||
|
||||
#### Payload Size Limits
|
||||
|
||||
CHACHA20_POLY1305 (per RFC 8439) supports plaintext up to 2^38 - 64 bytes.
|
||||
Implementations MAY impose stricter limits based on platform constraints
|
||||
(e.g., limiting to 2^32 - 1 bytes on 32-bit architectures).
|
||||
|
||||
Implementations MUST reject empty payloads.
|
||||
|
||||
#### Ciphertext
|
||||
|
||||
`CIPHERTEXT` is the encrypted data resulting from encryption of `PAYLOAD` with algorithm
|
||||
defined in `ENCRYPTION` where `PAYLOAD` is encoded following this format:
|
||||
|
||||
`CONTENT_TYPE` `CONTENT_LENGTH` `CONTENT` (`CONTENT_TYPE` `CONTENT_LENGTH` `CONTENT` ...) (`PADDING`)
|
||||
|
||||
`CONTENT_LENGTH`: variable-length integer representing the length of `CONTENT` in bytes.
|
||||
It MUST be present.
|
||||
|
||||
`CONTENT`: the `CONTENT_LENGTH` bytes of payload data.
|
||||
|
||||
`PADDING`: OPTIONAL bytes after the final `CONTENT`, up to the end of the decrypted
|
||||
`PAYLOAD`. Parsers MUST consume exactly `CONTENT_LENGTH` bytes of each `CONTENT`. 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
|
||||
|
||||
Backups that are updated over time can leak information through their size even when the
|
||||
contents are encrypted. A wallet that uploads a new backup after every received transaction
|
||||
can reveal activity to the storage provider through changing payload sizes. This is relevant
|
||||
for mutable payloads such as BIP-329 or BIP-0139.[^padding-privacy]
|
||||
|
||||
Padding is OPTIONAL and is an encoder concern only: decoders ignore the `PADDING` bytes and
|
||||
MUST NOT validate any bucket. Because the padding sits inside `CIPHERTEXT`, the
|
||||
`ENCRYPTED_PAYLOAD` `LENGTH` reveals only the padded size, not the real `PAYLOAD` size.
|
||||
|
||||
Encoders that pad SHOULD zero-fill `PAYLOAD` up to the smallest bucket `S_n` that fits it,
|
||||
with `S_0 = 10240` (10 KiB) and `S_n = floor(S_0 * (5 / 4)^n)`. Payloads of 10 KiB or less
|
||||
are padded to 10 KiB. This keeps padding overhead under 25% above the smallest fitting bucket
|
||||
while coarsening the observable size. Padding is RECOMMENDED for mutable payloads and
|
||||
unnecessary for static ones such as BIP-380 descriptors and BIP-388 wallet policies.
|
||||
|
||||
[^padding-privacy]: **Why pad inside the ciphertext?**
|
||||
Padding the encrypted payload, rather than appending bytes after the backup, hides the
|
||||
real payload size from anyone who parses the backup, not just from someone who measures
|
||||
the file size. The size field a parser sees is the padded `ENCRYPTED_PAYLOAD` `LENGTH`.
|
||||
|
||||
#### Integer Encodings
|
||||
|
||||
All variable-length integers are encoded as
|
||||
[compact size](https://en.bitcoin.it/wiki/Protocol_documentation#Variable_length_integer).
|
||||
|
||||
#### Content Type
|
||||
|
||||
`CONTENT_TYPE` is a variable length field defining the type of the `CONTENT` that follows
|
||||
it. It follows this format:
|
||||
|
||||
`TYPE` (`TYPE_LENGTH`) `TYPE_PARAMS`
|
||||
|
||||
A `PAYLOAD` carries one or more `CONTENT_TYPE CONTENT_LENGTH CONTENT` items, each `CONTENT_TYPE`
|
||||
describing the `CONTENT` 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 `TYPE_PARAMS`.
|
||||
|
||||
| Value | Definition |
|
||||
|:-------|:---------------------------------------|
|
||||
| 0x00 | End of content items; padding follows |
|
||||
| 0x01 | BIP Number (big-endian uint16) |
|
||||
| 0x02 | Vendor-Specific Opaque Tag |
|
||||
| 0x03 | String |
|
||||
|
||||
`TYPE_LENGTH`: variable-length integer representing the length of `TYPE_PARAMS` in bytes.
|
||||
|
||||
For all `TYPE` values except `0x01`, `TYPE_LENGTH` MUST be present.[^length-required]
|
||||
|
||||
[^length-required]: **Why is `TYPE_LENGTH` mandatory?**
|
||||
`TYPE_LENGTH` is what lets a parser skip a content type it does not implement and still
|
||||
read the items that follow; without it, the parser cannot know where `TYPE_PARAMS` ends.
|
||||
A string note placed before a descriptor, for example, must not stop an
|
||||
implementation that only handles descriptors from recovering that descriptor. A
|
||||
type whose `TYPE_PARAMS` is always empty still carries a zero `TYPE_LENGTH` for this reason.
|
||||
`0x01` is exempt because every implementation handles it, so it is never skipped
|
||||
blindly.
|
||||
|
||||
`TYPE_PARAMS`: variable-length field whose encoding depends on `TYPE`.
|
||||
|
||||
For `TYPE` values defined above:
|
||||
- 0x00: parsers MUST stop reading content items and treat the remaining bytes as
|
||||
padding.
|
||||
- 0x01: `TYPE_LENGTH` MUST be omitted and `TYPE_PARAMS` is a 2-byte big-endian unsigned integer
|
||||
representing the BIP number that defines it.
|
||||
- 0x02: `TYPE_PARAMS` MUST be `TYPE_LENGTH` bytes of opaque, vendor-specific data.
|
||||
- 0x03: `TYPE_PARAMS` MUST be empty, and the following `CONTENT` is the string itself,
|
||||
which MUST be valid UTF-8.
|
||||
|
||||
For all `TYPE` values except `0x01`, parsers MUST reject `CONTENT_TYPE` if `TYPE_LENGTH` exceeds
|
||||
the remaining payload bytes.
|
||||
|
||||
For an unknown `TYPE` less than `0x80`, parsers MUST consume its `TYPE_LENGTH` bytes of
|
||||
`TYPE_PARAMS`, treat the content type as unknown, consume the following payload
|
||||
`CONTENT_LENGTH` and `CONTENT`, and continue with the next item.
|
||||
|
||||
For an unknown `TYPE` greater than or equal to `0x80`, parsers MUST reject the
|
||||
payload.[^type-upgrade]
|
||||
|
||||
[^type-upgrade]: **Why the 0x80 threshold?**
|
||||
The `TYPE >= 0x80` rule keeps the encoding upgradeable. A future version can
|
||||
define a new content type at or above `0x80` that older parsers reject rather
|
||||
than misread, while types below `0x80` stay backward compatible.
|
||||
|
||||
#### BIP380 Descriptor Backup Content
|
||||
|
||||
When `CONTENT_TYPE` is `TYPE = 0x01` with `TYPE_PARAMS = 0x017c` (BIP380), `CONTENT` is a
|
||||
UTF-8 BIP380 descriptor backup. It is either a single bare descriptor string, or
|
||||
a JSON descriptor backup document (for several descriptors) when the first
|
||||
character is `{`.
|
||||
|
||||
Test vectors are in
|
||||
[`bip380_descriptor_backup.json`](./bip-0138/test_vectors/bip380_descriptor_backup.json).
|
||||
|
||||
Descriptor strings MUST NOT contain private key material and SHOULD include a
|
||||
checksum.
|
||||
|
||||
##### JSON Descriptor Backup Documents
|
||||
|
||||
The descriptor backup document is a JSON object with the following fields:
|
||||
|
||||
- `version`: integer. This specification defines version `1`.
|
||||
- `descriptor_sets`: array of descriptor set objects.
|
||||
|
||||
Each descriptor set describes BIP380 output script descriptors belonging to one
|
||||
logical account or script family.
|
||||
|
||||
##### Descriptor Set Fields
|
||||
|
||||
`descriptor` is a required string containing a BIP380 output script descriptor.
|
||||
|
||||
For BIP389 multipath descriptors, `/<0;1>` means receive and change,
|
||||
respectively. The `change_descriptor` field MUST NOT be used.
|
||||
|
||||
For descriptors without BIP389 multipath key expressions, `descriptor` is the
|
||||
receive descriptor and `change_descriptor` is the change descriptor.
|
||||
|
||||
If optional boolean `archived` is `true`, importing wallets SHOULD NOT use the
|
||||
descriptor set for new address generation.
|
||||
|
||||
`range` is an optional two-element array `[start, end]`, inclusive, describing
|
||||
the ranged derivation indexes covered by the descriptor set.
|
||||
|
||||
`birth_time` is an optional integer Unix timestamp in seconds, indicating a
|
||||
lower bound for when the descriptor set may have received funds. Importing
|
||||
wallets MAY use this value as a scanning hint.
|
||||
|
||||
#### BIP388 Wallet Policy Backup Content
|
||||
|
||||
When `CONTENT_TYPE` is `TYPE = 0x01` with `TYPE_PARAMS = 0x0184` (BIP388), `CONTENT` is a
|
||||
UTF-8 JSON wallet policy backup document. A BIP388 wallet policy is a descriptor
|
||||
template plus a vector of key information items, as defined in BIP388.
|
||||
|
||||
Test vectors are in
|
||||
[`bip388.json`](./bip-0138/test_vectors/bip388.json).
|
||||
|
||||
The document is one of two forms:
|
||||
|
||||
- A single policy, a JSON object `{ "keys": [...], "policy": "<template>" }`.
|
||||
- Multiple policies, a JSON object `{ "version": 1, "policy_sets": [...] }`.
|
||||
|
||||
Parsers select the form by structure: an object with a `policy_sets` field is the
|
||||
multiple form, an object with a `policy` field is the single form.
|
||||
|
||||
##### Policy Fields
|
||||
|
||||
`keys` is a required array of BIP388 key information items, each a serialized
|
||||
extended public key with optional key origin (`[fingerprint/path]xpub`). It MUST
|
||||
contain at least one key. Keys MUST NOT contain private key material.
|
||||
|
||||
`policy` is a required non-empty string containing a BIP388 wallet descriptor
|
||||
template, with `@i` key placeholders referring to `keys`.
|
||||
|
||||
##### Policy Set Fields
|
||||
|
||||
A policy set has the same `keys` and `policy` fields as the single form, plus the
|
||||
optional metadata fields:
|
||||
|
||||
If optional boolean `archived` is `true`, importing wallets SHOULD NOT use the
|
||||
policy for new address generation.
|
||||
|
||||
`range` is an optional two-element array `[start, end]`, inclusive, describing the
|
||||
ranged derivation indexes covered by the policy.
|
||||
|
||||
`birth_time` is an optional integer Unix timestamp in seconds, indicating a lower
|
||||
bound for when the policy may have received funds. Importing wallets MAY use this
|
||||
value as a scanning hint.
|
||||
|
||||
##### Multiple Policies Document
|
||||
|
||||
The multiple form is a JSON object with the following fields:
|
||||
|
||||
- `version`: integer. This specification defines version `1`.
|
||||
- `policy_sets`: array of policy set objects.
|
||||
|
||||
#### Encrypted Payload
|
||||
|
||||
`ENCRYPTED_PAYLOAD` follows this format:
|
||||
|
||||
`NONCE` `LENGTH` `CIPHERTEXT`
|
||||
|
||||
`NONCE`: 12-byte (96-bit) nonce. Parsers MUST reject a backup whose `NONCE` is all zero.
|
||||
`LENGTH`: variable-length integer representing ciphertext length.
|
||||
`CIPHERTEXT`: variable-length ciphertext.
|
||||
|
||||
Note: `CIPHERTEXT` is followed by the end of the `ENCRYPTED_PAYLOAD` section.
|
||||
Compliant parsers MUST stop reading after consuming `LENGTH` bytes of ciphertext;
|
||||
additional trailing bytes are reserved for vendor-specific extensions and MUST
|
||||
be ignored.
|
||||
|
||||
### Text Representation
|
||||
|
||||
Implementations SHOULD encode and decode the backup using Base64 (RFC 4648).[^psbt-base64]
|
||||
|
||||
[^psbt-base64]: **Why Base64?**
|
||||
PSBT (BIP174) is commonly exchanged as a Base64 string, so wallet software
|
||||
likely already supports this representation.
|
||||
|
||||
### File Extension
|
||||
|
||||
Backups saved to a file SHOULD use the `.bip138` file extension for the raw binary
|
||||
encoding and the `.txt` extension for the Base64 text representation, so that the
|
||||
extension tells implementations which encoding to expect.
|
||||
|
||||
## Rationale
|
||||
|
||||
See footnotes throughout the specification for design rationale.
|
||||
|
||||
### Future Extensions
|
||||
|
||||
The version field enables possible future enhancements:
|
||||
|
||||
- Additional encryption algorithms
|
||||
- Support for threshold-based decryption
|
||||
- Hiding number of participants
|
||||
- bech32m export
|
||||
|
||||
### Implementation
|
||||
|
||||
- Rust [implementation](https://github.com/pythcoiner/bip138)
|
||||
|
||||
### Test Vectors
|
||||
|
||||
[key_types.json](./bip-0138/test_vectors/keys_types.json) contains test
|
||||
vectors for key serialisations.
|
||||
[content_type.json](./bip-0138/test_vectors/content_type.json) contains test
|
||||
vectors for content types serialisations.
|
||||
[derivation_path.json](./bip-0138/test_vectors/derivation_path.json) contains
|
||||
test vectors for derivation paths serialisations.
|
||||
[individual_secrets.json](./bip-0138/test_vectors/individual_secrets.json)
|
||||
contains test vectors for individual secrets serialization.
|
||||
[encryption_secret.json](./bip-0138/test_vectors/encryption_secret.json)
|
||||
contains test vectors for generation of encryption secret.
|
||||
[chacha20poly1305_encryption.json](./bip-0138/test_vectors/chacha20poly1305_encryption.json)
|
||||
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, 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)
|
||||
contains test vectors for BIP388 wallet policy backup documents.
|
||||
|
||||
## Backward Compatibility
|
||||
|
||||
This BIP defines a new format and changes no existing one. Liana wallet uses an early
|
||||
version of this BIP, which is not compatible: its magic is `BEB` rather than `BIP138`.
|
||||
|
||||
## Acknowledgements
|
||||
|
||||
This BIP builds on the backup scheme proposed by @bigspider on
|
||||
[Delving Bitcoin](https://delvingbitcoin.org/t/a-simple-backup-scheme-for-wallet-accounts/1607),
|
||||
who also suggested the payload padding design.
|
||||
|
||||
Thanks to @Sjors for extensive reviews, many design contributions to the payload
|
||||
encoding, and a proof-of-concept implementation on top of Bitcoin Core. Thanks
|
||||
also to @murchandamus, @jonatack, @craigraw, @jp1ac4, and @torkelrogstad for
|
||||
their reviews and suggestions.
|
||||
33
bip-0138/test_vectors/bip380_descriptor_backup.json
Normal file
33
bip-0138/test_vectors/bip380_descriptor_backup.json
Normal file
@@ -0,0 +1,33 @@
|
||||
[
|
||||
{
|
||||
"description": "Descriptor with change descriptor",
|
||||
"valid": true,
|
||||
"document": {
|
||||
"version": 1,
|
||||
"descriptor_sets": [
|
||||
{
|
||||
"archived": false,
|
||||
"birth_time": 1710000000,
|
||||
"range": [0, 999],
|
||||
"descriptor": "wpkh([d34db33f/84h/1h/0h]tpubDC5FSnBiZDMmhiuCmWAYsLwgLYrrT9rAqvTySfuCCrgsWz8wxMXUS9Tb9iVMvcRbvFcAHGkMD5Kx8koh4GquNGNTfohfk7pgjhaPCdXpoba/0/*)",
|
||||
"change_descriptor": "wpkh([d34db33f/84h/1h/0h]tpubDC5FSnBiZDMmhiuCmWAYsLwgLYrrT9rAqvTySfuCCrgsWz8wxMXUS9Tb9iVMvcRbvFcAHGkMD5Kx8koh4GquNGNTfohfk7pgjhaPCdXpoba/1/*)"
|
||||
}
|
||||
]
|
||||
}
|
||||
},
|
||||
{
|
||||
"description": "BIP389 multipath descriptor",
|
||||
"valid": true,
|
||||
"document": {
|
||||
"version": 1,
|
||||
"descriptor_sets": [
|
||||
{
|
||||
"archived": false,
|
||||
"birth_time": 1710000000,
|
||||
"range": [0, 999],
|
||||
"descriptor": "wpkh([d34db33f/84h/1h/0h]tpubDC5FSnBiZDMmhiuCmWAYsLwgLYrrT9rAqvTySfuCCrgsWz8wxMXUS9Tb9iVMvcRbvFcAHGkMD5Kx8koh4GquNGNTfohfk7pgjhaPCdXpoba/<0;1>/*)"
|
||||
}
|
||||
]
|
||||
}
|
||||
}
|
||||
]
|
||||
92
bip-0138/test_vectors/bip388.json
Normal file
92
bip-0138/test_vectors/bip388.json
Normal file
@@ -0,0 +1,92 @@
|
||||
[
|
||||
{
|
||||
"description": "single pkh policy",
|
||||
"valid": true,
|
||||
"document": {
|
||||
"keys": [
|
||||
"[d34db33f/44'/0'/0']xpub6ERApfZwUNrhLCkDtcHTcxd75RbzS1ed54G1LkBUHQVHQKqhMkhgbmJbZRkrgZw4koxb5JaHWkY4ALHY2grBGRjaDMzQLcgJvLJuZZvRcEL"
|
||||
],
|
||||
"policy": "pkh(@0/**)"
|
||||
}
|
||||
},
|
||||
{
|
||||
"description": "multiple policy sets with metadata",
|
||||
"valid": true,
|
||||
"document": {
|
||||
"version": 1,
|
||||
"policy_sets": [
|
||||
{
|
||||
"keys": [
|
||||
"[6738736c/48'/0'/0'/2']xpub6FC1fXFP1GXLX5TKtcjHGT4q89SDRehkQLtbKJ2PzWcvbBHtyDsJPLtpLtkGqYNYZdVVAjRQ5kug9CsapegmmeRutpP7PW4u4wVF9JfkDhw",
|
||||
"[b2b1f0cf/48'/0'/0'/2']xpub6EWhjpPa6FqrcaPBuGBZRJVjzGJ1ZsMygRF26RwN932Vfkn1gyCiTbECVitBjRCkexEvetLdiqzTcYimmzYxyR1BZ79KNevgt61PDcukmC7"
|
||||
],
|
||||
"policy": "wsh(sortedmulti(2,@0/**,@1/**))",
|
||||
"archived": true,
|
||||
"range": [
|
||||
0,
|
||||
999
|
||||
],
|
||||
"birth_time": 1710000000
|
||||
},
|
||||
{
|
||||
"keys": [
|
||||
"[d34db33f/44'/0'/0']xpub6ERApfZwUNrhLCkDtcHTcxd75RbzS1ed54G1LkBUHQVHQKqhMkhgbmJbZRkrgZw4koxb5JaHWkY4ALHY2grBGRjaDMzQLcgJvLJuZZvRcEL"
|
||||
],
|
||||
"policy": "pkh(@0/**)"
|
||||
}
|
||||
]
|
||||
}
|
||||
},
|
||||
{
|
||||
"description": "version not one",
|
||||
"valid": false,
|
||||
"document": {
|
||||
"version": 2,
|
||||
"policy_sets": [
|
||||
{
|
||||
"keys": [
|
||||
"[d34db33f/44'/0'/0']xpub6ERApfZwUNrhLCkDtcHTcxd75RbzS1ed54G1LkBUHQVHQKqhMkhgbmJbZRkrgZw4koxb5JaHWkY4ALHY2grBGRjaDMzQLcgJvLJuZZvRcEL"
|
||||
],
|
||||
"policy": "pkh(@0/**)"
|
||||
}
|
||||
]
|
||||
}
|
||||
},
|
||||
{
|
||||
"description": "missing policy",
|
||||
"valid": false,
|
||||
"document": {
|
||||
"keys": [
|
||||
"[d34db33f/44'/0'/0']xpub6ERApfZwUNrhLCkDtcHTcxd75RbzS1ed54G1LkBUHQVHQKqhMkhgbmJbZRkrgZw4koxb5JaHWkY4ALHY2grBGRjaDMzQLcgJvLJuZZvRcEL"
|
||||
]
|
||||
}
|
||||
},
|
||||
{
|
||||
"description": "empty policy",
|
||||
"valid": false,
|
||||
"document": {
|
||||
"keys": [
|
||||
"[d34db33f/44'/0'/0']xpub6ERApfZwUNrhLCkDtcHTcxd75RbzS1ed54G1LkBUHQVHQKqhMkhgbmJbZRkrgZw4koxb5JaHWkY4ALHY2grBGRjaDMzQLcgJvLJuZZvRcEL"
|
||||
],
|
||||
"policy": ""
|
||||
}
|
||||
},
|
||||
{
|
||||
"description": "empty keys",
|
||||
"valid": false,
|
||||
"document": {
|
||||
"keys": [],
|
||||
"policy": "pkh(@0/**)"
|
||||
}
|
||||
},
|
||||
{
|
||||
"description": "single literal pubkey in keys",
|
||||
"valid": false,
|
||||
"document": {
|
||||
"keys": [
|
||||
"0279be667ef9dcbbac55a06295ce870b07029bfcdb2dce28d959f2815b16f81798"
|
||||
],
|
||||
"policy": "pkh(@0/**)"
|
||||
}
|
||||
}
|
||||
]
|
||||
37
bip-0138/test_vectors/chacha20poly1305_encryption.json
Normal file
37
bip-0138/test_vectors/chacha20poly1305_encryption.json
Normal file
@@ -0,0 +1,37 @@
|
||||
[
|
||||
{
|
||||
"description": "Basic encryption with short plaintext",
|
||||
"nonce": "000102030405060708090a0b",
|
||||
"plaintext": "48656c6c6f",
|
||||
"secret": "0000000000000000000000000000000000000000000000000000000000000000",
|
||||
"ciphertext": "7df9cb9a0ac5851cc054b14d05f781127b2b0d31fa"
|
||||
},
|
||||
{
|
||||
"description": "Empty plaintext should fail",
|
||||
"nonce": "000102030405060708090a0b",
|
||||
"plaintext": "",
|
||||
"secret": "0000000000000000000000000000000000000000000000000000000000000000",
|
||||
"ciphertext": null
|
||||
},
|
||||
{
|
||||
"description": "Encryption with zeroed nonce should fail",
|
||||
"nonce": "000000000000000000000000",
|
||||
"plaintext": "00000000000000000000000000000000",
|
||||
"secret": "0000000000000000000000000000000000000000000000000000000000000000",
|
||||
"ciphertext": null
|
||||
},
|
||||
{
|
||||
"description": "Encryption with all FFs",
|
||||
"nonce": "ffffffffffffffffffffffff",
|
||||
"plaintext": "ffffffffffffffffffffffffffffffff",
|
||||
"secret": "ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff",
|
||||
"ciphertext": "22d8bfc313e141bd692c82cec7785b29a0e5d5014c0d3b2d3a8b00548cd8d221"
|
||||
},
|
||||
{
|
||||
"description": "Longer plaintext",
|
||||
"nonce": "0f1e2d3c4b5a69788796a5b4",
|
||||
"plaintext": "546869732069732061206c6f6e67657220706c61696e746578742074686174207368756c6420626520656e637279707465642070726f7065726c792e",
|
||||
"secret": "deadbeefdeadbeefdeadbeefdeadbeefdeadbeefdeadbeefdeadbeefdeadbeef",
|
||||
"ciphertext": "2af094190e2b43a02b8dd6bfc25a8833f84f81bc6f690d75f0214e466ef392616c4644bee65118c444a926e1e365b3a7ba0509a5636524eb4e5722f5926938f32e4df79237acb6dd4a6ccbc4"
|
||||
}
|
||||
]
|
||||
82
bip-0138/test_vectors/content_type.json
Normal file
82
bip-0138/test_vectors/content_type.json
Normal file
@@ -0,0 +1,82 @@
|
||||
[
|
||||
{
|
||||
"description": "Bip 138",
|
||||
"valid": true,
|
||||
"content": "01008a"
|
||||
},
|
||||
{
|
||||
"description": "Bip 380",
|
||||
"valid": true,
|
||||
"content": "01017c"
|
||||
},
|
||||
{
|
||||
"description": "Bip 388",
|
||||
"valid": true,
|
||||
"content": "010184"
|
||||
},
|
||||
{
|
||||
"description": "Bip 329",
|
||||
"valid": true,
|
||||
"content": "010149"
|
||||
},
|
||||
{
|
||||
"description": "Bip 999",
|
||||
"valid": true,
|
||||
"content": "0103e7"
|
||||
},
|
||||
{
|
||||
"description": "Bip max",
|
||||
"valid": true,
|
||||
"content": "01ffff"
|
||||
},
|
||||
{
|
||||
"description": "Bip min",
|
||||
"valid": true,
|
||||
"content": "010000"
|
||||
},
|
||||
{
|
||||
"description": "Propietary 00010203",
|
||||
"valid": true,
|
||||
"content": "020400010203"
|
||||
},
|
||||
{
|
||||
"description": "String",
|
||||
"valid": true,
|
||||
"content": "0300"
|
||||
},
|
||||
{
|
||||
"description": "TYPE 0x00 ends the content items",
|
||||
"valid": false,
|
||||
"content": "00"
|
||||
},
|
||||
{
|
||||
"description": "Invalid BIP (insufficient bytes)",
|
||||
"valid": false,
|
||||
"content": "0100"
|
||||
},
|
||||
{
|
||||
"description": "Invalid proprietary (missing data)",
|
||||
"valid": false,
|
||||
"content": "0201"
|
||||
},
|
||||
{
|
||||
"description": "Invalid proprietary (TYPE_LENGTH exceeds payload)",
|
||||
"valid": false,
|
||||
"content": "020500"
|
||||
},
|
||||
{
|
||||
"description": "Invalid string (metadata must be empty)",
|
||||
"valid": false,
|
||||
"content": "030161"
|
||||
},
|
||||
{
|
||||
"description": "TYPE >= 0x80 stops parsing",
|
||||
"valid": false,
|
||||
"content": "ff"
|
||||
},
|
||||
{
|
||||
"description": "TYPE >= 0x80 stops parsing",
|
||||
"valid": false,
|
||||
"content": "ff000000"
|
||||
}
|
||||
]
|
||||
186
bip-0138/test_vectors/derivation_path.json
Normal file
186
bip-0138/test_vectors/derivation_path.json
Normal file
@@ -0,0 +1,186 @@
|
||||
[
|
||||
{
|
||||
"description": "Empty derivation paths",
|
||||
"paths": [],
|
||||
"expected": "00"
|
||||
},
|
||||
{
|
||||
"description": "Single path with one child: m/0",
|
||||
"paths": ["m/0"],
|
||||
"expected": "010100000000"
|
||||
},
|
||||
{
|
||||
"description": "Single path with hardened child: m/44'",
|
||||
"paths": ["m/44'"],
|
||||
"expected": "01018000002c"
|
||||
},
|
||||
{
|
||||
"description": "Standard BIP-84 path: m/84'/0'/0'",
|
||||
"paths": ["m/84'/0'/0'"],
|
||||
"expected": "0103800000548000000080000000"
|
||||
},
|
||||
{
|
||||
"description": "Mixed hardened and normal: m/0/1'/2/3'",
|
||||
"paths": ["m/0/1'/2/3'"],
|
||||
"expected": "010400000000800000010000000280000003"
|
||||
},
|
||||
{
|
||||
"description": "Multiple paths: m/0/1'/2/3' and m/84'/0'/0'/2'",
|
||||
"paths": ["m/0/1'/2/3'", "m/84'/0'/0'/2'"],
|
||||
"expected": "0204000000008000000100000002800000030480000054800000008000000080000002"
|
||||
},
|
||||
{
|
||||
"description": "Path with large indices: m/2147483647'/2147483646",
|
||||
"paths": ["m/2147483647'/2147483646"],
|
||||
"expected": "0102ffffffff7ffffffe"
|
||||
},
|
||||
{
|
||||
"description": "Single child path: m/1",
|
||||
"paths": ["m/1"],
|
||||
"expected": "010100000001"
|
||||
},
|
||||
{
|
||||
"description": "Path with max normal index: m/2147483647",
|
||||
"paths": ["m/2147483647"],
|
||||
"expected": "01017fffffff"
|
||||
},
|
||||
{
|
||||
"description": "Path with multiple normal indices: m/0/1/2/3/4",
|
||||
"paths": ["m/0/1/2/3/4"],
|
||||
"expected": "01050000000000000001000000020000000300000004"
|
||||
},
|
||||
{
|
||||
"description": "Path with all hardened: m/0'/1'/2'",
|
||||
"paths": ["m/0'/1'/2'"],
|
||||
"expected": "0103800000008000000180000002"
|
||||
},
|
||||
{
|
||||
"description": "Two different single-child paths: m/0 and m/1",
|
||||
"paths": ["m/0", "m/1"],
|
||||
"expected": "0201000000000100000001"
|
||||
},
|
||||
{
|
||||
"description": "Unsorted paths are sorted when encoded",
|
||||
"paths": ["m/84'/0'/0'/2'", "m/0/1'/2/3'"],
|
||||
"expected": "0204000000008000000100000002800000030480000054800000008000000080000002"
|
||||
},
|
||||
{
|
||||
"description": "Duplicate paths are deduplicated",
|
||||
"paths": ["m/1", "m/0", "m/1"],
|
||||
"expected": "0201000000000100000001"
|
||||
},
|
||||
{
|
||||
"description": "BIP-44 account 0: m/44'/0'/0'",
|
||||
"paths": ["m/44'/0'/0'"],
|
||||
"expected": "01038000002c8000000080000000"
|
||||
},
|
||||
{
|
||||
"description": "BIP-49 account 0: m/49'/0'/0'",
|
||||
"paths": ["m/49'/0'/0'"],
|
||||
"expected": "0103800000318000000080000000"
|
||||
},
|
||||
{
|
||||
"description": "Common fallback path: m/49'/0'/9'",
|
||||
"paths": ["m/49'/0'/9'"],
|
||||
"expected": "0103800000318000000080000009"
|
||||
},
|
||||
{
|
||||
"description": "Common fallback path: m/84'/1'/9'",
|
||||
"paths": ["m/84'/1'/9'"],
|
||||
"expected": "0103800000548000000180000009"
|
||||
},
|
||||
{
|
||||
"description": "Common fallback path: m/86'/1'/9'",
|
||||
"paths": ["m/86'/1'/9'"],
|
||||
"expected": "0103800000568000000180000009"
|
||||
},
|
||||
{
|
||||
"description": "Fallible fallback path: m/87'/1'/9'",
|
||||
"paths": ["m/87'/1'/9'"],
|
||||
"expected": "0103800000578000000180000009"
|
||||
},
|
||||
{
|
||||
"description": "Common fallback path: m/48'/0'/9'/1'",
|
||||
"paths": ["m/48'/0'/9'/1'"],
|
||||
"expected": "010480000030800000008000000980000001"
|
||||
},
|
||||
{
|
||||
"description": "Common fallback path: m/48'/1'/9'/2'",
|
||||
"paths": ["m/48'/1'/9'/2'"],
|
||||
"expected": "010480000030800000018000000980000002"
|
||||
},
|
||||
{
|
||||
"description": "Single path with 255 children (maximum depth, success)",
|
||||
"paths": ["m/0/0/0/0/0/0/0/0/0/0/0/0/0/0/0/0/0/0/0/0/0/0/0/0/0/0/0/0/0/0/0/0/0/0/0/0/0/0/0/0/0/0/0/0/0/0/0/0/0/0/0/0/0/0/0/0/0/0/0/0/0/0/0/0/0/0/0/0/0/0/0/0/0/0/0/0/0/0/0/0/0/0/0/0/0/0/0/0/0/0/0/0/0/0/0/0/0/0/0/0/0/0/0/0/0/0/0/0/0/0/0/0/0/0/0/0/0/0/0/0/0/0/0/0/0/0/0/0/0/0/0/0/0/0/0/0/0/0/0/0/0/0/0/0/0/0/0/0/0/0/0/0/0/0/0/0/0/0/0/0/0/0/0/0/0/0/0/0/0/0/0/0/0/0/0/0/0/0/0/0/0/0/0/0/0/0/0/0/0/0/0/0/0/0/0/0/0/0/0/0/0/0/0/0/0/0/0/0/0/0/0/0/0/0/0/0/0/0/0/0/0/0/0/0/0/0/0/0/0/0/0/0/0/0/0/0/0/0/0/0/0/0/0/0/0/0/0/0/0/0/0/0/0/0/0"],
|
||||
"expected": "01ff000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000"
|
||||
},
|
||||
{
|
||||
"description": "256 paths should fail (exceeds u8::MAX)",
|
||||
"paths": [
|
||||
"m/0", "m/1", "m/2", "m/3", "m/4", "m/5", "m/6", "m/7", "m/8", "m/9",
|
||||
"m/10", "m/11", "m/12", "m/13", "m/14", "m/15", "m/16", "m/17", "m/18", "m/19",
|
||||
"m/20", "m/21", "m/22", "m/23", "m/24", "m/25", "m/26", "m/27", "m/28", "m/29",
|
||||
"m/30", "m/31", "m/32", "m/33", "m/34", "m/35", "m/36", "m/37", "m/38", "m/39",
|
||||
"m/40", "m/41", "m/42", "m/43", "m/44", "m/45", "m/46", "m/47", "m/48", "m/49",
|
||||
"m/50", "m/51", "m/52", "m/53", "m/54", "m/55", "m/56", "m/57", "m/58", "m/59",
|
||||
"m/60", "m/61", "m/62", "m/63", "m/64", "m/65", "m/66", "m/67", "m/68", "m/69",
|
||||
"m/70", "m/71", "m/72", "m/73", "m/74", "m/75", "m/76", "m/77", "m/78", "m/79",
|
||||
"m/80", "m/81", "m/82", "m/83", "m/84", "m/85", "m/86", "m/87", "m/88", "m/89",
|
||||
"m/90", "m/91", "m/92", "m/93", "m/94", "m/95", "m/96", "m/97", "m/98", "m/99",
|
||||
"m/100", "m/101", "m/102", "m/103", "m/104", "m/105", "m/106", "m/107", "m/108", "m/109",
|
||||
"m/110", "m/111", "m/112", "m/113", "m/114", "m/115", "m/116", "m/117", "m/118", "m/119",
|
||||
"m/120", "m/121", "m/122", "m/123", "m/124", "m/125", "m/126", "m/127", "m/128", "m/129",
|
||||
"m/130", "m/131", "m/132", "m/133", "m/134", "m/135", "m/136", "m/137", "m/138", "m/139",
|
||||
"m/140", "m/141", "m/142", "m/143", "m/144", "m/145", "m/146", "m/147", "m/148", "m/149",
|
||||
"m/150", "m/151", "m/152", "m/153", "m/154", "m/155", "m/156", "m/157", "m/158", "m/159",
|
||||
"m/160", "m/161", "m/162", "m/163", "m/164", "m/165", "m/166", "m/167", "m/168", "m/169",
|
||||
"m/170", "m/171", "m/172", "m/173", "m/174", "m/175", "m/176", "m/177", "m/178", "m/179",
|
||||
"m/180", "m/181", "m/182", "m/183", "m/184", "m/185", "m/186", "m/187", "m/188", "m/189",
|
||||
"m/190", "m/191", "m/192", "m/193", "m/194", "m/195", "m/196", "m/197", "m/198", "m/199",
|
||||
"m/200", "m/201", "m/202", "m/203", "m/204", "m/205", "m/206", "m/207", "m/208", "m/209",
|
||||
"m/210", "m/211", "m/212", "m/213", "m/214", "m/215", "m/216", "m/217", "m/218", "m/219",
|
||||
"m/220", "m/221", "m/222", "m/223", "m/224", "m/225", "m/226", "m/227", "m/228", "m/229",
|
||||
"m/230", "m/231", "m/232", "m/233", "m/234", "m/235", "m/236", "m/237", "m/238", "m/239",
|
||||
"m/240", "m/241", "m/242", "m/243", "m/244", "m/245", "m/246", "m/247", "m/248", "m/249",
|
||||
"m/250", "m/251", "m/252", "m/253", "m/254", "m/255"
|
||||
],
|
||||
"expected": null
|
||||
},
|
||||
{
|
||||
"description": "Path with 256 children should fail (exceeds u8::MAX)",
|
||||
"paths": ["m/0/0/0/0/0/0/0/0/0/0/0/0/0/0/0/0/0/0/0/0/0/0/0/0/0/0/0/0/0/0/0/0/0/0/0/0/0/0/0/0/0/0/0/0/0/0/0/0/0/0/0/0/0/0/0/0/0/0/0/0/0/0/0/0/0/0/0/0/0/0/0/0/0/0/0/0/0/0/0/0/0/0/0/0/0/0/0/0/0/0/0/0/0/0/0/0/0/0/0/0/0/0/0/0/0/0/0/0/0/0/0/0/0/0/0/0/0/0/0/0/0/0/0/0/0/0/0/0/0/0/0/0/0/0/0/0/0/0/0/0/0/0/0/0/0/0/0/0/0/0/0/0/0/0/0/0/0/0/0/0/0/0/0/0/0/0/0/0/0/0/0/0/0/0/0/0/0/0/0/0/0/0/0/0/0/0/0/0/0/0/0/0/0/0/0/0/0/0/0/0/0/0/0/0/0/0/0/0/0/0/0/0/0/0/0/0/0/0/0/0/0/0/0/0/0/0/0/0/0/0/0/0/0/0/0/0/0/0/0/0/0/0/0/0/0/0/0/0/0/0/0/0/0/0/0/0"],
|
||||
"expected": null
|
||||
},
|
||||
{
|
||||
"description": "255 paths should succeed (maximum allowed)",
|
||||
"paths": [
|
||||
"m/0", "m/1", "m/2", "m/3", "m/4", "m/5", "m/6", "m/7", "m/8", "m/9",
|
||||
"m/10", "m/11", "m/12", "m/13", "m/14", "m/15", "m/16", "m/17", "m/18", "m/19",
|
||||
"m/20", "m/21", "m/22", "m/23", "m/24", "m/25", "m/26", "m/27", "m/28", "m/29",
|
||||
"m/30", "m/31", "m/32", "m/33", "m/34", "m/35", "m/36", "m/37", "m/38", "m/39",
|
||||
"m/40", "m/41", "m/42", "m/43", "m/44", "m/45", "m/46", "m/47", "m/48", "m/49",
|
||||
"m/50", "m/51", "m/52", "m/53", "m/54", "m/55", "m/56", "m/57", "m/58", "m/59",
|
||||
"m/60", "m/61", "m/62", "m/63", "m/64", "m/65", "m/66", "m/67", "m/68", "m/69",
|
||||
"m/70", "m/71", "m/72", "m/73", "m/74", "m/75", "m/76", "m/77", "m/78", "m/79",
|
||||
"m/80", "m/81", "m/82", "m/83", "m/84", "m/85", "m/86", "m/87", "m/88", "m/89",
|
||||
"m/90", "m/91", "m/92", "m/93", "m/94", "m/95", "m/96", "m/97", "m/98", "m/99",
|
||||
"m/100", "m/101", "m/102", "m/103", "m/104", "m/105", "m/106", "m/107", "m/108", "m/109",
|
||||
"m/110", "m/111", "m/112", "m/113", "m/114", "m/115", "m/116", "m/117", "m/118", "m/119",
|
||||
"m/120", "m/121", "m/122", "m/123", "m/124", "m/125", "m/126", "m/127", "m/128", "m/129",
|
||||
"m/130", "m/131", "m/132", "m/133", "m/134", "m/135", "m/136", "m/137", "m/138", "m/139",
|
||||
"m/140", "m/141", "m/142", "m/143", "m/144", "m/145", "m/146", "m/147", "m/148", "m/149",
|
||||
"m/150", "m/151", "m/152", "m/153", "m/154", "m/155", "m/156", "m/157", "m/158", "m/159",
|
||||
"m/160", "m/161", "m/162", "m/163", "m/164", "m/165", "m/166", "m/167", "m/168", "m/169",
|
||||
"m/170", "m/171", "m/172", "m/173", "m/174", "m/175", "m/176", "m/177", "m/178", "m/179",
|
||||
"m/180", "m/181", "m/182", "m/183", "m/184", "m/185", "m/186", "m/187", "m/188", "m/189",
|
||||
"m/190", "m/191", "m/192", "m/193", "m/194", "m/195", "m/196", "m/197", "m/198", "m/199",
|
||||
"m/200", "m/201", "m/202", "m/203", "m/204", "m/205", "m/206", "m/207", "m/208", "m/209",
|
||||
"m/210", "m/211", "m/212", "m/213", "m/214", "m/215", "m/216", "m/217", "m/218", "m/219",
|
||||
"m/220", "m/221", "m/222", "m/223", "m/224", "m/225", "m/226", "m/227", "m/228", "m/229",
|
||||
"m/230", "m/231", "m/232", "m/233", "m/234", "m/235", "m/236", "m/237", "m/238", "m/239",
|
||||
"m/240", "m/241", "m/242", "m/243", "m/244", "m/245", "m/246", "m/247", "m/248", "m/249",
|
||||
"m/250", "m/251", "m/252", "m/253", "m/254"
|
||||
],
|
||||
"expected": "ff0100000000010000000101000000020100000003010000000401000000050100000006010000000701000000080100000009010000000a010000000b010000000c010000000d010000000e010000000f0100000010010000001101000000120100000013010000001401000000150100000016010000001701000000180100000019010000001a010000001b010000001c010000001d010000001e010000001f0100000020010000002101000000220100000023010000002401000000250100000026010000002701000000280100000029010000002a010000002b010000002c010000002d010000002e010000002f0100000030010000003101000000320100000033010000003401000000350100000036010000003701000000380100000039010000003a010000003b010000003c010000003d010000003e010000003f0100000040010000004101000000420100000043010000004401000000450100000046010000004701000000480100000049010000004a010000004b010000004c010000004d010000004e010000004f0100000050010000005101000000520100000053010000005401000000550100000056010000005701000000580100000059010000005a010000005b010000005c010000005d010000005e010000005f0100000060010000006101000000620100000063010000006401000000650100000066010000006701000000680100000069010000006a010000006b010000006c010000006d010000006e010000006f0100000070010000007101000000720100000073010000007401000000750100000076010000007701000000780100000079010000007a010000007b010000007c010000007d010000007e010000007f0100000080010000008101000000820100000083010000008401000000850100000086010000008701000000880100000089010000008a010000008b010000008c010000008d010000008e010000008f0100000090010000009101000000920100000093010000009401000000950100000096010000009701000000980100000099010000009a010000009b010000009c010000009d010000009e010000009f01000000a001000000a101000000a201000000a301000000a401000000a501000000a601000000a701000000a801000000a901000000aa01000000ab01000000ac01000000ad01000000ae01000000af01000000b001000000b101000000b201000000b301000000b401000000b501000000b601000000b701000000b801000000b901000000ba01000000bb01000000bc01000000bd01000000be01000000bf01000000c001000000c101000000c201000000c301000000c401000000c501000000c601000000c701000000c801000000c901000000ca01000000cb01000000cc01000000cd01000000ce01000000cf01000000d001000000d101000000d201000000d301000000d401000000d501000000d601000000d701000000d801000000d901000000da01000000db01000000dc01000000dd01000000de01000000df01000000e001000000e101000000e201000000e301000000e401000000e501000000e601000000e701000000e801000000e901000000ea01000000eb01000000ec01000000ed01000000ee01000000ef01000000f001000000f101000000f201000000f301000000f401000000f501000000f601000000f701000000f801000000f901000000fa01000000fb01000000fc01000000fd01000000fe"
|
||||
}
|
||||
]
|
||||
157
bip-0138/test_vectors/encrypted_backup.json
Normal file
157
bip-0138/test_vectors/encrypted_backup.json
Normal file
@@ -0,0 +1,157 @@
|
||||
[
|
||||
{
|
||||
"description": "Single key, no derivation paths, BIP380 content",
|
||||
"version": 1,
|
||||
"encryption": 1,
|
||||
"content": "01017c",
|
||||
"keys": [
|
||||
"02e6642fd69bd211f93f7f1f36ca51a26a5290eb2dd1b0d8279a87bb0d480c8443"
|
||||
],
|
||||
"decoy_individual_secrets": [
|
||||
"0000000000000000000000000000000000000000000000000000000000000001",
|
||||
"c000000000000000000000000000000000000000000000000000000000000000",
|
||||
"c200000000000000000000000000000000000000000000000000000000000000",
|
||||
"ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff"
|
||||
],
|
||||
"derivation_paths": [],
|
||||
"plaintext": "00",
|
||||
"nonce": "a1b2c3d4e5f607080910a1b2",
|
||||
"expected": "4249503133380100050000000000000000000000000000000000000000000000000000000000000001c000000000000000000000000000000000000000000000000000000000000000c14d5bfeb7f9709e996c6696959107d4c57d367d2aee207d5361f116e3c4708bc200000000000000000000000000000000000000000000000000000000000000ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff01a1b2c3d4e5f607080910a1b216a42cdae8b34bb573f5cd678ef6a25c29a214abbf52de",
|
||||
"trailing": "deadbeef00ff",
|
||||
"expected_base64": "QklQMTM4AQAFAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAHAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAMFNW/63+XCemWxmlpWRB9TFfTZ9Ku4gfVNh8RbjxHCLwgAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAD//////////////////////////////////////////wGhssPU5fYHCAkQobIWpCza6LNLtXP1zWeO9qJcKaIUq79S3g=="
|
||||
},
|
||||
{
|
||||
"description": "Two keys, 1 derivation paths, BIP380 content",
|
||||
"version": 1,
|
||||
"encryption": 1,
|
||||
"content": "01017c",
|
||||
"keys": [
|
||||
"02e6642fd69bd211f93f7f1f36ca51a26a5290eb2dd1b0d8279a87bb0d480c8443",
|
||||
"0384526253c27c7aef56c7b71a5cd25bebb66dddda437826defc5b2568bde81f07"
|
||||
],
|
||||
"decoy_individual_secrets": [
|
||||
"0000000000000000000000000000000000000000000000000000000000000001",
|
||||
"c000000000000000000000000000000000000000000000000000000000000000",
|
||||
"ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff"
|
||||
],
|
||||
"derivation_paths": [
|
||||
"m/48'/1'/0'/2'"
|
||||
],
|
||||
"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": "0102030405060708090a0b0c",
|
||||
"expected": "4249503133380100050000000000000000000000000000000000000000000000000000000000000001b8c6ce74f81b0ffe7d7511824e75f95114f9b140e57bb570e5c5d807f0a5e96fb8e749fceb0dd84d20a75af4dbd6d585d89c54053f6313ac6592cbfe8c1bdd4fc000000000000000000000000000000000000000000000000000000000000000ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff010102030405060708090a0b0cfd6601829ae3ce2f35059533a55d10fead962d645b08a53a6fad9da13e2aa270d4561f36602d92ba9af12ef4bb495fb8296a7f7ec1ddabef1d1b25cd7e93b8dc9d437dfcd282d24ab22aaa29292ceb463cb7560321cdcae6e537fafcbedbf59e75ccb15f3a930e132037b54d8bb9b675f5f979ed8c1e084b8d9e0216519bd8ab22825ab40868133ff0ec76b623d9341c51f96cbc97e61c753e4c12e5841b640fba3fc09864ac1b67f690447c6db5e960f2ca507cad5bfae71b2fef38cc0b68c34d7f956ca0cc59d54c2d53ff5a678b4e09ce5408f6ca723040ab42e889e77c6be3771fb38a0df881128466deaa8a84e3b7cbd0ddf4a000b03d63a8e2cf5f73310e1066d3b392dc45ad30bd664490641a6bd78d4008d44193b9ea3d9285029eaa309e80afff383dda3cff1df4df4b75a254eaaf8e0f0af86e90f40b78c9d98bd354eb6eb512b6b95d05d5f95c0ca56042cea52f76252d7f2e8a95ddc4e8bffe631b399a9d69ef80d56c",
|
||||
"expected_base64": "QklQMTM4AQAFAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAG4xs50+BsP/n11EYJOdflRFPmxQOV7tXDlxdgH8KXpb7jnSfzrDdhNIKda9NvW1YXYnFQFP2MTrGWSy/6MG91PwAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAD//////////////////////////////////////////wEBAgMEBQYHCAkKCwz9ZgGCmuPOLzUFlTOlXRD+rZYtZFsIpTpvrZ2hPiqicNRWHzZgLZK6mvEu9LtJX7gpan9+wd2r7x0bJc1+k7jcnUN9/NKC0kqyKqopKSzrRjy3VgMhzcrm5Tf6/L7b9Z51zLFfOpMOEyA3tU2LubZ19fl57YweCEuNngIWUZvYqyKCWrQIaBM/8Ox2tiPZNBxR+Wy8l+YcdT5MEuWEG2QPuj/AmGSsG2f2kER8bbXpYPLKUHytW/rnGy/vOMwLaMNNf5VsoMxZ1UwtU/9aZ4tOCc5UCPbKcjBAq0Loied8a+N3H7OKDfiBEoRm3qqKhOO3y9Dd9KAAsD1jqOLPX3MxDhBm07OS3EWtML1mRJBkGmvXjUAI1EGTueo9koUCnqownoCv/zg92jz/HfTfS3WiVOqvjg8K+G6Q9At4ydmL01TrbrUStrldBdX5XAylYELOpS92JS1/LoqV3cTov/5jGzmanWnvgNVs"
|
||||
},
|
||||
{
|
||||
"description": "Three keys, multiple derivation paths, BIP329 content",
|
||||
"version": 1,
|
||||
"encryption": 1,
|
||||
"content": "010149",
|
||||
"keys": [
|
||||
"02e6642fd69bd211f93f7f1f36ca51a26a5290eb2dd1b0d8279a87bb0d480c8443",
|
||||
"0384526253c27c7aef56c7b71a5cd25bebb66dddda437826defc5b2568bde81f07",
|
||||
"03c6047f9441ed7d6d3045406e95c07cd85c778e4b8cef3ca7abac09b95c709ee5"
|
||||
],
|
||||
"decoy_individual_secrets": [
|
||||
"7000000000000000000000000000000000000000000000000000000000000000",
|
||||
"8000000000000000000000000000000000000000000000000000000000000000"
|
||||
],
|
||||
"derivation_paths": [
|
||||
"m/84'/0'/0'",
|
||||
"m/0/1'/2/3'"
|
||||
],
|
||||
"plaintext": "{\"type\":\"tx\",\"ref\":\"f91d0a8a78462bc59398f2c5d7a84fcff491c26ba54c4833478b202796c8aafd\",\"label\":\"Transaction\",\"origin\":\"wpkh([d34db33f/84'/0'/0'])\"}\n{\"type\":\"addr\",\"ref\":\"bc1q34aq5drpuwy3wgl9lhup9892qp6svr8ldzyy7c\",\"label\":\"Address\"}\n{\"type\":\"pubkey\",\"ref\":\"0283409659355b6d1cc3c32decd5d561abaac86c37a353b52895a5e6c196d6f448\",\"label\":\"Public Key\"}\n{\"type\":\"input\",\"ref\":\"f91d0a8a78462bc59398f2c5d7a84fcff491c26ba54c4833478b202796c8aafd:0\",\"label\":\"Input\"}\n{\"type\":\"output\",\"ref\":\"f91d0a8a78462bc59398f2c5d7a84fcff491c26ba54c4833478b202796c8aafd:1\",\"label\":\"Output\",\"spendable\":false}\n{\"type\":\"xpub\",\"ref\":\"xpub661MyMwAqRbcFtXgS5sYJABqqG9YLmC4Q1Rdap9gSE8NqtwybGhePY2gZ29ESFjqJoCu1Rupje8YtGqsefD265TMg7usUDFdp6W1EGMcet8\",\"label\":\"Extended Public Key\"}\n{\"type\":\"tx\",\"ref\":\"f546156d9044844e02b181026a1a407abfca62e7ea1159f87bbeaa77b4286c74\",\"label\":\"Account #1 Transaction\",\"origin\":\"wpkh([d34db33f/84'/0'/1'])\"}",
|
||||
"nonce": "deadbeefcafebabe12345678",
|
||||
"expected": "4249503133380101040000000080000001000000028000000305281aff33e4b8186ac4176427b59ec3c72af96bf6ecd1ad7ed1d746103d078a17283b78bbf7aecfd999c52f51203def13e69c8eb336c90ba2518055e941b9be3770000000000000000000000000000000000000000000000000000000000000008000000000000000000000000000000000000000000000000000000000000000f6353d50c714c43f7b86794ee21e3490af33468ef30217dd93003413e23b4c1701deadbeefcafebabe12345678fd9f032b5e117a385bfc3c88c2eae4e2e4aeeaaff5c5ced44579c77cb67fbb6c12bdc113c1e2c9bb1029ec47f589311030efe4aa3924958aa53b737d5fdf0fc2272037ba9260303a07010ceaf38e40aec5d28318968e833511bdc6d4ab99cb1e51153f0571fd6c0e08b58a8b75bdb91c7fb94b16872ac5800c981f06d3c28fdf71a9382c08c74d2d0ffe9e20774e6c8bec95cd6713ec60ff2fa54d50a507e84448d91ba5fcaa8dd17ad19dbb962e4514a127d795d8cf82ced19d242a9777a9bd6f714c3deec247530f74c055410e6b42ae98de71259103cf14f0d5719ae2900675841c010c1e6c076a9be2ddf271e3281184dc8759063a4c1be8f2e3a57e6557b76228bf13e5d1cf6fc8726d6429cad74c84fbb15046abb12fe7f6f6e3856016dae37fff0a161cb9da34e814976ccc9b03a587900eb36cbd56049cdc9680816fe9c4a14838fa2a999bf4ad7fe5efa7d31c7164886d6eafa18fe40185bcc982768d0a3ca05e3450979e4140cacd834f8e6399048b59e6ab025964c2afcf6119b614c56755e5e37b6425ea3926dd9b9fe4cd6e127d6006abdb38b393437cb26cd8ccbda13825c90b857deab2dbaf759b14ffb0692e448ecbba9a3cdbac7b7661be2a8cec5a0b9df3bbe1a67014653e159c41c3b36974563b8392731f3dec68c16e4a644bad4236208876aba0d00bdd3cefac04c31b1e1673b91d0010f8ebe7070c07f8b00effa79b8e94fb1b9285904114e37d4e2987d9246a300958a9fbf1c2af1016edcec7b9e0fca80935652c3426e837a9ce018615d1f1127da307daca4dc8bc201f44b09c0adb52859f49cc625a5ecd31bbe513ea5c97dfb8f192cffd60864acc4c1a0a4f630190cbf1e1fe8201d8b7b2b4da7e8813f56e1d885f57700289ee4661928540607be79221137c1a79b8b4ab6150f1c9c4c6ca2367a673d5f7faa2cbcdbc1fd68c45acb33e7344e55a431c03ad03fb4442bd01b8b51cce71c7779fa2f63120bed1ed30ff35969cc2cb049b598a473b670012bd155e6efcad815a83cd76ea06eef14867cef22998bf39debadd78fface8cb6cb9ee3f02636683d69458f6ace058f232ef1d1d547c0073a82ba507a006df40f69d2a247b485ee6010cfbb58bbc6f0423287f475df21c2e23533a1653c48aac55b7a64e489850477482a08924c984700d5be68834455c17b8cae220f898679515735273d4d8e8a0c62735e859d7a7158db7f8e8d1d94e94dd9750c1bd8b5a89a8f67a1ba146201a3999b00350ae1467de39d984b56d4d62ec04bdf0cf05a241468b6a0b70e8ccbbe476ee",
|
||||
"expected_base64": "QklQMTM4AQEEAAAAAIAAAAEAAAACgAAAAwUoGv8z5LgYasQXZCe1nsPHKvlr9uzRrX7R10YQPQeKFyg7eLv3rs/ZmcUvUSA97xPmnI6zNskLolGAVelBub43cAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAACAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAPY1PVDHFMQ/e4Z5TuIeNJCvM0aO8wIX3ZMANBPiO0wXAd6tvu/K/rq+EjRWeP2fAyteEXo4W/w8iMLq5OLkruqv9cXO1EV5x3y2f7tsEr3BE8HiybsQKexH9YkxEDDv5Ko5JJWKpTtzfV/fD8InIDe6kmAwOgcBDOrzjkCuxdKDGJaOgzURvcbUq5nLHlEVPwVx/WwOCLWKi3W9uRx/uUsWhyrFgAyYHwbTwo/fcak4LAjHTS0P/p4gd05si+yVzWcT7GD/L6VNUKUH6ERI2Rul/KqN0XrRnbuWLkUUoSfXldjPgs7RnSQql3epvW9xTD3uwkdTD3TAVUEOa0KumN5xJZEDzxTw1XGa4pAGdYQcAQwebAdqm+Ld8nHjKBGE3IdZBjpMG+jy46V+ZVe3Yii/E+XRz2/Icm1kKcrXTIT7sVBGq7Ev5/b244VgFtrjf/8KFhy52jToFJdszJsDpYeQDrNsvVYEnNyWgIFv6cShSDj6Kpmb9K1/5e+n0xxxZIhtbq+hj+QBhbzJgnaNCjygXjRQl55BQMrNg0+OY5kEi1nmqwJZZMKvz2EZthTFZ1Xl43tkJeo5Jt2bn+TNbhJ9YAar2zizk0N8smzYzL2hOCXJC4V96rLbr3WbFP+waS5Ejsu6mjzbrHt2Yb4qjOxaC53zu+GmcBRlPhWcQcOzaXRWO4OScx897GjBbkpkS61CNiCIdqug0AvdPO+sBMMbHhZzuR0AEPjr5wcMB/iwDv+nm46U+xuShZBBFON9TimH2SRqMAlYqfvxwq8QFu3Ox7ng/KgJNWUsNCboN6nOAYYV0fESfaMH2spNyLwgH0SwnArbUoWfScxiWl7NMbvlE+pcl9+48ZLP/WCGSsxMGgpPYwGQy/Hh/oIB2LeytNp+iBP1bh2IX1dwAonuRmGShUBge+eSIRN8Gnm4tKthUPHJxMbKI2emc9X3+qLLzbwf1oxFrLM+c0TlWkMcA60D+0RCvQG4tRzOccd3n6L2MSC+0e0w/zWWnMLLBJtZikc7ZwASvRVebvytgVqDzXbqBu7xSGfO8imYvzneut14/6zoy2y57j8CY2aD1pRY9qzgWPIy7x0dVHwAc6grpQegBt9A9p0qJHtIXuYBDPu1i7xvBCMof0dd8hwuI1M6FlPEiqxVt6ZOSJhQR3SCoIkkyYRwDVvmiDRFXBe4yuIg+JhnlRVzUnPU2Oigxic16FnXpxWNt/jo0dlOlN2XUMG9i1qJqPZ6G6FGIBo5mbADUK4UZ9452YS1bU1i7AS98M8FokFGi2oLcOjMu+R27g=="
|
||||
},
|
||||
{
|
||||
"description": "Single key, proprietary content (3 bytes)",
|
||||
"version": 1,
|
||||
"encryption": 1,
|
||||
"content": "0204deadbeef",
|
||||
"keys": [
|
||||
"02e6642fd69bd211f93f7f1f36ca51a26a5290eb2dd1b0d8279a87bb0d480c8443"
|
||||
],
|
||||
"decoy_individual_secrets": [
|
||||
"0000000000000000000000000000000000000000000000000000000000000001",
|
||||
"c000000000000000000000000000000000000000000000000000000000000000",
|
||||
"c200000000000000000000000000000000000000000000000000000000000000",
|
||||
"ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff"
|
||||
],
|
||||
"derivation_paths": [],
|
||||
"plaintext": "706c61696e74657874",
|
||||
"nonce": "000102030405060708090a0b",
|
||||
"expected": "4249503133380100050000000000000000000000000000000000000000000000000000000000000001c000000000000000000000000000000000000000000000000000000000000000c14d5bfeb7f9709e996c6696959107d4c57d367d2aee207d5361f116e3c4708bc200000000000000000000000000000000000000000000000000000000000000ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff01000102030405060708090a0b2988e0747028c10af011cba311ebabb3a094366a96ad747cd8e3edfc1474b356c2393e13ee9c5cd0aae5",
|
||||
"expected_base64": "QklQMTM4AQAFAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAHAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAMFNW/63+XCemWxmlpWRB9TFfTZ9Ku4gfVNh8RbjxHCLwgAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAD//////////////////////////////////////////wEAAQIDBAUGBwgJCgspiOB0cCjBCvARy6MR66uzoJQ2apatdHzY4+38FHSzVsI5PhPunFzQquU="
|
||||
},
|
||||
{
|
||||
"description": "Two keys, BIP388 wallet policy content (multisig)",
|
||||
"version": 1,
|
||||
"encryption": 1,
|
||||
"content": "010184",
|
||||
"keys": [
|
||||
"02ee3887104834ec2970bb793abc7fd37661e2c44c49fb48c10745ef7d7c85b17c",
|
||||
"036f155ae2153b09bb4e1383756723c0879e80d0f32767c7e4875d5de2fb9a400d"
|
||||
],
|
||||
"decoy_individual_secrets": [
|
||||
"0000000000000000000000000000000000000000000000000000000000000001",
|
||||
"8000000000000000000000000000000000000000000000000000000000000000",
|
||||
"ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff"
|
||||
],
|
||||
"derivation_paths": [
|
||||
"m/48'/0'/0'/2'"
|
||||
],
|
||||
"plaintext": "{\"keys\":[\"[6738736c/48'/0'/0'/2']xpub6FC1fXFP1GXLX5TKtcjHGT4q89SDRehkQLtbKJ2PzWcvbBHtyDsJPLtpLtkGqYNYZdVVAjRQ5kug9CsapegmmeRutpP7PW4u4wVF9JfkDhw\",\"[b2b1f0cf/48'/0'/0'/2']xpub6EWhjpPa6FqrcaPBuGBZRJVjzGJ1ZsMygRF26RwN932Vfkn1gyCiTbECVitBjRCkexEvetLdiqzTcYimmzYxyR1BZ79KNevgt61PDcukmC7\"],\"policy\":\"wsh(sortedmulti(2,@0/**,@1/**))\"}",
|
||||
"nonce": "000000000000000000000388",
|
||||
"expected": "424950313338010005000000000000000000000000000000000000000000000000000000000000000163f5769bbb36d77fc5d3251700590c087013ca44284850e88f379f2519190f978000000000000000000000000000000000000000000000000000000000000000e5b4cabf8bdb9a04a92fc3e104dd2d8a2cb8e5ea886e143236dd4b04619e796dffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff01000000000000000000000388fd5d011def7dae872431f1fa0df78989f7e5087cd0cb112a69bc211d3346b1031c5d1e8702197712ac46597e05d80421fda7e60d09f3ba2178bd770c904bf840d3d779565fbd0668a989934483820c4c828f32ffe5fc1ce55bbfe287a6d4eb4461e4da1b6a6f22cc0932773c84f07d879b1ed8035831e2a358101be023ea2efb7c70411f757c42715f4e5f7eff416a456a5dadf1b980480e22a7b66726ebc84afe04acdfbf47c6b41c2bb39c5a069a93dba0de4ea9bc192f938f968c9fa2afc26025dd577461b73bad0870e97d7519945ced9d73500c7ece85696d98f223350cd6a337cb74feeeea8d5144ee94553dc54a46e43f67fa48f11c7746e006aac4478fa0c484f041be451548152a1f11f632a9d966de62e3cd80ed9885117e5901042974c80d3f95a13c1cfe2157f2bfb80bea7b3bc0a71127d8daa6a75d3cc517ef934dd9af4b504600c5ce223ba9538c9bc0472aa3832571b1486e2f51b40a5351",
|
||||
"expected_base64": "QklQMTM4AQAFAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAFj9XabuzbXf8XTJRcAWQwIcBPKRChIUOiPN58lGRkPl4AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA5bTKv4vbmgSpL8PhBN0tiiy45eqIbhQyNt1LBGGeeW3//////////////////////////////////////////wEAAAAAAAAAAAAAA4j9XQEd732uhyQx8foN94mJ9+UIfNDLESppvCEdM0axAxxdHocCGXcSrEZZfgXYBCH9p+YNCfO6IXi9dwyQS/hA09d5Vl+9BmipiZNEg4IMTIKPMv/l/BzlW7/ih6bU60Rh5Nobam8izAkydzyE8H2Hmx7YA1gx4qNYEBvgI+ou+3xwQR91fEJxX05ffv9BakVqXa3xuYBIDiKntmcm68hK/gSs379HxrQcK7OcWgaak9ug3k6pvBkvk4+WjJ+ir8JgJd1XdGG3O60IcOl9dRmUXO2dc1AMfs6FaW2Y8iM1DNajN8t0/u7qjVFE7pRVPcVKRuQ/Z/pI8Rx3RuAGqsRHj6DEhPBBvkUVSBUqHxH2MqnZZt5i482A7ZiFEX5ZAQQpdMgNP5WhPBz+IVfyv7gL6ns7wKcRJ9japqddPMUX75NN2a9LUEYAxc4iO6lTjJvARyqjgyVxsUhuL1G0ClNR"
|
||||
},
|
||||
{
|
||||
"description": "Two content items in one payload (BIP380 descriptor + BIP329 labels)",
|
||||
"version": 1,
|
||||
"encryption": 1,
|
||||
"content": "01017c",
|
||||
"keys": [
|
||||
"02e6642fd69bd211f93f7f1f36ca51a26a5290eb2dd1b0d8279a87bb0d480c8443",
|
||||
"0384526253c27c7aef56c7b71a5cd25bebb66dddda437826defc5b2568bde81f07"
|
||||
],
|
||||
"decoy_individual_secrets": [
|
||||
"0000000000000000000000000000000000000000000000000000000000000001",
|
||||
"c000000000000000000000000000000000000000000000000000000000000000",
|
||||
"ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff"
|
||||
],
|
||||
"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": "4249503133380100050000000000000000000000000000000000000000000000000000000000000001b8c6ce74f81b0ffe7d7511824e75f95114f9b140e57bb570e5c5d807f0a5e96fb8e749fceb0dd84d20a75af4dbd6d585d89c54053f6313ac6592cbfe8c1bdd4fc000000000000000000000000000000000000000000000000000000000000000ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff010c0d0e0f101112131415161afde201d35ed73109113688c5cc808c44e3e4a6837adf0ee8c9339947e176418c41f16e92c36b395a07e036117df93fda41bf3b1bacae6cb0fe1cf2c07f519fff3a96b95540de161c48cd8ee6485a1b5477c18d038257af7bacedc36ef0cea2f0661c2267b0d72cf8273f32d734046eb8fbfe75a47619a7d5c12b95e9ec6a49b0a031ccdbfaa6bd201ddf94cb3979ceae1390af41baaedeba38dfcf078c97c33404f0833d36a750e1ebac14d2139719c35aacfa025cde5a19f776d8e1d1367764700f8e8bc3ae99d08fbffaa322abe1e69f2839f8840cdffbcfed9544e4fde1dac882bee1e0d34367f63fc5eec38540f0b3683cd79dbe67eab0ddd52765edf6de7f24adb3e9df8e7b9bf793863f60dfa6fd39aed67eac5d4f774069af6ff436bd85affb199846c55e7d2063d950182b60886f8d65c890d0a4ff6253a8ed0963a052c46ed858dcdefe3e929d970e97d7b65b9843caf94a5649bd8547f5a976cc40b7356dfb6cf3df6b87267ca83d15a2d11cd8e918f2a2b17bb717b33f55a78fd5a6a01cd11d39b54af2734066be57977fb140db2944bf612ce63fa2dc7ae841f47f930637eaaacc96bf5a9cf82483f0aba57dafb79319631a3b954c0a05731607c29290b5c9487def5371585671f4ae6ab0e8cdb51423faf15de6ca34430d21581de9cfe36e",
|
||||
"extra": [
|
||||
{
|
||||
"content": "010149",
|
||||
"plaintext": "{\"type\": \"tx\", \"ref\": \"f4184fc596403b9d638783cf57adfe4c75c605f6356fbc91338530e9831e9e16\", \"label\": \"multi content demo\"}"
|
||||
}
|
||||
],
|
||||
"expected_base64": "QklQMTM4AQAFAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAG4xs50+BsP/n11EYJOdflRFPmxQOV7tXDlxdgH8KXpb7jnSfzrDdhNIKda9NvW1YXYnFQFP2MTrGWSy/6MG91PwAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAD//////////////////////////////////////////wEMDQ4PEBESExQVFhr94gHTXtcxCRE2iMXMgIxE4+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"
|
||||
],
|
||||
"decoy_individual_secrets": [
|
||||
"0000000000000000000000000000000000000000000000000000000000000001",
|
||||
"c000000000000000000000000000000000000000000000000000000000000000",
|
||||
"ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff"
|
||||
],
|
||||
"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": "4249503133380100050000000000000000000000000000000000000000000000000000000000000001b8c6ce74f81b0ffe7d7511824e75f95114f9b140e57bb570e5c5d807f0a5e96fb8e749fceb0dd84d20a75af4dbd6d585d89c54053f6313ac6592cbfe8c1bdd4fc000000000000000000000000000000000000000000000000000000000000000ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff01000000000000000000000000fd66010d8538e52c03d7069660ca0fc3e961eb7d2ae284498ba1358b7476c09d44bfa60e1963f0271eaf66e816348f001fa4ee1d0fd11e24e93ed12ee288371ce6ca8629b70692e36a43d7647cb340f8f22c6ef4aeb8968f16920ddd2f11f450f7d2420f210f55204d4c40eb8306c02ec8e30c2fd13a15ba0999ad4831a9be7754eab3ddf4f5e71301b89a881a279cf262556708697b8e3da7236872270d3f8d62b6d56e4065835df66277f30177566c233764417eb7d2de6cf5f293321d80c6328c261d0f2d06c9fbd6fd29cd059e0db61d6e1b60951605f40f93c239b643da049186fcc5811bd116808d8bdd8beaefc0d4124088dcd00261c396eb3f27ed254ff91c4457a1c817c53004ea0e764309149044d4e8f92d2ee688619fc44a67a096bdd6c978411d6c103b634896e080cb3dba6f66f0fe580cdb9f944457c65312f449d82c2b1bc86ac972df641ae93ff2d1ea2d9ae64abdce2dd452bf2fc37a5f493dd1704f91a2c765",
|
||||
"valid": false,
|
||||
"expected_base64": "QklQMTM4AQAFAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAG4xs50+BsP/n11EYJOdflRFPmxQOV7tXDlxdgH8KXpb7jnSfzrDdhNIKda9NvW1YXYnFQFP2MTrGWSy/6MG91PwAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAD//////////////////////////////////////////wEAAAAAAAAAAAAAAAD9ZgENhTjlLAPXBpZgyg/D6WHrfSrihEmLoTWLdHbAnUS/pg4ZY/AnHq9m6BY0jwAfpO4dD9EeJOk+0S7iiDcc5sqGKbcGkuNqQ9dkfLNA+PIsbvSuuJaPFpIN3S8R9FD30kIPIQ9VIE1MQOuDBsAuyOMML9E6FboJma1IMam+d1Tqs9309ecTAbiaiBonnPJiVWcIaXuOPacjaHInDT+NYrbVbkBlg132YnfzAXdWbCM3ZEF+t9LebPXykzIdgMYyjCYdDy0GyfvW/SnNBZ4Nth1uG2CVFgX0D5PCObZD2gSRhvzFgRvRFoCNi92L6u/A1BJAiNzQAmHDlus/J+0lT/kcRFehyBfFMATqDnZDCRSQRNTo+S0u5ohhn8RKZ6CWvdbJeEEdbBA7Y0iW4IDLPbpvZvD+WAzbn5REV8ZTEvRJ2CwrG8hqyXLfZBrpP/LR6i2a5kq9zi3UUr8vw3pfST3RcE+Rosdl"
|
||||
}
|
||||
]
|
||||
100
bip-0138/test_vectors/encryption_secret.json
Normal file
100
bip-0138/test_vectors/encryption_secret.json
Normal file
@@ -0,0 +1,100 @@
|
||||
[
|
||||
{
|
||||
"description": "Single public key",
|
||||
"keys": [
|
||||
"02e6642fd69bd211f93f7f1f36ca51a26a5290eb2dd1b0d8279a87bb0d480c8443"
|
||||
],
|
||||
"decryption_secret": "9628546fe8fbf82fb10ff692d82953fa2db546275be9ce1b00134aff1a8bacdd",
|
||||
"individual_secrets": [
|
||||
"c14d5bfeb7f9709e996c6696959107d4c57d367d2aee207d5361f116e3c4708b"
|
||||
]
|
||||
},
|
||||
{
|
||||
"description": "Two public keys",
|
||||
"keys": [
|
||||
"02e6642fd69bd211f93f7f1f36ca51a26a5290eb2dd1b0d8279a87bb0d480c8443",
|
||||
"0384526253c27c7aef56c7b71a5cd25bebb66dddda437826defc5b2568bde81f07"
|
||||
],
|
||||
"decryption_secret": "efa3c1e5a719874f5516818603cdad7ffc31c11a947c5b16b6b763ee09ea3539",
|
||||
"individual_secrets": [
|
||||
"b8e749fceb0dd84d20a75af4dbd6d585d89c54053f6313ac6592cbfe8c1bdd4f",
|
||||
"b8c6ce74f81b0ffe7d7511824e75f95114f9b140e57bb570e5c5d807f0a5e96f"
|
||||
]
|
||||
},
|
||||
{
|
||||
"description": "Three public keys",
|
||||
"keys": [
|
||||
"02e6642fd69bd211f93f7f1f36ca51a26a5290eb2dd1b0d8279a87bb0d480c8443",
|
||||
"0384526253c27c7aef56c7b71a5cd25bebb66dddda437826defc5b2568bde81f07",
|
||||
"03c6047f9441ed7d6d3045406e95c07cd85c778e4b8cef3ca7abac09b95c709ee5"
|
||||
],
|
||||
"decryption_secret": "7f7ff0a2bbba90dbec74f423f82697e9c2311bac9dd6431882a5fdf9c4485641",
|
||||
"individual_secrets": [
|
||||
"283b78bbf7aecfd999c52f51203def13e69c8eb336c90ba2518055e941b9be37",
|
||||
"f6353d50c714c43f7b86794ee21e3490af33468ef30217dd93003413e23b4c17",
|
||||
"281aff33e4b8186ac4176427b59ec3c72af96bf6ecd1ad7ed1d746103d078a17"
|
||||
]
|
||||
},
|
||||
{
|
||||
"description": "Three public keys bis (different sorting)",
|
||||
"keys": [
|
||||
"03c6047f9441ed7d6d3045406e95c07cd85c778e4b8cef3ca7abac09b95c709ee5",
|
||||
"02e6642fd69bd211f93f7f1f36ca51a26a5290eb2dd1b0d8279a87bb0d480c8443",
|
||||
"0384526253c27c7aef56c7b71a5cd25bebb66dddda437826defc5b2568bde81f07"
|
||||
],
|
||||
"decryption_secret": "7f7ff0a2bbba90dbec74f423f82697e9c2311bac9dd6431882a5fdf9c4485641",
|
||||
"individual_secrets": [
|
||||
"283b78bbf7aecfd999c52f51203def13e69c8eb336c90ba2518055e941b9be37",
|
||||
"f6353d50c714c43f7b86794ee21e3490af33468ef30217dd93003413e23b4c17",
|
||||
"281aff33e4b8186ac4176427b59ec3c72af96bf6ecd1ad7ed1d746103d078a17"
|
||||
]
|
||||
},
|
||||
{
|
||||
"description": "Three public keys ter (different sorting)",
|
||||
"keys": [
|
||||
"0384526253c27c7aef56c7b71a5cd25bebb66dddda437826defc5b2568bde81f07",
|
||||
"03c6047f9441ed7d6d3045406e95c07cd85c778e4b8cef3ca7abac09b95c709ee5",
|
||||
"02e6642fd69bd211f93f7f1f36ca51a26a5290eb2dd1b0d8279a87bb0d480c8443"
|
||||
],
|
||||
"decryption_secret": "7f7ff0a2bbba90dbec74f423f82697e9c2311bac9dd6431882a5fdf9c4485641",
|
||||
"individual_secrets": [
|
||||
"283b78bbf7aecfd999c52f51203def13e69c8eb336c90ba2518055e941b9be37",
|
||||
"f6353d50c714c43f7b86794ee21e3490af33468ef30217dd93003413e23b4c17",
|
||||
"281aff33e4b8186ac4176427b59ec3c72af96bf6ecd1ad7ed1d746103d078a17"
|
||||
]
|
||||
},
|
||||
{
|
||||
"description": "Keys processed in sorted order",
|
||||
"keys": [
|
||||
"0384526253c27c7aef56c7b71a5cd25bebb66dddda437826defc5b2568bde81f07",
|
||||
"02e6642fd69bd211f93f7f1f36ca51a26a5290eb2dd1b0d8279a87bb0d480c8443"
|
||||
],
|
||||
"decryption_secret": "efa3c1e5a719874f5516818603cdad7ffc31c11a947c5b16b6b763ee09ea3539",
|
||||
"individual_secrets": [
|
||||
"b8e749fceb0dd84d20a75af4dbd6d585d89c54053f6313ac6592cbfe8c1bdd4f",
|
||||
"b8c6ce74f81b0ffe7d7511824e75f95114f9b140e57bb570e5c5d807f0a5e96f"
|
||||
]
|
||||
},
|
||||
{
|
||||
"description": "Duplicate keys should be handled",
|
||||
"keys": [
|
||||
"02e6642fd69bd211f93f7f1f36ca51a26a5290eb2dd1b0d8279a87bb0d480c8443",
|
||||
"02e6642fd69bd211f93f7f1f36ca51a26a5290eb2dd1b0d8279a87bb0d480c8443"
|
||||
],
|
||||
"decryption_secret": "9628546fe8fbf82fb10ff692d82953fa2db546275be9ce1b00134aff1a8bacdd",
|
||||
"individual_secrets": [
|
||||
"c14d5bfeb7f9709e996c6696959107d4c57d367d2aee207d5361f116e3c4708b"
|
||||
]
|
||||
},
|
||||
{
|
||||
"description": "Keys sharing an x coordinate normalize to a single key",
|
||||
"keys": [
|
||||
"02e6642fd69bd211f93f7f1f36ca51a26a5290eb2dd1b0d8279a87bb0d480c8443",
|
||||
"03e6642fd69bd211f93f7f1f36ca51a26a5290eb2dd1b0d8279a87bb0d480c8443"
|
||||
],
|
||||
"decryption_secret": "9628546fe8fbf82fb10ff692d82953fa2db546275be9ce1b00134aff1a8bacdd",
|
||||
"individual_secrets": [
|
||||
"c14d5bfeb7f9709e996c6696959107d4c57d367d2aee207d5361f116e3c4708b"
|
||||
]
|
||||
}
|
||||
]
|
||||
571
bip-0138/test_vectors/individual_secrets.json
Normal file
571
bip-0138/test_vectors/individual_secrets.json
Normal file
File diff suppressed because one or more lines are too long
47
bip-0138/test_vectors/keys_types.json
Normal file
47
bip-0138/test_vectors/keys_types.json
Normal file
@@ -0,0 +1,47 @@
|
||||
[
|
||||
{
|
||||
"description": "Xpub with origin and multipath wildcard",
|
||||
"key": "[58b7f8dc/48'/1'/0'/2']tpubDEPBvXvhta3pjVaKokqC3eeMQnszj9ehFaA2zD5nSdkaccwGAizu8jVB2NeSpvmP2P52MBoZvNCixqXRJnTyXx51FQzARR63tjxQSyP3Btw/<0;1>/*",
|
||||
"expected": "ebd252ca0877aae09b9d058219682775aa3cbcd049c12f07832f2cf6a3b51708"
|
||||
},
|
||||
{
|
||||
"description": "Xpub with single-path wildcard",
|
||||
"key": "[58b7f8dc/48'/1'/0'/2']tpubDEPBvXvhta3pjVaKokqC3eeMQnszj9ehFaA2zD5nSdkaccwGAizu8jVB2NeSpvmP2P52MBoZvNCixqXRJnTyXx51FQzARR63tjxQSyP3Btw/0/*",
|
||||
"expected": "ebd252ca0877aae09b9d058219682775aa3cbcd049c12f07832f2cf6a3b51708"
|
||||
},
|
||||
{
|
||||
"description": "Xpub with bare wildcard (no preceding path)",
|
||||
"key": "[58b7f8dc/48'/1'/0'/2']tpubDEPBvXvhta3pjVaKokqC3eeMQnszj9ehFaA2zD5nSdkaccwGAizu8jVB2NeSpvmP2P52MBoZvNCixqXRJnTyXx51FQzARR63tjxQSyP3Btw/*",
|
||||
"expected": "ebd252ca0877aae09b9d058219682775aa3cbcd049c12f07832f2cf6a3b51708"
|
||||
},
|
||||
{
|
||||
"description": "Xpub with fixed deep derivation, no wildcard",
|
||||
"key": "[58b7f8dc/48'/1'/0'/2']tpubDEPBvXvhta3pjVaKokqC3eeMQnszj9ehFaA2zD5nSdkaccwGAizu8jVB2NeSpvmP2P52MBoZvNCixqXRJnTyXx51FQzARR63tjxQSyP3Btw/0/5",
|
||||
"expected": "ebd252ca0877aae09b9d058219682775aa3cbcd049c12f07832f2cf6a3b51708"
|
||||
},
|
||||
{
|
||||
"description": "Xpub with multipath, no wildcard",
|
||||
"key": "[58b7f8dc/48'/1'/0'/2']tpubDEPBvXvhta3pjVaKokqC3eeMQnszj9ehFaA2zD5nSdkaccwGAizu8jVB2NeSpvmP2P52MBoZvNCixqXRJnTyXx51FQzARR63tjxQSyP3Btw/<0;1>",
|
||||
"expected": "ebd252ca0877aae09b9d058219682775aa3cbcd049c12f07832f2cf6a3b51708"
|
||||
},
|
||||
{
|
||||
"description": "Bare xpub (no derivation, no wildcard); DISALLOWED",
|
||||
"key": "[d4ab66f1/48'/1'/1'/2']tpubDFTxBKyUCgkwp5enwZh3t2FJ5AMJqmCWoh1NRT13qNYQb1iKTUrAG6u5gpsDYhG8cZGXouYWuQtzcuSVjPStTc4dwU6JqPMFtgaLGvSQXhi",
|
||||
"expected": null
|
||||
},
|
||||
{
|
||||
"description": "Compressed literal pubkey; DISALLOWED",
|
||||
"key": "02ebd252ca0877aae09b9d058219682775aa3cbcd049c12f07832f2cf6a3b51708",
|
||||
"expected": null
|
||||
},
|
||||
{
|
||||
"description": "X-only literal pubkey; DISALLOWED",
|
||||
"key": "ebd252ca0877aae09b9d058219682775aa3cbcd049c12f07832f2cf6a3b51708",
|
||||
"expected": null
|
||||
},
|
||||
{
|
||||
"description": "Uncompressed literal pubkey; DISALLOWED",
|
||||
"key": "04ebd252ca0877aae09b9d058219682775aa3cbcd049c12f07832f2cf6a3b517089e956909c4c07e8529f45f3ff8904d28df5a181619e21bdf748a896322530039",
|
||||
"expected": null
|
||||
}
|
||||
]
|
||||
Reference in New Issue
Block a user