rust-bitcoin / rust-miniscript

Support for Miniscript and Output Descriptors for rust-bitcoin
Creative Commons Zero v1.0 Universal
353 stars 139 forks source link

Concrete policy does not allow duplicates pubkey when necessary #338

Closed dr-orlovsky closed 1 year ago

dr-orlovsky commented 2 years ago

It is impossible to do constructions like

or(
  thresh(3, pk1, pk2, pk3),
  and(thresh(2, pk1, pk2, pk3), older(100),
  and(thresh(1, pk1, pk2, pk3), older(1000),
)

Such constructs are possible with taproot trees (manually constructed), but I am afraid that in WIP compiler for taproot they can also get prohibited.

apoelstra commented 2 years ago

My concern is that constructions like

or(pk1, pk1)

are malleable, because of the reuse of pk1. This is true even if they are in different branches of a taptree, and it's easy enough to construct non-stupid variants of this.

I agree that key reuse is useful and sometimes necessary to produce optimal trees. But this was true before Taproot, and Taproot does not fix the problems that they cause for Miniscript, so I don't see any way to move forward.

sanket1729 commented 2 years ago
or(
thresh(3, pk1, pk2, pk3),
and(thresh(2, pk1, pk2, pk3), older(100),
and(thresh(1, pk1, pk2, pk3), older(1000),
)

The goal of the policy language is to set spending conditions. The user need not know whether it uses a taproot tree internally or not. In your case, the user should specify thresh(3, pk1, pk2, pk3, older(100), older(1000)) and let the compiler do the rest. If you really need the tree to be constructed in a specific way. You would have compiled each of the miniscripts separately and then construct a tree.

This is true even if they are in different branches of a taptree, and it's easy enough to construct non-stupid variants of this.

The key also signs the LeafHash to which it belongs. Therefore, signature malleability across tapleafs is only a concern if we have the exact same leaf in different positions of the tree.

There is some ongoing discussion between Pieter and Darosior on repeated keys, I should check on its status.

dr-orlovsky commented 2 years ago

Ok, what about case when I need a 3-of-5 multisig anytime, or 2-of-5 in 5 years, or 1-of-5 in 20 years, or single sig of a notary (not participating the original 5 multisig) in 50 years? It can't be expressed without using duplicated keys.

SarcasticNastik commented 2 years ago

Hi! Was there any update in this discussion? Is there a plan to opt for duplicate keys in different branches of the TapTree in the future?

apoelstra commented 2 years ago

There has been no update. It appears to be infeasible for Miniscript to support repeated keys while having correct malleability analysis. I am open to algorithmic ideas, but listing use cases will not make it feasible.

sanket1729 commented 2 years ago

@dr-orlovsky , you can do the same as:

or(pk(notary), older(50 years)),thresh(3,pk(A),pk(B),pk(C),pk(D),pk(E),older(5 years),older(20 years))

dr-orlovsky commented 2 years ago

@sanket1729 very good point, thank you! But can we proof in generic way that any or-set of threshold-and-timelock conditions can be represented without using repeating keys? I assume the answer is "no".

sanket1729 commented 2 years ago

I think the answer is no. Or rather I don't know how to do it or if it is possible.

But, if you are using keys across disjunctions,/thresholds your scripts can be malleable, which is precisely the goal of miniscript. And if you are keys across conjunctions, you are doing something dumb (and(A,A)) etc.

If it is possible for Miniscript to support repeated keys while having correct malleability analysis, I am all in for it. As an example, or(pk(A),and(pk(A),pk(B))) is malleable. In multi-party protocols, this can result in pinning attacks, where B reduces the fee rate by the transaction by looking at the with only pk(A) and signing using the other half.

sanket1729 commented 2 years ago

This is not a problem with compiler policy, but rather with Miniscript malleability reasoning.

sanket1729 commented 1 year ago

Closing this a duplicate as the goals contradict with miniscript malleability reasoning.