1
0
Fork 0
mirror of https://github.com/ACINQ/eclair.git synced 2025-03-12 19:01:39 +01:00

Add support for kmp node key generation

This is needed for the migration to kmp
This commit is contained in:
dpad85 2022-03-24 17:29:19 +01:00
parent cad5b2a546
commit defc917dbc
No known key found for this signature in database
GPG key ID: 574C8C6A1673E987
3 changed files with 20 additions and 1 deletions

View file

@ -31,6 +31,8 @@ trait KeyManager {
def nodeId: PublicKey
def kmpNodeKey: DeterministicWallet.ExtendedPrivateKey
def fundingPublicKey(keyPath: DeterministicWallet.KeyPath): ExtendedPublicKey
def revocationPoint(channelKeyPath: DeterministicWallet.KeyPath): ExtendedPublicKey

View file

@ -40,6 +40,14 @@ object LocalKeyManager {
case Block.RegtestGenesisBlock.hash | Block.TestnetGenesisBlock.hash => DeterministicWallet.hardened(46) :: DeterministicWallet.hardened(0) :: Nil
case Block.LivenetGenesisBlock.hash => DeterministicWallet.hardened(47) :: DeterministicWallet.hardened(0) :: Nil
}
// WARNING: if you change this path, you will change your node id even if the seed remains the same!!!
// Note that the node path and the above channel path are on different branches so even if the
// node key is compromised there is no way to retrieve the wallet keys
def kmpNodeKeyBasePath(chainHash: ByteVector32) = (chainHash: @unchecked) match {
case Block.RegtestGenesisBlock.hash | Block.TestnetGenesisBlock.hash => DeterministicWallet.hardened(48) :: DeterministicWallet.hardened(0) :: Nil
case Block.LivenetGenesisBlock.hash => DeterministicWallet.hardened(50) :: DeterministicWallet.hardened(0) :: Nil
}
}
/**
@ -53,6 +61,7 @@ class LocalKeyManager(seed: ByteVector, chainHash: ByteVector32) extends KeyMana
override val nodeKey = DeterministicWallet.derivePrivateKey(master, LocalKeyManager.nodeKeyBasePath(chainHash))
override val nodeId = nodeKey.publicKey
override val kmpNodeKey = DeterministicWallet.derivePrivateKey(master, LocalKeyManager.kmpNodeKeyBasePath(chainHash))
private val privateKeys: LoadingCache[KeyPath, ExtendedPrivateKey] = CacheBuilder.newBuilder()
.maximumSize(6 * 200) // 6 keys per channel * 200 channels

View file

@ -18,7 +18,7 @@ package fr.acinq.eclair.crypto
import fr.acinq.bitcoin.scala.Crypto.{PrivateKey, PublicKey}
import fr.acinq.bitcoin.scala.DeterministicWallet.KeyPath
import fr.acinq.bitcoin.scala.{Block, ByteVector32, DeterministicWallet}
import fr.acinq.bitcoin.scala.{Block, ByteVector32, DeterministicWallet, MnemonicCode}
import fr.acinq.eclair.TestConstants
import fr.acinq.eclair.channel.ChannelVersion
import org.scalatest.funsuite.AnyFunSuite
@ -34,6 +34,14 @@ class LocalKeyManagerSpec extends AnyFunSuite {
assert(keyManager.nodeId == PublicKey(hex"02a051267759c3a149e3e72372f4e0c4054ba597ebfd0eda78a2273023667205ee"))
}
test("generate the same KMP node id from the same seed") {
// if this test breaks it means that we will generate a different KMP node id from
// the same seed, which could be a problem during migration from eclair-core to kmp
val seed = MnemonicCode.toSeed("sock able evoke work output half bamboo energy simple fiber unhappy afford", passphrase = "")
val keyManager = new LocalKeyManager(seed, Block.TestnetGenesisBlock.hash)
assert(keyManager.kmpNodeKey.publicKey == PublicKey(hex"022b49d4ab3342ada31d79d2a57ceaa2e8f573277552a44433bc8a4ee5b945085d"))
}
test("generate the same secrets from the same seed") {
// data was generated with eclair 0.3
val seed = hex"17b086b228025fa8f4416324b6ba2ec36e68570ae2fc3d392520969f2a9d0c1501"