ZmnSCPxj [ARCHIVE] on Nostr: 📅 Original date posted:2020-02-03 📝 Original message: Good morning Rusty, > ...
📅 Original date posted:2020-02-03
📝 Original message:
Good morning Rusty,
> Bastien TEINTURIER bastien at acinq.fr writes:
>
> > We can easily get rid of (1.) by leveraging the `payment_secret`. The
> > improved scheme is:
> >
> > - Alice draws a random `decoy_key`
> > - Alice computes the corresponding `decoy_node_id = decoy_key * G`
> > - Alice draws a random `payment_secret`
> > - Alice computes `decoy_short_channel_id = H(payment_secret * decoy_key * bob_node_id) xor short_channel_id`
> > - Alice uses the `decoy_key` to sign the invoice
> > - Carol recovers `decoy_node_id` from the invoice signature
> > - Carol includes `P_I = payment_secret * decoy_node_id` in the onion
> > payload for Bob
> >
> > - Bob can compute `short_channel_id = H(bob_private_key * P_I) xor decoy_short_channel_id`
> >
> > But I don't see how to get rid of (2.). If anyone has a clever idea on how
> > to do that, I'd love to hear it!
>
> I really don't want a special marker on Carol; she needs to just pay
> like normal. Not just because it's simple, but because it means that
> Carol can use a custodial wallet without having to flag the payment as
> somehow special.
>
> AFAICT, having Bob assign scids is the only viable way to do this. The
> current proposal limits to one scid at a time, but it could be extended
> to allow multiple scids.
>
> (I'm seeking a clever way that Bob can assign them and trivially tell
> which ID is assigned to which peer, but I can't figure it out, so I
> guess Bob keeps a mapping and restricts each peer to 256 live scids?).
We can observe that short-channel-ids have a 24-bit blocknum, but it is exceedingly unlikely that for most blockchains, the genesis block will have a Lightning network channel.
So we could reserve blocknum=0 to identify special SCIDs.
The rest of the SCID could refer to the lowest 40 bits of the X-coord of the node ID that is the destination.
We should remember that short channel IDs are used as a convenient way to refer to the next *node* and not the next channel in the onion routing (which is why in Adelaide 2018 we decided to make short channel IDs "advisory", implementation that support multiple channels per peer can use any channel with that peer to forward, not just the specific SCID indicated in the onion).
Now, 40 bits is not a lot, but we can observe that for almost all git repositories, 7 or 8 hex digits is usually enough to unambiguously identify a commit within the repository, even for git repositories with thousands of commits, and 8 hex digits is just 32 bits of identification.
So it seems to me that Bob could just look up the 40 bit identifier to each of the nodes with unpublished channels with it, and this will work well up to Bob having a few thousand peers with unpublished channels.
If we focus on Bitcoin specifically, we can observe as well that `when_lightning_became_cool` is well above 262144 (2^18 ) so we can steal 18 more bits from the blocknum, i.e. if none of the top 6 bits of blocknum are set (blocknum < 262144), then the lower 58 bits of the blockid are the lowest 58 bits of the node ID of the next hop.
Though obviously that is not as good for regtest and testnet, do note that, assuming a non-premined blockchain with a similar 100-block maturity for coinbases, we could still steal 6 bits (blocknum < 64), since no Lightning channel can occur on the first 100 blocks anyway due to the maturity requirement (there *are* no coins that can be spent before then, so no Lightning channels can be created then).
Admittedly, if somebody knows your node id, they need only 40 bits of work to grind a node id of their own whose last 40 bits matches yours, then connect to the same public node you are on.
In that case, it becomes ambiguous for Bob which of the nodes it should send the last hop to, so it could just try them one by one (trying them in parallel risks Bob getting ripped off by an attacker who specifically generates multiple nodes with the same lower bits in the node ID).
Or Bob could just reject future channels from nodes whose lower bits match that with something already channeled with it.
Finally, in this context, this is intended to be used for nodes with unpublished channels.
Of note is that the second-to-the-last node already knows the exact identity, timing, and amount of every payment to the last node anyway, because unpublished channels are not private.
So in this particular case, the second-to-the-last node can actually just drop the payer onion, and replace it with its own onion to the final node.
This is relevant if we ever want to hide the node id of the last node: Bob could provide a symmetric encryption key to all its peers with unpublished channels, which the peer can XOR with its own true node id and use the lowest 40 bits (or 46 bits or 58 bits) in the SCID.
Then when Bob receives an onion whose next SCID has the top 24 or 18 or 6 bits set to 0, it can XOR the symmetric key to the lower bits and then determine the lowest bits of the node id of the last node, and it can then replace the outgoing onion with the corrected onion to that node.
The last node cannot use the payment secret (invoice secret), but that is not going to protect against probe attacks from a public node to a completely unpublished node anyway.
Also the last node cannot receive any data via this method (because the onion is replaced by Bob) but for simple pay-for-preimage applications this will work perfectly fine.
It strikes me as well that a C-Lightning plugin can actually implement this due to `htlc_accepted` hook.
Regards,
ZmnSCPxj
Published at
2023-06-09 12:58:31Event JSON
{
"id": "815e56ad0606949b09cae99342de7cd2c03680264a9530f10ae786fc3f1b7328",
"pubkey": "4505072744a9d3e490af9262bfe38e6ee5338a77177b565b6b37730b63a7b861",
"created_at": 1686315511,
"kind": 1,
"tags": [
[
"e",
"3ed35742512a6038c8a47910d5915af4fefd8766015db6ab01e4ef19d4ac6fff",
"",
"root"
],
[
"e",
"c614bffbb8a6667b46246b684911c8e1fd168b457e0f215cf4dfee63e7ea0e41",
"",
"reply"
],
[
"p",
"13bd8c1c5e3b3508a07c92598647160b11ab0deef4c452098e223e443c1ca425"
]
],
"content": "📅 Original date posted:2020-02-03\n📝 Original message:\nGood morning Rusty,\n\n\u003e Bastien TEINTURIER bastien at acinq.fr writes:\n\u003e\n\u003e \u003e We can easily get rid of (1.) by leveraging the `payment_secret`. The\n\u003e \u003e improved scheme is:\n\u003e \u003e\n\u003e \u003e - Alice draws a random `decoy_key`\n\u003e \u003e - Alice computes the corresponding `decoy_node_id = decoy_key * G`\n\u003e \u003e - Alice draws a random `payment_secret`\n\u003e \u003e - Alice computes `decoy_short_channel_id = H(payment_secret * decoy_key * bob_node_id) xor short_channel_id`\n\u003e \u003e - Alice uses the `decoy_key` to sign the invoice\n\u003e \u003e - Carol recovers `decoy_node_id` from the invoice signature\n\u003e \u003e - Carol includes `P_I = payment_secret * decoy_node_id` in the onion\n\u003e \u003e payload for Bob\n\u003e \u003e\n\u003e \u003e - Bob can compute `short_channel_id = H(bob_private_key * P_I) xor decoy_short_channel_id`\n\u003e \u003e\n\u003e \u003e But I don't see how to get rid of (2.). If anyone has a clever idea on how\n\u003e \u003e to do that, I'd love to hear it!\n\u003e\n\u003e I really don't want a special marker on Carol; she needs to just pay\n\u003e like normal. Not just because it's simple, but because it means that\n\u003e Carol can use a custodial wallet without having to flag the payment as\n\u003e somehow special.\n\u003e\n\u003e AFAICT, having Bob assign scids is the only viable way to do this. The\n\u003e current proposal limits to one scid at a time, but it could be extended\n\u003e to allow multiple scids.\n\u003e\n\u003e (I'm seeking a clever way that Bob can assign them and trivially tell\n\u003e which ID is assigned to which peer, but I can't figure it out, so I\n\u003e guess Bob keeps a mapping and restricts each peer to 256 live scids?).\n\nWe can observe that short-channel-ids have a 24-bit blocknum, but it is exceedingly unlikely that for most blockchains, the genesis block will have a Lightning network channel.\n\nSo we could reserve blocknum=0 to identify special SCIDs.\n\nThe rest of the SCID could refer to the lowest 40 bits of the X-coord of the node ID that is the destination.\nWe should remember that short channel IDs are used as a convenient way to refer to the next *node* and not the next channel in the onion routing (which is why in Adelaide 2018 we decided to make short channel IDs \"advisory\", implementation that support multiple channels per peer can use any channel with that peer to forward, not just the specific SCID indicated in the onion).\nNow, 40 bits is not a lot, but we can observe that for almost all git repositories, 7 or 8 hex digits is usually enough to unambiguously identify a commit within the repository, even for git repositories with thousands of commits, and 8 hex digits is just 32 bits of identification.\nSo it seems to me that Bob could just look up the 40 bit identifier to each of the nodes with unpublished channels with it, and this will work well up to Bob having a few thousand peers with unpublished channels.\n\nIf we focus on Bitcoin specifically, we can observe as well that `when_lightning_became_cool` is well above 262144 (2^18 ) so we can steal 18 more bits from the blocknum, i.e. if none of the top 6 bits of blocknum are set (blocknum \u003c 262144), then the lower 58 bits of the blockid are the lowest 58 bits of the node ID of the next hop.\nThough obviously that is not as good for regtest and testnet, do note that, assuming a non-premined blockchain with a similar 100-block maturity for coinbases, we could still steal 6 bits (blocknum \u003c 64), since no Lightning channel can occur on the first 100 blocks anyway due to the maturity requirement (there *are* no coins that can be spent before then, so no Lightning channels can be created then).\n\n\nAdmittedly, if somebody knows your node id, they need only 40 bits of work to grind a node id of their own whose last 40 bits matches yours, then connect to the same public node you are on.\nIn that case, it becomes ambiguous for Bob which of the nodes it should send the last hop to, so it could just try them one by one (trying them in parallel risks Bob getting ripped off by an attacker who specifically generates multiple nodes with the same lower bits in the node ID).\nOr Bob could just reject future channels from nodes whose lower bits match that with something already channeled with it.\n\n\nFinally, in this context, this is intended to be used for nodes with unpublished channels.\nOf note is that the second-to-the-last node already knows the exact identity, timing, and amount of every payment to the last node anyway, because unpublished channels are not private.\nSo in this particular case, the second-to-the-last node can actually just drop the payer onion, and replace it with its own onion to the final node.\nThis is relevant if we ever want to hide the node id of the last node: Bob could provide a symmetric encryption key to all its peers with unpublished channels, which the peer can XOR with its own true node id and use the lowest 40 bits (or 46 bits or 58 bits) in the SCID.\nThen when Bob receives an onion whose next SCID has the top 24 or 18 or 6 bits set to 0, it can XOR the symmetric key to the lower bits and then determine the lowest bits of the node id of the last node, and it can then replace the outgoing onion with the corrected onion to that node.\nThe last node cannot use the payment secret (invoice secret), but that is not going to protect against probe attacks from a public node to a completely unpublished node anyway.\nAlso the last node cannot receive any data via this method (because the onion is replaced by Bob) but for simple pay-for-preimage applications this will work perfectly fine.\n\n\nIt strikes me as well that a C-Lightning plugin can actually implement this due to `htlc_accepted` hook.\n\n\nRegards,\nZmnSCPxj",
"sig": "e18409d500032c146b5009a2f7327790e82008dc4d20be9dc7b39ddc9b69b112f081ea2bcf7f27696c7dfea77295b0b32268195ccf5101cd7a1cc3345e274635"
}