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

Make lightning privkey derivation totally random to prevent collisions #5966

Closed
ecdsa opened this issue Feb 14, 2020 · 6 comments
Closed

Make lightning privkey derivation totally random to prevent collisions #5966

ecdsa opened this issue Feb 14, 2020 · 6 comments

Comments

@ecdsa
Copy link
Member

ecdsa commented Feb 14, 2020

No description provided.

@ecdsa ecdsa added this to the 4.0 milestone Feb 14, 2020
@SomberNight
Copy link
Member

SomberNight commented Feb 14, 2020

I have made some notes a while ago about this. dumping here:

ln keys derivation:

  • instead of global counter, generate funding privkey randomly,
    • derive all other keys from funding pubkey (+seed)
  • with current key derivation we use (global counter),
    • if user restores from an old backup (copied file at least), we will reuse keys, which can lead to fund loss... (even with up to date wallet-file-copy)
  • if we derived the LN keys directly from seed
    • if user used same seed on two different devices, e.g. phone and laptop. we would reuse keys...

related: ACINQ/eclair@bf3fd32
ACINQ/eclair#1093
ACINQ/eclair#1097

@ecdsa ecdsa self-assigned this Feb 19, 2020
@ecdsa
Copy link
Member Author

ecdsa commented Feb 19, 2020

Looking at the code again, the risk is not as high as it seems.

  • The root xprv passed to LNWorker is already random. It is thus safe to use the same seed on two different devices.
  • if the user opens a backup file, the 'is_backup' flag will prevent channel creation.
  • if the user opens a copied file (without the backup flag), then indeed the same key might be used in a new channel. However, in that situation we have bigger problems, because they are also going to broadcast old states for their existing channels...

@ecdsa
Copy link
Member Author

ecdsa commented Feb 21, 2020

implemented in 55e0e1a

@ecdsa
Copy link
Member Author

ecdsa commented Feb 21, 2020

Notes regarding disaster recovery and DLP:

  • if the remote node is here:
    • without static_remotekey, the backup file is critical. It is needed to perform DLP and spend the to_remote output.
    • with static_remotekey, the backup only helps to speed up recovery using DLP.
  • if the remote is not here, the backup is needed to force-close (but that is risky, we might broadcast an old state).

Thus, I believe we should require static_remotekey. (and yes, 40% is plenty)

Note that what Eclair does (channel keys are derived from the funding_pubkey) allows recovery of to_remote without using one of the wallet pubkeys in static_remotekey. If we did that, we could enable lightning in non-p2wpk wallets.

@ecdsa
Copy link
Member Author

ecdsa commented Feb 21, 2020

To follow-up on yesterday's discussion, I think I have found a way to perform disaster recovery from mnemonic seed only (without a backup file, and without op_return data in the blockchain). The idea is that we do not need to remember the remote node_id, because 'they will contact us'.

  • we assume that our node_id is deterministic
  • we create a lightning disaster recovery mode, enabled by the user.
  • In disaster recovery mode, we announce our node in the gossip, and we accept incoming connections.
  • nodes that have a channel with us will contact us and send us channel_reestablish
  • we reply with ctn 0, so that they force close
  • with static_remotekey, there is nothing to do
  • without static_remotekey, they send us a pcp. we would need to derive the payment_basepoint deterministically from funding_pubkey, (what Eclair does)

We need to make sure that we can use the same node_id on two devices, when the disaster recovery mode is not enabled. In that case we should probably ignore channel_reestablish messages, or disconnect (no idea if that would work, it needs to be tested).

@ecdsa ecdsa closed this as completed Feb 21, 2020
@ecdsa ecdsa reopened this Feb 21, 2020
@ecdsa ecdsa closed this as completed Feb 21, 2020
@SomberNight
Copy link
Member

SomberNight commented Feb 21, 2020

In disaster recovery mode, we announce our node in the gossip, and we accept incoming connections.

Two things:

  • due to widespread NAT on consumer devices, it's often non-trivial to listen on a port
  • according to the BOLTs, as a counter-spam measure, a node needs to have at least one publicly announced channel before its node announcement will be propagated
    • and it does not seem possible to me to "upgrade" a private channel to a public one

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

No branches or pull requests

2 participants