Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

option_scid_assign: privacy protection for private channels. #681

Closed

Conversation

rustyrussell
Copy link
Collaborator

This turned out to be a bit more complex than I expected.

Private channels expose their funding transaction in routehints to
receive payments, but this is unnecesary. Their funding tx can also
be probed via payment attempts.

  1. A new feature, so you know when you can use these controls.
  2. A channel_flags bit so you can ensure that new channels are
    protected probes from the start.
  3. Messages to assign (and unassign) random short_channel_ids,
    with a side-effect of disabling the funding-tx-based one.

Fixes: #675

…in Contents.

It wes between "Packet Structure" and "Payload for the Last Node",
which is just weird.  Move it after "Payload for the Last Node".

Signed-off-by: Rusty Russell <rusty@rustcorp.com.au>
Private channels expose their funding transaction in routehints to
receive payments, but this is unnecesary.  Their funding tx can also
be probed via payment attempts.

1. A new feature, so you know when you can use these controls.
2. A channel_flags bit so you can ensure that new channels are
   protected probes from the start.
3. Messages to assign (and unassign) random short_channel_ids,
   with a side-effect of disabling the funding-tx-based one.

Fixes: lightning#675
Signed-off-by: Rusty Russell <rusty@rustcorp.com.au>
Copy link
Collaborator

@t-bast t-bast left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Great proposal, thanks for putting this together.
I was thinking about that a couple of weeks ago and tinkering with the idea of going even further and allowing "private/unannounced" nodes to use multiple node IDs (node_id_alias maybe?).

My high-level idea is that Eve (not Alice, Alice is nice and has nothing to hide) opens an unannounced channel with some public node (why not ACINQ, I hear it's a great node?). She then registers several node ids with the public node to use as alias. When the public node receives a forwarding request, he uses the real node_id and short_channel_id. WDYT?

the funding flow wishes to advertise this channel publicly to the
network, as detailed within [BOLT #7](07-routing-gossip.md#bolt-7-p2p-node-and-channel-discovery).

`disable_incoming` indicates that no payments are to be accepted for this
channel: this is only effective if `announce_channel` is not set, and the
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is a bit misleading. Payments will be accepted for this channel, but with a different short_channel_id than the funding-tx-based one, right? So maybe:

Suggested change
channel: this is only effective if `announce_channel` is not set, and the
channel using its funding-transaction-derived `short_channel_id`: this is only effective if `announce_channel` is not set, and the

Comment on lines 1180 to 1185
If it were to conflict with a future `short_channel_id` for a real
channel, misrouting may occur. The simplest way to minimize this is
to use old block numbers, but that also reduces the search space.
Simpler is to select a random value which isn't already used, and
close (before funding_locked) any future channel unfortunate enough to
clash.
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'm more in favor of restricting to old blocks, this makes it a lot simpler to manage.
Restricting to old blocks means we have ~500.000*2^40 possibilities ~= 10^17
Assuming 100.000 attempts per second (most nodes probably won't be able to forward that many payment attempts per second, so it feels conservative) it will take more than 150.000 years to probe.
Should be a big enough search space, isn't it? ;)

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

In practice, you can just pick a random 64 you will never clash. I don't want to overly restrict implementations: you can choose to use a subset of believable unspent outputs, etc.

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Agreed, I just think we can remove the statement that choosing old blocks reduces the search space because in practice it's irrelevant.

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Should random scid be the same for both peers? I suppose there's no reason for it to be different from each side as that would be easier to apply to current implementations where same scid is already assumed.

No, since it might clash for one side, and one side might tear it down while you were trying to use it. And why make it the same? That just leaks information.

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

And why make it the same? That just leaks information.

Makes implementation easier at least in Eclair where I'm trying to do it: currently graph engine determines that two ChannelUpdates belong to the same channel by them having a same scid. But of course this should not dictate the spec.

Just curious: what kind of info is specifically leaked by same scid?

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The leak us:

  1. Alice has a private channel with Bob: they call it scid-tmp.
  2. Mallory asks Alice's website for an invoice, Alice gives Mallory a fake pubkeyA and scid-tmp from Bob.
  3. Mallory asks Bob's website for an invoice, Bob gives a fake pubkeyB and the same scid-tmp from Alice.

Mallory has learned that Alice == pubkeyA and Bob == pubkeyB.

@rustyrussell
Copy link
Collaborator Author

Great proposal, thanks for putting this together.
I was thinking about that a couple of weeks ago and tinkering with the idea of going even further and allowing "private/unannounced" nodes to use multiple node IDs (node_id_alias maybe?).

This is always possible, but makes routing loops worse, and can always be done on a separate layer.
I prefer rendezvous routing, which doesn't require registration.

@t-bast
Copy link
Collaborator

t-bast commented Oct 5, 2019

I prefer rendezvous routing, which doesn't require registration.

Isn't that true as well for the scid trick you're proposing in this PR? It's obsolete once we have rendezvous routing (which may also make the invoice route hints obsolete altogether).

However I believe that rendezvous routing is potentially more costly in terms of bytes used in the invoice, but maybe we should spend more time spec-ing a proposal to figure that out. I can work on that.

@t-bast
Copy link
Collaborator

t-bast commented Oct 7, 2019

Rendezvous routing will not play nicely with MPP...if a recipient wants to use rendezvous for multi-part payments, it will have to generate multiple onions (for each partial payment) which will be too big to put in the invoice.

This scid proposal is more lightweight so it will add value even if we have rendezvous support at some point.

This is always possible, but makes routing loops worse

I don't understand your point about routing loops...for "private" nodes these alias node ids will not be announced to the network and will only be included in invoices, with details of the (unannounced) channel leading to it. So it won't mess anything routing-related. And those alias node ids can be BIP32-derived from a main nodeId, so they won't even clash with any other nodeId in the network. Maybe I should draft something more detailed?

@akumaigorodski
Copy link

Should random scid be the same for both peers? I suppose there's no reason for it to be different from each side as that would be easier to apply to current implementations where same scid is already assumed. But that would mean one side should ask, and the other one should update a scid for itsef and peer, not both at once, or am I missing something?

@akumaigorodski
Copy link

@rustyrussell
Copy link
Collaborator Author

My high-level idea is that Eve (not Alice, Alice is nice and has nothing to hide) opens an unannounced channel with some public node (why not ACINQ, I hear it's a great node?). She then registers several node ids with the public node to use as alias. When the public node receives a forwarding request, he uses the real node_id and short_channel_id. WDYT?

I thought about this some more: you can do this already without revealing to the public node what transient key you're using. Which is even more win!

@rustyrussell
Copy link
Collaborator Author

https://github.com/lightningnetwork/lightning-rfc/pull/681/files#diff-ad219ee50fcd8926614ca5a5d5f1a1f7R31

Should not 114/115 be 14/15?

No, I'm using the experimental range until this gets approved. THen it will get the next available.

@rustyrussell
Copy link
Collaborator Author

I prefer rendezvous routing, which doesn't require registration.

Isn't that true as well for the scid trick you're proposing in this PR? It's obsolete once we have rendezvous routing (which may also make the invoice route hints obsolete altogether).

Good point.

However I believe that rendezvous routing is potentially more costly in terms of bytes used in the invoice, but maybe we should spend more time spec-ing a proposal to figure that out. I can work on that.

So many things to do...!

Feedback from @t-bast.

Renamed the option, and made it clear that it only disabled the
funding-tx-based scid.

Noted also that *both* ends should hide the original id.

Signed-off-by: Rusty Russell <rusty@rustcorp.com.au>
@akumaigorodski
Copy link

Should a peer also send a fresh channel_update after assign_scid_reply? An old one would have an incorrect signature (but not sure how important that would be for a privat channel).

2. data:
* [`channel_id`:`channel_id`]

1. type: 268 (`assign_scid_reply`) (`option_scid_assign`)
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Nit: use message type 266 since you appear to be filling the blanks?

02-peer-protocol.md Outdated Show resolved Hide resolved
(see [Assigned `short_channel_id` Forwarding](04-onion-routing.md#assigned-short_channel_id-forwarding)).
and return it in an ``assign_scid_reply` message.
- SHOULD ensure this does not conflict with future `short_channel_id`s.
- MUST discard any previous assigned `short_channel_id` for this channel
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

With this requirement, I don't think we need the unassign_* messages. If they care about privacy, then they will request new scids regularly. (NB: with this proposal we can't have two pending invoices simultaneously with two different scids, I think that's fine).

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think we still want unassign to reduce the chance for probing when you're offline?

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Just send an assign_scid? It has the same effect.

@rustyrussell
Copy link
Collaborator Author

Should a peer also send a fresh channel_update after assign_scid_reply? An old one would have an incorrect signature (but not sure how important that would be for a privat channel).

You can send channel_update for a private channel; we should mention that will always use the original "real" short_channel_id.

rustyrussell and others added 2 commits November 5, 2019 07:04
Co-Authored-By: Pierre-Marie Padiou <pm47@users.noreply.github.com>
1. @pm47 points out we can use number 266.
2. Make it clear that (private) channel_updates use
   the original scid.

Signed-off-by: Rusty Russell <rusty@rustcorp.com.au>
@t-bast
Copy link
Collaborator

t-bast commented Nov 8, 2019

I thought about this some more: you can do this already without revealing to the public node what transient key you're using. Which is even more win!

Can you detail that @rustyrussell? Or is this something you'll add to that PR once you have something ready?

@rustyrussell
Copy link
Collaborator Author

I thought about this some more: you can do this already without revealing to the public node what transient key you're using. Which is even more win!

Can you detail that @rustyrussell? Or is this something you'll add to that PR once you have something ready?

The key Alice uses to decrypt the onion is unknown to her peer Bob anyway. So Alice just tells Mallory an invoice with a made up transient "nodeid".

@t-bast
Copy link
Collaborator

t-bast commented Jan 22, 2020

I have an alternative proposal here: https://lists.linuxfoundation.org/pipermail/lightning-dev/2020-January/002435.html

It has a different set of trade-offs, which I personally prefer :)
I'm interested in getting feedback on whether it makes sense to go down that path or if people prefer the option_scid_assign proposal.

We introduce the id of a per-peer `scid_series`, which is simply
the funding-transaction-based scid in the non-option_scid_assign case.

Otherwise, you can ask for new entries or delete entries in simple operations.

Signed-off-by: Rusty Russell <rusty@rustcorp.com.au>
A recipient which is carefully using separate nodeids and
short_channel_ids for separate invoices needs to know which nodeid to
use with this invoice, otherwise an attacker can try paying one
invoice via another invoice's routehint, and if it succeeds (or gives
any error but invalid_onion_hmac) they can know it was the same
node.

Signed-off-by: Rusty Russell <rusty@rustcorp.com.au>
@rustyrussell
Copy link
Collaborator Author

OK, I'm closing this proposal, in favor of a more powerful blinded paths proposal that @t-bast is working on. This will cover the private channels as well as more general cases.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

random short channel id for private channels
4 participants