Subject: Re: [bitcoin-dev] OP_VAULT: a new vault proposal

From: "James O'Beirne" <[email-masked]>
Date: Fri, 20 Jan 2023 12:43:14 -0500

Andrew, thanks for taking the time.

> It seems like this proposal will encourage address reuse for vaults,
> at least in some parts. It seems like it would not be difficult to
> ensure that each vault address was unique through the use of key
> derivation.

I think it's worth stepping back and noting that this proposal defers
the level of privacy-vs.-efficiency to be decided by the end user.

For users who are very privacy conscious and are doing fairly low volume
(a few vaulted coins a month?), trading the ability to do batched
operations for no privacy loss seems reasonable. They can use a ranged
descriptor to generate recovery paths and unvault sPKs and reveal no
marginal information during recoveries or unvaults.

Though of course there still may be an obvious temporal association
across transactions in the case of recovery - everything with the same
unvault key has to be recovered at once.

For users who expect to have large numbers of vaulted coins and maybe
don't care as much about privacy (e.g. many commercial users), revealing
the related nature of coins that are being unvaulted or recovered seems
like an okay cost to pay. Such users might decide to create "tranches"
of vaults with different parameters in whatever manner makes sense for
their use.

Importantly: in either case, you can always keep the nature of
still-vaulted coins hidden by burying the OP_VAULT script in a taptree
and varying the internal key you use for each coin with a ranged
descriptor. This way, only the revealed contents of unvaults and
recoveries can be associated. So I think that's your worst case, which
really doesn't seem bad to me.

As an aside, a goal in supporting address reuse wasn't for address reuse
*per se* - it was to remove potential catastrophe resulting from the
case where you give someone a vault address to deposit to, and they wind
up depositing to it multiple times - whether you warned them against it
or not.

> I'm not sure how [batching without privacy loss] could be solved
> though.

For recovery, I think it might be intractable at the moment.

Seemingly unrelated vaults which have the same recovery parameters will
presumably be recovered together if the unvault key is compromised. The
simple fact that these outputs are being spent together and are OP_VAULT
scripts fundamentally reveals their association during recovery, no way
around that AFAICT.

Similarly for the unvaulting, you can't get around revealing that you're
spending a group of outputs that contain an OP_VAULT script.

As mentioned above, unvaulting -- regardless of whether your vault
configuration supports batching or not -- *never* has to correlate
unvaulted coins to still-vaulted coins if you are either

  (i) varying the internal key used for the OP_VAULT taptrees, or
  (ii) using the optional "authorized recovery" feature and are varying
       that sPK with a ranged descriptor.

So there's really never a case where unvaults have to reveal a
relationship to, or between, still-vaulted coins. Subsequent unvaults
may be able to be correlated though on the basis of the recovery sPK
target hash.

> It just means that the recovery scripts must be the same, and this
> would leave an identifying mark on chain for every unvault.

This is only true if the user decides to create vaults which share
"literal" recovery paths. At the risk of belaboring the point for
clarity, you can avoid this by generating the different "literal"
recovery paths from a ranged descriptor which is controlled by a single
private key -- of course at the cost of no batched recovery.

> not to mention that sweeping to recovery would also reveal all of your
> coins too.

Maybe it's worth contextualizing that recovery sweeps really only happen
as a final fallback in catastrophic cases that, in a world without
vaults, would result in the coins simply being stolen. In this case I
would guess most users are willing to make the privacy trade to retain
ownership of their coins.

> I think it would be sufficient to do the same check as the OP_UNVAULT
> script [when validating the revault output in the unvault trigger
> transaction] and just require that the recovery script and the delay
> are the same

Consider that this allows the holder of the unvault key (possibly an
attacker) to immediately spend the vault into a new vault configuration
with a different unvault key.

Obviously the recovery path would still be the same, and so the owner of
the vault could still sweep if the unvault key switch was unauthorized,
but I'll need to think a little bit more about whether this change is
more fundamental.

Generally that would be easy to implement, though. I'll think on it. My
suspicion is that you're right and this would be a good change.

> I'm also not convinced that OP_VAULT and OP_UNVAULT should be allowed
> for bare and P2WSH outputs. It seems like it would make sense to just
> limit their usage to tapscripts as this would simply their
> implementation.

I think you're right, and accordingly I'll shortly be reimplementing
this with OP_SUCCESSx overrides instead of OP_NOPs. I'd be curious to
know if anyone has any objections to this - i.e. if there's a solid case
for vaults in a pre-taproot context.

James