diff --git a/bip-0138.md b/bip-0138.md index e44571c3..39f7739c 100644 --- a/bip-0138.md +++ b/bip-0138.md @@ -114,8 +114,8 @@ 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). +The [Descriptor key requirements](#descriptor-key-requirements) exclude +keys exposed by literal or bare-xpub expressions in the backed-up scripts. Implementations MUST exclude the key with x coordinate `50929b74c1a04954b78b4b6035e97a5e078a5a0f28ec96d547bfee9ace803ac0` (the BIP341 NUMS point). Applications MAY exclude any further key they know to be public. @@ -172,14 +172,19 @@ does not reveal the individual participant keys. For encryption, use each participant's xpub root rather than the aggregate key. Literal public-key participants remain excluded. +A candidate root MUST be excluded if its x-coordinate matches a literal key +or a bare xpub root used outside `musig()` in any descriptor or resolved +policy in the payload. For example, +`wsh(or_i(pk(X/0/*),pk(X)))` exposes the root of xpub `X` on spending, so that +root must be excluded even though `X/0/*` is otherwise eligible. + Implementations: - MUST exclude every other form (literal pubkeys, bare xpubs outside `musig()`, ...) 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. +- MUST make the user aware of each excluded expression and candidate root, + since its holder may be unable to decrypt the backup with that key. ### Key Normalization diff --git a/bip-0138/test_vectors/recipient_keys.json b/bip-0138/test_vectors/recipient_keys.json index 5105a7e7..f12adb0b 100644 --- a/bip-0138/test_vectors/recipient_keys.json +++ b/bip-0138/test_vectors/recipient_keys.json @@ -103,5 +103,29 @@ "8b42cd4776376c82791b494155151f56c2d7b471e0c7a526a7ce60dd872e3867", "ebd252ca0877aae09b9d058219682775aa3cbcd049c12f07832f2cf6a3b51708" ] + }, + { + "description": "Root used both bare and derived is excluded", + "descriptors": [ + "wsh(or_i(pk(tpubDEPBvXvhta3pjVaKokqC3eeMQnszj9ehFaA2zD5nSdkaccwGAizu8jVB2NeSpvmP2P52MBoZvNCixqXRJnTyXx51FQzARR63tjxQSyP3Btw/0/*),pk(tpubDEPBvXvhta3pjVaKokqC3eeMQnszj9ehFaA2zD5nSdkaccwGAizu8jVB2NeSpvmP2P52MBoZvNCixqXRJnTyXx51FQzARR63tjxQSyP3Btw)))" + ], + "expected_keys": null + }, + { + "description": "Xpub root (03ebd252ca0877aae09b9d058219682775aa3cbcd049c12f07832f2cf6a3b51708) excluded by an opposite-parity literal in another descriptor set", + "descriptors": [ + "tr(tpubDEPBvXvhta3pjVaKokqC3eeMQnszj9ehFaA2zD5nSdkaccwGAizu8jVB2NeSpvmP2P52MBoZvNCixqXRJnTyXx51FQzARR63tjxQSyP3Btw/*)", + "wpkh(02ebd252ca0877aae09b9d058219682775aa3cbcd049c12f07832f2cf6a3b51708)" + ], + "expected_keys": null + }, + { + "description": "MuSig participant exposed in a script leaf", + "descriptors": [ + "tr(musig(tpubDC5FSnBiZDMmhiuCmWAYsLwgLYrrT9rAqvTySfuCCrgsWz8wxMXUS9Tb9iVMvcRbvFcAHGkMD5Kx8koh4GquNGNTfohfk7pgjhaPCdXpoba,tpubDEPBvXvhta3pjVaKokqC3eeMQnszj9ehFaA2zD5nSdkaccwGAizu8jVB2NeSpvmP2P52MBoZvNCixqXRJnTyXx51FQzARR63tjxQSyP3Btw)/0/*,pk(tpubDC5FSnBiZDMmhiuCmWAYsLwgLYrrT9rAqvTySfuCCrgsWz8wxMXUS9Tb9iVMvcRbvFcAHGkMD5Kx8koh4GquNGNTfohfk7pgjhaPCdXpoba))" + ], + "expected_keys": [ + "ebd252ca0877aae09b9d058219682775aa3cbcd049c12f07832f2cf6a3b51708" + ] } ]