Skip to content

Commit

Permalink
Fix some wrong examples missing /**; add test vectors for invalid des…
Browse files Browse the repository at this point in the history
…criptor templates
  • Loading branch information
bigspider committed Sep 12, 2023
1 parent 9adbecc commit 4b1f826
Showing 1 changed file with 27 additions and 9 deletions.
36 changes: 27 additions & 9 deletions bip-wallet-policies.mediawiki
Original file line number Diff line number Diff line change
Expand Up @@ -175,7 +175,8 @@ A ''wallet descriptor template'' is a <tt>SCRIPT</tt> expression.
* followed by a non-negative decimal number, with no leading zeros (except for <tt>@0</tt>)
* ''always'' followed by either:
** the string <tt>/**</tt>, or
** a string of the form <tt>/<NUM;NUM>/*</tt>, for two distinct decimal numbers <tt>NUM</tt> representing unhardened derivations.
** a string of the form <tt>/<NUM;NUM>/*</tt>, for two distinct decimal numbers <tt>NUM</tt> representing unhardened derivations, or
** any of the additional, implementation-specific valid derivation path patterns (see [[#Optional_derivation_paths|Optional derivation paths]] below).
The <tt>/**</tt> in the placeholder template represents commonly used paths for receive/change addresses, and is equivalent to <tt><0;1>/*</tt>.

Expand Down Expand Up @@ -236,8 +237,8 @@ In order to allow supporting legacy derivation schemes (for example, using simpl

However, care needs to be taken in view of the following considerations:

- Allowing derivation schemes with a different length or cardinality in the same wallet policy would make it difficult to guarantee that there are no repeated pubkeys for every possible address generated by the policy. For example, `@0/<0;1>/*` and `@1/*` would generate the same pubkeys if the second public key in the keys information vector is one of the first two unhardened children of the first public key. This could cause malleability with potential security implications (for example, in policies containing miniscript).
- Allowing naked pubkeys with no <tt>/*</tt> suffix (for example a descriptor template like <tt>wsh(multi(2,@0,@1/<0;1>/*))</tt>) would cause a pubkey to be repeated in every output generated from the policy, which would result in a total loss of privacy.
* Allowing derivation schemes with a different length or cardinality in the same wallet policy would make it difficult to guarantee that there are no repeated pubkeys for every possible address generated by the policy. For example, `@0/<0;1>/*` and `@1/*` would generate the same pubkeys if the second public key in the keys information vector is one of the first two unhardened children of the first public key. This could cause malleability with potential security implications (for example, in policies containing miniscript).
* Allowing naked pubkeys with no <tt>/*</tt> suffix (for example a descriptor template like <tt>wsh(multi(2,@0,@1/<0;1>/*))</tt>) would cause a pubkey to be repeated in every output generated from the policy, which would result in a total loss of privacy.
== Examples ==

Expand All @@ -250,16 +251,18 @@ Common single-signature account patterns:
* <tt>tr(@0/**)</tt> (taproot single-signature account).
Common multisignature schemes:
* <tt>wsh(multi(2,@0,@1))</tt> - SegWit 2-of-2 multisignature, keys in order.
* <tt>sh(sortedmulti(2,@0,@1,@2))</tt> - Legacy 2-of-3 multisignature, sorted keys.
* <tt>wsh(multi(2,@0/**,@1/**))</tt> - SegWit 2-of-2 multisignature, keys in order.
* <tt>sh(sortedmulti(2,@0/**,@1/**,@2/**))</tt> - Legacy 2-of-3 multisignature, sorted keys.
Some miniscript policies in <tt>wsh</tt>:
* <tt>wsh(and_v(v:pk(@0),or_d(pk(@1),older(12960))))</tt> - Trust-minimized second factor, degrading to a single signature after about 90 days.
* <tt>wsh(and_v(v:pk(@0/**),or_d(pk(@1/**),older(12960))))</tt> - Trust-minimized second factor, degrading to a single signature after about 90 days.
* <tt>wsh(thresh(3,pk(@0/**),s:pk(@1/**),s:pk(@2/**),sln:older(12960)))</tt> - A 3-of-3 wallet that becomes a 2-of-3 if coins are not spent for about 90 days.
* <tt>wsh(or_d(pk(@0),and_v(v:multi(2,@1,@2,@3),older(65535))))</tt> - A singlesig wallet with automatic inheritance to a timelocked 2-of-3 multisig of family members.
* <tt>wsh(or_d(pk(@0/**),and_v(v:multi(2,@1/**,@2/**,@3/**),older(65535))))</tt> - A singlesig wallet with automatic inheritance to a timelocked 2-of-3 multisig of family members.
== Test Vectors ==

=== Valid policies ===

[[bip-0044.mediawiki|BIP-44]], first account
Descriptor template: pkh(@0/**)
Keys info: ["[6738736c/44'/0'/0']xpub6Br37sWxruYfT8ASpCjVHKGwgdnYFEn98DwiN76i2oyY6fgH1LAPmmDcF46xjxJr22gw4jmVjTE2E3URMnRPEPYyo1zoPSUba563ESMXCeb"]
Expand All @@ -276,9 +279,9 @@ Some miniscript policies in <tt>wsh</tt>:
Descriptor:wpkh([6738736c/84'/0'/2']xpub6CRQzb8u9dmMcq5XAwwRn9gcoYCjndJkhKgD11WKzbVGd932UmrExWFxCAvRnDN3ez6ZujLmMvmLBaSWdfWVn75L83Qxu1qSX4fJNrJg2Gt)
<br>
[[bip-0086.mediawiki|BIP-86]], first account
Descriptor template: tr(@0/**))
Descriptor template: tr(@0/**)
Keys info: ["[6738736c/86'/0'/0']xpub6CryUDWPS28eR2cDyojB8G354izmx294BdjeSvH469Ty3o2E6Tq5VjBJCn8rWBgesvTJnyXNAJ3QpLFGuNwqFXNt3gn612raffLWfdHNkYL"]
Descriptor:tr([6738736c/86'/0'/0']xpub6CryUDWPS28eR2cDyojB8G354izmx294BdjeSvH469Ty3o2E6Tq5VjBJCn8rWBgesvTJnyXNAJ3QpLFGuNwqFXNt3gn612raffLWfdHNkYL))
Descriptor:tr([6738736c/86'/0'/0']xpub6CryUDWPS28eR2cDyojB8G354izmx294BdjeSvH469Ty3o2E6Tq5VjBJCn8rWBgesvTJnyXNAJ3QpLFGuNwqFXNt3gn612raffLWfdHNkYL)
<br>
[[bip-0048.mediawiki|BIP-48]] P2WSH multisig
Descriptor template: wsh(sortedmulti(2,@0/**,@1/**))
Expand All @@ -298,6 +301,21 @@ Miniscript: A singlesig wallet with automatic inheritance to a timelocked 2-of-3

TBD: add examples with taproot scripts and miniscript.

=== Invalid policies ===

The following descriptor templates are invalid:

* <tt>pkh(@0)</tt>: Key placeholder with no path following it
* <tt>pkh(@0/0/*)</tt>: Key placeholder with an explicit path present
* <tt>sh(multi(1,@1/**,@0/**))</tt>: Key placeholders out of order
* <tt>sh(multi(1,@0/**,@2/**))</tt>: Skipped key placeholder <tt>@1</tt>
* <tt>sh(multi(1,@0/**,@0/**))</tt>: Repeated keys w/same path expression
* <tt>sh(multi(1,@0/<0;1>/*,@0/<1;2>/*))</tt>: Non-disjoint multipath expressions (<tt>@0/1/*</tt> appears twice)
* <tt>sh(multi(1,@0/**,xpub6AHA9hZDN11k2ijHMeS5QqHx2KP9aMBRhTDqANMnwVtdyw2TDYRmF8PjpvwUFcL1Et8Hj59S3gTSMcUQ5gAqTz3Wd8EsMTmF3DChhqPQBnU/<0;1>/*))</tt>: Expression with a non KP key present
* <tt>pkh(@0/<0;1;2>/*)</tt>: Solved cardinality > 2
Remark: some of the descriptor templates above might be valid if optional extensions allowing them are added in the implementation.

== Backwards Compatibility ==

The <tt>@</tt> character used for key placeholders is not part of the syntax of output script descriptors, therefore any valid output descriptor with at least one `KEY` expression is not a valid descriptor template. Vice versa, any descriptor template with at least one key placeholder is not a valid output script descriptor.
Expand Down

0 comments on commit 4b1f826

Please sign in to comment.