mirror of
https://github.com/bitcoin/bips.git
synced 2026-10-19 19:29:18 +00:00
Merge pull request #2299 from Sjors/2026/09/bip138-encoding
bip138: binary encoding clarifications
This commit is contained in:
26
bip-0138.md
26
bip-0138.md
@@ -10,7 +10,7 @@
|
|||||||
Discussion: https://delvingbitcoin.org/t/a-simple-backup-scheme-for-wallet-accounts/1607
|
Discussion: https://delvingbitcoin.org/t/a-simple-backup-scheme-for-wallet-accounts/1607
|
||||||
https://groups.google.com/g/bitcoindev/c/5NgJbpVDgEc/m/TtGK9sF9BgAJ
|
https://groups.google.com/g/bitcoindev/c/5NgJbpVDgEc/m/TtGK9sF9BgAJ
|
||||||
https://github.com/bitcoin/bips/pull/1951
|
https://github.com/bitcoin/bips/pull/1951
|
||||||
Version: 0.1.1
|
Version: 0.1.2
|
||||||
Requires: 32, 340, 380, 388, 389
|
Requires: 32, 340, 380, 388, 389
|
||||||
```
|
```
|
||||||
|
|
||||||
@@ -196,7 +196,9 @@ and integrity.[^chacha-default]
|
|||||||
hardware acceleration, making it suitable for hardware wallets and embedded devices.
|
hardware acceleration, making it suitable for hardware wallets and embedded devices.
|
||||||
|
|
||||||
* let $nonce$ = random(96 bits)
|
* let $nonce$ = random(96 bits)
|
||||||
* let $ciphertext$ = encrypt($payload$, $secret$, $nonce$)
|
* let $ciphertext$ = encrypt($payload$, $secret$, $nonce$, $aad$)
|
||||||
|
|
||||||
|
The additional authenticated data ($aad$) is empty.
|
||||||
|
|
||||||
The $nonce$ MUST NOT be all zero. If the random source yields an all-zero nonce,
|
The $nonce$ MUST NOT be all zero. If the random source yields an all-zero nonce,
|
||||||
the encoder MUST generate a new one.
|
the encoder MUST generate a new one.
|
||||||
@@ -210,7 +212,7 @@ computes:
|
|||||||
* for each `individual_secret_i` generate `reconstructed_secret_i` =
|
* for each `individual_secret_i` generate `reconstructed_secret_i` =
|
||||||
`individual_secret_i` ⊕ `si`
|
`individual_secret_i` ⊕ `si`
|
||||||
* for each `reconstructed_secret_i` process $payload$ =
|
* for each `reconstructed_secret_i` process $payload$ =
|
||||||
decrypt($ciphertext$, $secret$, $nonce$)
|
decrypt($ciphertext$, $secret$, $nonce$, $aad$)
|
||||||
|
|
||||||
Decryption will succeed if and only if **p** was one of the keys in the
|
Decryption will succeed if and only if **p** was one of the keys in the
|
||||||
descriptor/wallet policy.
|
descriptor/wallet policy.
|
||||||
@@ -336,7 +338,7 @@ CHACHA20_POLY1305 (per RFC 8439) supports plaintext up to 2^38 - 64 bytes.
|
|||||||
Implementations MAY impose stricter limits based on platform constraints
|
Implementations MAY impose stricter limits based on platform constraints
|
||||||
(e.g., limiting to 2^32 - 1 bytes on 32-bit architectures).
|
(e.g., limiting to 2^32 - 1 bytes on 32-bit architectures).
|
||||||
|
|
||||||
Implementations MUST reject empty payloads.
|
Implementations MUST reject empty payloads (i.e. zero content items).
|
||||||
|
|
||||||
#### Ciphertext
|
#### Ciphertext
|
||||||
|
|
||||||
@@ -406,7 +408,7 @@ remaining bytes are `PADDING`. A `PAYLOAD` MUST contain at least one item (see
|
|||||||
|
|
||||||
`TYPE_LENGTH`: variable-length integer representing the length of `TYPE_PARAMS` in bytes.
|
`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]
|
For all `TYPE` values except `0x00` and `0x01`, `TYPE_LENGTH` MUST be present.[^length-required]
|
||||||
|
|
||||||
[^length-required]: **Why is `TYPE_LENGTH` mandatory?**
|
[^length-required]: **Why is `TYPE_LENGTH` mandatory?**
|
||||||
`TYPE_LENGTH` is what lets a parser skip a content type it does not implement and still
|
`TYPE_LENGTH` is what lets a parser skip a content type it does not implement and still
|
||||||
@@ -415,20 +417,19 @@ For all `TYPE` values except `0x01`, `TYPE_LENGTH` MUST be present.[^length-requ
|
|||||||
implementation that only handles descriptors from recovering that descriptor. A
|
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.
|
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
|
`0x01` is exempt because every implementation handles it, so it is never skipped
|
||||||
blindly.
|
blindly. `0x00` is a terminator rather than a content item.
|
||||||
|
|
||||||
`TYPE_PARAMS`: variable-length field whose encoding depends on `TYPE`.
|
`TYPE_PARAMS`: variable-length field whose encoding depends on `TYPE`.
|
||||||
|
|
||||||
For `TYPE` values defined above:
|
For `TYPE` values defined above:
|
||||||
- 0x00: parsers MUST stop reading content items and treat the remaining bytes as
|
- 0x00: parsers MUST stop immediately and treat the remaining bytes as padding.
|
||||||
padding.
|
|
||||||
- 0x01: `TYPE_LENGTH` MUST be omitted and `TYPE_PARAMS` is a 2-byte big-endian unsigned integer
|
- 0x01: `TYPE_LENGTH` MUST be omitted and `TYPE_PARAMS` is a 2-byte big-endian unsigned integer
|
||||||
representing the BIP number that defines it.
|
representing the BIP number that defines it.
|
||||||
- 0x02: `TYPE_PARAMS` MUST be `TYPE_LENGTH` bytes of opaque, vendor-specific data.
|
- 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,
|
- 0x03: `TYPE_PARAMS` MUST be empty, and the following `CONTENT` is the string itself,
|
||||||
which MUST be valid UTF-8.
|
which MUST be valid UTF-8.
|
||||||
|
|
||||||
For all `TYPE` values except `0x01`, parsers MUST reject `CONTENT_TYPE` if `TYPE_LENGTH` exceeds
|
For all `TYPE` values except `0x00` and `0x01`, parsers MUST reject `CONTENT_TYPE` if `TYPE_LENGTH` exceeds
|
||||||
the remaining payload bytes.
|
the remaining payload bytes.
|
||||||
|
|
||||||
For an unknown `TYPE` less than `0x80`, parsers MUST consume its `TYPE_LENGTH` bytes of
|
For an unknown `TYPE` less than `0x80`, parsers MUST consume its `TYPE_LENGTH` bytes of
|
||||||
@@ -593,6 +594,10 @@ The version field enables possible future enhancements:
|
|||||||
vectors for key serialisations.
|
vectors for key serialisations.
|
||||||
[content_type.json](./bip-0138/test_vectors/content_type.json) contains test
|
[content_type.json](./bip-0138/test_vectors/content_type.json) contains test
|
||||||
vectors for content types serialisations.
|
vectors for content types serialisations.
|
||||||
|
[payload.json](./bip-0138/test_vectors/payload.json) contains test vectors for payload parsing.
|
||||||
|
`payload` and each item's `content` are hexadecimal bytes; `type` is the numeric
|
||||||
|
type byte, and `items` lists the content items before the terminator.
|
||||||
|
|
||||||
[derivation_path.json](./bip-0138/test_vectors/derivation_path.json) contains
|
[derivation_path.json](./bip-0138/test_vectors/derivation_path.json) contains
|
||||||
test vectors for derivation paths serialisations.
|
test vectors for derivation paths serialisations.
|
||||||
[individual_secrets.json](./bip-0138/test_vectors/individual_secrets.json)
|
[individual_secrets.json](./bip-0138/test_vectors/individual_secrets.json)
|
||||||
@@ -628,6 +633,9 @@ their reviews and suggestions.
|
|||||||
|
|
||||||
## Changelog
|
## Changelog
|
||||||
|
|
||||||
|
* __0.1.2__ (2026-09-24):
|
||||||
|
* Specify empty AEAD associated data.
|
||||||
|
* Clarify that `0x00` ends payload parsing and add test vectors.
|
||||||
* __0.1.1__ (2026-09-23):
|
* __0.1.1__ (2026-09-23):
|
||||||
* Clarify derivation range bounds and zero or omitted birth-time semantics for descriptors and policies.
|
* Clarify derivation range bounds and zero or omitted birth-time semantics for descriptors and policies.
|
||||||
* Clarify receive-only descriptor sets and add a corresponding test vector.
|
* Clarify receive-only descriptor sets and add a corresponding test vector.
|
||||||
|
|||||||
18
bip-0138/test_vectors/payload.json
Normal file
18
bip-0138/test_vectors/payload.json
Normal file
@@ -0,0 +1,18 @@
|
|||||||
|
[
|
||||||
|
{
|
||||||
|
"description": "Bytes after terminator are ignored",
|
||||||
|
"valid": true,
|
||||||
|
"payload": "030001610080ff",
|
||||||
|
"items": [
|
||||||
|
{
|
||||||
|
"type": 3,
|
||||||
|
"content": "61"
|
||||||
|
}
|
||||||
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"description": "Payload with no content item.",
|
||||||
|
"valid": false,
|
||||||
|
"payload": "00"
|
||||||
|
}
|
||||||
|
]
|
||||||
Reference in New Issue
Block a user