lightningnetwork / lnd

Lightning Network Daemon ⚡️
MIT License
7.63k stars 2.07k forks source link

proof of reserve for bitcoin in channels #5391

Open nicolasburtey opened 3 years ago

nicolasburtey commented 3 years ago

We'd like to add proof of reserve on our banking application. one of the unknown I have currently lies on the side of the bitcoin that are in a channel.

Is there a way to sign a message to show proof ownership of a portion of the UTXO that is within a channel?

I'm sure there is no API yet but I'm currently wondering if this would even be possible with the current spec. maybe the other party would need to sign a message as well? Or maybe the forced-closed-ready-to-broadcast transaction could be used?

I'm sure there are also side things to think about like escrow (would not be an issue with the new channel) but I'm trying to get sense of the big picture first.

The track on our side for this item. An ongoing PR on the BDK side.

alexbosworth commented 3 years ago

You can sign a message on the channel output to_local key, if it's a static key all you have to do is export the keys into bitcoin core and then find the one that matches the channel key and then use that to sign

At a high level it's going to be pretty tricky to prove conclusively because channels are stateful in their own domain. How do I know that this proof hasn't already been invalidated by a future channel state?

nicolasburtey commented 3 years ago

At a high level it's going to be pretty tricky to prove conclusively because channels are stateful in their own domain. How do I know that this proof hasn't already been invalidated by a future channel state?

when the channel is being updated, there are some state in the script that are related to the block height IIRC?

if we can force an update of the channel somehow (I don't think we can... but not sure? maybe could trigger a msat payment when it's needed), we would have the last block height and this could be used as the time value at which the snapshot is done for the proof of reserve.

alexbosworth commented 3 years ago

You can update a channel more frequently than per block so even if this were the case I don't think it would be a solution

Maybe you could do something with hold payments: the auditor routes a payment through your channel back to themselves, proving that there is coins

nicolasburtey commented 3 years ago

Maybe you could do something with hold payments: the auditor routes a payment through your channel back to themselves, proving that there is coins

but if you have a lot of channels would this be working? it would basically block the channel while the hold payment is ongoing assuming the auditor want to see the full capacity of the channel ? and the time to loop all the channels the liquidity could also have changed?

You can update a channel more frequently than per block so even if this were the case I don't think it would be a solution

I think the proof of reserve implies a snapshot at a particular time. there are ways to gamify proof of reserve: a platform could borrow the coin they need to cover their assets just prior to the snapshot and send it back to the lender just after snapshot has been taken.

but if the snapshot is done at a regular interval (let's say every day, or multiple times a day) then this becomes much harder to gamify, compared to if it's done every 6 months for instance. but for that to be implemented it should be a solution that would not be too intrusive.

Roasbeef commented 3 years ago

Is there a way to sign a message to show proof ownership of a portion of the UTXO that is within a channel?

Given that the latest commitment shows the latest snapshot of the current channel balance distribution, you'd just need to show that commitment, and then send your half of the signature to the "auditor". It can't really be gamified as you describe, since the auditor would likley attempt to pin the set of channels to your advertised node. Public chanenls are easy since all nodes already have a proof (the channel announcement) that the channel is anchored at your node. Private channels aren't too different as you can show that there exists a channel which you can sign for.

In terms of what you need today to do something like this: the SCB file already contains the key descriptor information you need to generate an ad-hoc signature using the multi-sig key. From there, you'd need to obtain the latest commitment transaction which is already stored on disk, but not yet exposed on the RPC interface. If the ListChannels call returns the current unsigned commitment transaction then you can generate a manual signature. To err on the safe side, you likely want to sign a challenge that includes the commitment transaction and channel information, so your signature can't be levreage to breach the channel in the unlikely case that the auditor is colluding with your channel counter-party.