diff --git a/bip-0138.md b/bip-0138.md index 90ae803e..8c5d6cda 100644 --- a/bip-0138.md +++ b/bip-0138.md @@ -10,7 +10,7 @@ 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 - Version: 0.1.1 + Version: 0.1.2 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. * 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 encoder MUST generate a new one. @@ -210,7 +212,7 @@ computes: * for each `individual_secret_i` generate `reconstructed_secret_i` = `individual_secret_i` ⊕ `si` * 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 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 (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 @@ -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. -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?** `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 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. + blindly. `0x00` is a terminator rather than a content item. `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. +- 0x00: parsers MUST stop immediately 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 +For all `TYPE` values except `0x00` and `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 @@ -593,6 +594,10 @@ The version field enables possible future enhancements: vectors for key serialisations. [content_type.json](./bip-0138/test_vectors/content_type.json) contains test 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 test vectors for derivation paths serialisations. [individual_secrets.json](./bip-0138/test_vectors/individual_secrets.json) @@ -628,6 +633,9 @@ their reviews and suggestions. ## 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): * 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. diff --git a/bip-0138/test_vectors/payload.json b/bip-0138/test_vectors/payload.json new file mode 100644 index 00000000..90ee8f65 --- /dev/null +++ b/bip-0138/test_vectors/payload.json @@ -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" + } +]