Exploding Keys
TLDR: Public keys that commit to a set of outputs. If the key is spent to those outputs, no signature or witness is needed.
Motivation: Exploding keys gets you basically the same functionality as op_ctv
but done in a somewhat clever way that saves a few bytes. I came up with this a while ago but kept thinking there was a way to make this better / more powerful / really compelling. Maybe that’s not going to happen, and I want to write up all the things that would be really cool but don’t work. On it’s own it’s kind of fun though and maybe will give people some ideas, or could be a tool for bitcoin covenants.
For the example transactions, assume that public keys are used like in taproot outputs, rather than public key hashes.
The example tx has 1 input and 3 outputs.
Input 0:
txid:idx (points to prev PkScript KeyQ, 9 BTC)
no sigscript
no witness
Output 0:
KeyA, 2 BTC
Output 1:
KeyB, 3 BTC
Output 2:
KeyC, 4 BTC
Normally you’d look at this and say, well there’s no witness, so no deal, fail the tx. But with the exploding keys soft fork (guess you’d need to use a new segwit version or some other tag to keep the fork soft) you perform an additional check if the tx has no witnesses:
For each output, use the presented key as an “inner key” and commit in the amount of BTC taproot style (BIP 341). Store the keys for the next step.
KeyA' = KeyA + hash(2, KeyA)*G
KeyB' = KeyB + hash(3, KeyB)*G
KeyC' = KeyC + hash(4, KeyC)*G
Next, take the key aggregation function in BIP 327, KeyAgg(), and feed it all the tweaked keys. (I think you don’t want to run KeySort() first and keep it in the order seen in the tx).
KeyW = KeyAgg(KeyA', KeyB', KeyC')
Then check if KeyW == KeyQ
seen in the input. If they’re equal then the input passes the validation checks despite having an empty witness. (You still need to check that the amounts work - in this example they do with 0 fee)
I think this works in that if you’re given a KeyQ
, there’s no way to come up with a set of keys that aggregates to it other than the one initially used to construct KeyQ
itself. If there were, that would be a problem / collision for BIP 327 aggregation. Similarly, given a tweaked key like KeyA'
, there should be no way to come up with a different inner key and tweak value, because that would be a problem for BIP 341 tweaking.
To construct an exploding key, you go through the same sequence as verification: start with the keys and amounts you want to explode to, then tweak, then aggregate the tweaked keys. The resulting key is an explodable key which you can send coins to. What’s nice is that private key holders A, B, and C can still interact to sign with the explodable key to send it somewhere else. If they can’t interact though, any party with the knowledge of the output set (which is not just A, B, and C, after all there is no signature needed) can explode the key into the 3 components. This could be useful for a shared UTXO where multiple parties all claim a portion of the total coins - they can cooperate to sign or press the explode button to leave.
Just like op_ctv
, this works recursively – KeyA
can itself be an exploding key.
So that’s it. It gives the basic functionality of op_ctv
, while saving a few bytes of witness data. On it’s own it’s maybe not all that compelling, but I wanted to put it out there as maybe it could be a useful primitive as part of a more complex covenant construction.
Don’t have time today but I do want to write a bit in a day or two about some things that would be really cool if exploding keys could do them, but they can’t and maybe nothing can
Thanks to sipa & real-or-random who I discussed this with a while ago and helped with feedback. (Also I may have forgotten their feedback, rendering this construction insecure, in which case, that’s on me not them )