Skip to content

Commit

Permalink
Fix and expand channel keypath (#1147)
Browse files Browse the repository at this point in the history
* Fix funding pubkey to channel key path computation

Channel key path is generated from 8 bytes computed from our funding pubkey, but we extracted 4 uint32 values instead of 2 (last 2 were always 0). We now use 128 bits to derive channel key paths.

* Add a channel key path compatibility test

This test will fail if we change the way we compute channel key paths, which would break existing channels.
  • Loading branch information
sstone authored Sep 25, 2019
1 parent 88880c3 commit e11e3e0
Show file tree
Hide file tree
Showing 2 changed files with 11 additions and 3 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -112,7 +112,7 @@ object KeyManager {
* @return a BIP32 path
*/
def channelKeyPath(fundingPubKey: PublicKey) : DeterministicWallet.KeyPath = {
val buffer = fundingPubKey.hash160.take(8)
val buffer = fundingPubKey.hash160.take(16)
val bis = new ByteArrayInputStream(buffer.toArray)
DeterministicWallet.KeyPath(Seq(Protocol.uint32(bis, ByteOrder.BIG_ENDIAN), Protocol.uint32(bis, ByteOrder.BIG_ENDIAN), Protocol.uint32(bis, ByteOrder.BIG_ENDIAN), Protocol.uint32(bis, ByteOrder.BIG_ENDIAN)))
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -16,9 +16,9 @@

package fr.acinq.eclair.crypto

import fr.acinq.bitcoin.{Block, ByteVector32, DeterministicWallet}
import fr.acinq.bitcoin.Crypto.PublicKey
import fr.acinq.bitcoin.Crypto.{PrivateKey, PublicKey}
import fr.acinq.bitcoin.DeterministicWallet.KeyPath
import fr.acinq.bitcoin.{Block, ByteVector32, DeterministicWallet}
import org.scalatest.FunSuite
import scodec.bits._

Expand Down Expand Up @@ -57,4 +57,12 @@ class LocalKeyManagerSpec extends FunSuite {
assert(keyManager1.fundingPublicKey(keyPath) != keyManager2.fundingPublicKey(keyPath))
assert(keyManager1.commitmentPoint(keyPath, 1) != keyManager2.commitmentPoint(keyPath, 1))
}

test("compute channel key path from funding keys") {
// if this test fails it means that we don't generate the same channel key path from the same funding pubkey, which
// will break existing channels !
val pub = PrivateKey(ByteVector32.fromValidHex("01" * 32)).publicKey
val keyPath = KeyManager.channelKeyPath(pub)
assert(keyPath.toString() == "m/2041577608/1982247572/689197082'/1288840885")
}
}

0 comments on commit e11e3e0

Please sign in to comment.