<blockquote>
  <p>So that leaves the per_commitment_point to be figured out, derived from per_commitment_secret. I'm confused where that comes from.</p>
</blockquote>

<p>This comes from the <a href="https://github.com/lightningnetwork/lightning-rfc/blob/master/02-peer-protocol.md#the-open_channel-message" rel="nofollow noreferrer"><code>open_channel/accept_channel</code></a> messages in BOLT2. It is called <code>first_per_commitment_point</code>.</p>

<p>Unfortunately I can't find where you can access this on lnd documentation. </p>

<p>An idea: Look at the lnd backup documentation and try to figure out how that works. <code>per_commitment_secret</code> must be backed up to trustlessly redeem funds. Since it looks like they do not offer easy access to that, you may be able to find it in the backup information.</p>

CC BY-SA 4.0
2019-09-12T15:23:49.267Z
2019-09-12T15:23:49.267Z
Chris Stewart
<p>In c-lightning the per commitment point is derived from the <code>hsm_secret</code> using <a href="https://github.com/ElementsProject/lightning/blob/v0.7.2.1/common/derive_basepoints.h#L122-L130" rel="noreferrer">per_commit_point</a> from:</p>

<ol>
<li>The node id / public key (can be found with <code>listfunds</code>, until the channel is purged some time after closing)</li>
<li>The channel database id (can be found with <code>cat ~/.lightning/debug.log | grep $node_id</code>), shown as <code>chan #$node_id</code></li>
<li>The commitment number (0 when opening the channel, increases during fee negotiations and other channel updates, <code>|  grep commit</code>)</li>
</ol>

<p>We care about the commitment point, not the secret, because the private key we need is derived as follows:</p>

<pre><code>privkey = basepoint_secret + SHA256(per_commitment_point || basepoint)
</code></pre>

<p>I created a tool for c-lightning to dump this point (with help from @cdecker): <a href="https://github.com/ElementsProject/lightning/pull/3115" rel="noreferrer">https://github.com/ElementsProject/lightning/pull/3115</a></p>

<p>Back to Lnd... One easy place to dump a private key is in the <code>lnwallet walletinfo</code> command. Add something like this to <code>commands.go</code>:</p>



<pre><code>basePointSecret, err := keyRing.DerivePrivKey(keychain.KeyDescriptor{
  KeyLocator: keychain.KeyLocator{
    Family: keychain.KeyFamilyPaymentBase,
    Index:  0, // Same commitment index as used in c-lightning 
  },
})

// Parse per_commitment_point dumped by c-lightning:
bytes, err := hex.DecodeString(".........")
commitPoint, err := btcec.ParsePubKey(bytes, btcec.S256())

// Obtain SHA256(per_commitment_point || basepoint)
h := sha256.New()
h.Write(commitPoint.SerializeCompressed())
h.Write(basePointSecret.PubKey().SerializeCompressed())
commitTweak := h.Sum(nil)

// Obtain and dump private key
tweakedPrivkey := TweakPrivKey(basePointSecret, commitTweak)
commitmentWif, err := btcutil.NewWIF(tweakedPrivkey, &amp;chaincfg.MainNetParams, true)

fmt.Printf("Dump commitment priv key: %s\n", commitmentWif)
</code></pre>

<p>Where TweakPrivKey() is lifted from <a href="https://github.com/lightningnetwork/lnd/blob/b1b4aab7792a8a99739ab58265544d41d3255055/input/script_utils.go#L1022" rel="noreferrer">script_utils</a>.</p>

<p>Import the resulting private key into Bitcoin Core et voila!</p>

CC BY-SA 4.0
2019-09-29T18:30:56.273Z
2019-10-18T13:31:16.173Z
2019-10-18T13:31:16.173Z
Sjors Provoost
<p>I lost my Lnd channel backup in a boating accident, but I still have the mnemonic. I had one freshly opened channel to my own c-lightning node which has never been used. I force closed the channel from the c-lightning side.</p>

<p>The funds are now in a P2WPKH address which I've imported into Bitcoin Core. Now I need to figure out the private key in order to sweep it. This requires knowing how to derive it, and then how to dump it.</p>

<p>There is <a href="https://github.com/lightningnetwork/lnd/pull/2373" rel="noreferrer">wallet utility pull request</a> that I could tweak in order to dump the key I need once I know how to derive it.</p>

<p>I also know the funding transaction id, the channel id and all the other channel details c-lightning spits out with <code>listfunds</code>. </p>

<p>Key derivation is explained in <a href="https://github.com/lightningnetwork/lnd/blob/master/keychain/derivation.go" rel="noreferrer">derivation.go</a>:</p>

<pre><code>m/1017'/coinType'/keyFamily'/0/index
</code></pre>

<p>The coinType for Bitcoin is 0, and I believe the key family is 3: "used in scripts that pay directly to us without any delay"</p>

<p>My guess is that the index is 0 since it was the first channel.</p>

<p><a href="https://github.com/lightningnetwork/lightning-rfc/blob/master/03-transactions.md#key-derivation" rel="noreferrer">BOLT 3</a> then explains how to do tweak this key for a commitment transaction. Because the other side closed this channel, I need the <code>to_remote</code> output, which requires the <code>remotepubkey</code>.</p>

<pre><code>pubkey = basepoint + SHA256(per_commitment_point || basepoint) * G 
privkey = basepoint_secret + SHA256(per_commitment_point || basepoint)
</code></pre>

<p>The spec says "the remotepubkey uses the remote node's payment_basepoint". Is that the key we just derived?</p>

<p>So that leaves the <code>per_commitment_point</code> to be figured out, derived from <code>per_commitment_secret</code>. I'm confused where that comes from.</p>

<p><em>What Go incantation should I use to dump the private key I'm looking for?</em></p>

CC BY-SA 4.0
2019-09-03T18:51:53.107Z
I cannot give you the answer out of the box but I wanted to chase down that logic since a long time. if noone finds the answer I would volunteer to have a hangout (or what ever service you prefer) to chase down the derrivation of the the per_commit secretes from the mnemonic seed
Rene Pickhardt
<lightning-network><wallet-recovery><lightning-network-daemon>
How to recover funds from a force-closed Lnd lightning channel?
Sjors Provoost
# How to recover funds from a force-closed Lnd lightning channel?

(Asked by: username_0 on 2019-09-03)

I lost my Lnd channel backup in a boating accident, but I still have the mnemonic. I had one freshly opened channel to my own c-lightning node which has never been used. I force closed the channel from the c-lightning side.

The funds are now in a P2WPKH address which I've imported into Bitcoin Core. Now I need to figure out the private key in order to sweep it. This requires knowing how to derive it, and then how to dump it.

There is [wallet utility pull request](https://github.com/lightningnetwork/lnd/pull/2373) that I could tweak in order to dump the key I need once I know how to derive it.

I also know the funding transaction id, the channel id and all the other channel details c-lightning spits out with `listfunds`.

Key derivation is explained in [derivation.go](https://github.com/lightningnetwork/lnd/blob/master/keychain/derivation.go):

```
m/1017'/coinType'/keyFamily'/0/index

```

The coinType for Bitcoin is 0, and I believe the key family is 3: "used in scripts that pay directly to us without any delay"

My guess is that the index is 0 since it was the first channel.

[BOLT 3](https://github.com/lightningnetwork/lightning-rfc/blob/master/03-transactions.md#key-derivation) then explains how to do tweak this key for a commitment transaction. Because the other side closed this channel, I need the `to_remote` output, which requires the `remotepubkey`.

```
pubkey = basepoint + SHA256(per_commitment_point || basepoint) * G 
privkey = basepoint_secret + SHA256(per_commitment_point || basepoint)

```

The spec says "the remotepubkey uses the remote node's payment\_basepoint". Is that the key we just derived?

So that leaves the `per_commitment_point` to be figured out, derived from `per_commitment_secret`. I'm confused where that comes from.

*What Go incantation should I use to dump the private key I'm looking for?*

**Tags:** lightning-network, wallet-recovery, lightning-network-daemon

> **Comments:**
> **username_1**: I cannot give you the answer out of the box but I wanted to chase down that logic since a long time. if noone finds the answer I would volunteer to have a hangout (or what ever service you prefer) to chase down the derrivation of the the per_commit secretes from the mnemonic seed  

---

## 2 answers

### Answer by username_0 on 2019-09-29. Score: 5 | Accepted answer

In c-lightning the per commitment point is derived from the `hsm_secret` using [per\_commit\_point](https://github.com/ElementsProject/lightning/blob/v0.7.2.1/common/derive_basepoints.h#L122-L130) from:

1. The node id / public key (can be found with `listfunds`, until the channel is purged some time after closing)
2. The channel database id (can be found with `cat ~/.lightning/debug.log | grep $node_id`), shown as `chan #$node_id`
3. The commitment number (0 when opening the channel, increases during fee negotiations and other channel updates, `| grep commit`)

We care about the commitment point, not the secret, because the private key we need is derived as follows:

```
privkey = basepoint_secret + SHA256(per_commitment_point || basepoint)

```

I created a tool for c-lightning to dump this point (with help from @cdecker): <https://github.com/ElementsProject/lightning/pull/3115>

Back to Lnd... One easy place to dump a private key is in the `lnwallet walletinfo` command. Add something like this to `commands.go`:

```
basePointSecret, err := keyRing.DerivePrivKey(keychain.KeyDescriptor{
  KeyLocator: keychain.KeyLocator{
    Family: keychain.KeyFamilyPaymentBase,
    Index:  0, // Same commitment index as used in c-lightning 
  },
})

// Parse per_commitment_point dumped by c-lightning:
bytes, err := hex.DecodeString(".........")
commitPoint, err := btcec.ParsePubKey(bytes, btcec.S256())

// Obtain SHA256(per_commitment_point || basepoint)
h := sha256.New()
h.Write(commitPoint.SerializeCompressed())
h.Write(basePointSecret.PubKey().SerializeCompressed())
commitTweak := h.Sum(nil)

// Obtain and dump private key
tweakedPrivkey := TweakPrivKey(basePointSecret, commitTweak)
commitmentWif, err := btcutil.NewWIF(tweakedPrivkey, &chaincfg.MainNetParams, true)

fmt.Printf("Dump commitment priv key: %s\n", commitmentWif)

```

Where TweakPrivKey() is lifted from [script\_utils](https://github.com/lightningnetwork/lnd/blob/b1b4aab7792a8a99739ab58265544d41d3255055/input/script_utils.go#L1022).

Import the resulting private key into Bitcoin Core et voila!


---

### Answer by username_2 on 2019-09-12. Score: 0

> So that leaves the per\_commitment\_point to be figured out, derived from per\_commitment\_secret. I'm confused where that comes from.

This comes from the [`open_channel/accept_channel`](https://github.com/lightningnetwork/lightning-rfc/blob/master/02-peer-protocol.md#the-open_channel-message) messages in BOLT2. It is called `first_per_commitment_point`.

Unfortunately I can't find where you can access this on lnd documentation.

An idea: Look at the lnd backup documentation and try to figure out how that works. `per_commitment_secret` must be backed up to trustlessly redeem funds. Since it looks like they do not offer easy access to that, you may be able to find it in the backup information.


---

