diff --git a/eclair-core/src/main/scala/fr/acinq/eclair/channel/fsm/Channel.scala b/eclair-core/src/main/scala/fr/acinq/eclair/channel/fsm/Channel.scala index 0348b81de8..42d559fcc3 100644 --- a/eclair-core/src/main/scala/fr/acinq/eclair/channel/fsm/Channel.scala +++ b/eclair-core/src/main/scala/fr/acinq/eclair/channel/fsm/Channel.scala @@ -667,7 +667,7 @@ class Channel(val nodeParams: NodeParams, val wallet: OnChainChannelFunder with val finalScriptPubKey = getOrGenerateFinalScriptPubKey(d) val tlvStream: TlvStream[ShutdownTlv] = if (d.commitments.params.commitmentFormat.useTaproot) { log.info("generating closing nonce {} with fundingKeyPath = {} fundingTxIndex = {}", closingNonce, d.commitments.latest.localParams.fundingKeyPath, d.commitments.latest.fundingTxIndex) - closingNonce = Some(keyManager.closingNonce(d.commitments.latest.localParams.fundingKeyPath, d.commitments.latest.fundingTxIndex)) + closingNonce = Some(keyManager.signingNonce(d.commitments.latest.localParams.fundingKeyPath, d.commitments.latest.fundingTxIndex)) TlvStream(ShutdownTlv.ShutdownNonce(closingNonce.get._2)) } else { TlvStream.empty @@ -700,7 +700,7 @@ class Channel(val nodeParams: NodeParams, val wallet: OnChainChannelFunder with case Right(localShutdownScript) => val tlvStream: TlvStream[ShutdownTlv] = if (d.commitments.params.commitmentFormat.useTaproot) { log.info("generating closing nonce {} with fundingKeyPath = {} fundingTxIndex = {}", closingNonce, d.commitments.latest.localParams.fundingKeyPath, d.commitments.latest.fundingTxIndex) - closingNonce = Some(keyManager.closingNonce(d.commitments.latest.localParams.fundingKeyPath, d.commitments.latest.fundingTxIndex)) + closingNonce = Some(keyManager.signingNonce(d.commitments.latest.localParams.fundingKeyPath, d.commitments.latest.fundingTxIndex)) TlvStream(ShutdownTlv.ShutdownNonce(closingNonce.get._2)) } else { TlvStream.empty @@ -759,7 +759,7 @@ class Channel(val nodeParams: NodeParams, val wallet: OnChainChannelFunder with case None => val tlvStream: TlvStream[ShutdownTlv] = if (d.commitments.params.commitmentFormat.useTaproot) { log.info("generating closing nonce {} with fundingKeyPath = {} fundingTxIndex = {}", closingNonce, d.commitments.latest.localParams.fundingKeyPath, d.commitments.latest.fundingTxIndex) - closingNonce = Some(keyManager.closingNonce(d.commitments.latest.localParams.fundingKeyPath, d.commitments.latest.fundingTxIndex)) + closingNonce = Some(keyManager.signingNonce(d.commitments.latest.localParams.fundingKeyPath, d.commitments.latest.fundingTxIndex)) TlvStream(ShutdownTlv.ShutdownNonce(closingNonce.get._2)) } else { TlvStream.empty diff --git a/eclair-core/src/main/scala/fr/acinq/eclair/crypto/keymanager/ChannelKeyManager.scala b/eclair-core/src/main/scala/fr/acinq/eclair/crypto/keymanager/ChannelKeyManager.scala index 9584b18e0d..0db4e10593 100644 --- a/eclair-core/src/main/scala/fr/acinq/eclair/crypto/keymanager/ChannelKeyManager.scala +++ b/eclair-core/src/main/scala/fr/acinq/eclair/crypto/keymanager/ChannelKeyManager.scala @@ -43,12 +43,27 @@ trait ChannelKeyManager { def commitmentPoint(channelKeyPath: DeterministicWallet.KeyPath, index: Long): Crypto.PublicKey + /** + * Create a deterministic verification nonce for a specific funding private key and commit tx index. The public nonce will be sent to our peer to create a partial signature + * of our commit tx, the private nonce is never shared (and never serialized or stored) and is used to create our local partial signature to be combined with our peer's. + * @param fundingKeyPath funding key path + * @param fundingTxIndex funding tx index + * @param channelKeyPath channel key path + * @param index commit tx index + * @return a verification nonce that is used to create a partial musig2 signature for our commit tx. + */ def verificationNonce(fundingKeyPath: DeterministicWallet.KeyPath, fundingTxIndex: Long, channelKeyPath: DeterministicWallet.KeyPath, index: Long): (SecretNonce, IndividualNonce) + /** + * Create a new, randomized singing nonce for a specific funding private key. These nonces are used to create a partial musig2 signature for our peer's commit tx and are sent + * alongside the partial signature. They are created on the fly, and never stored. + * @param fundingKeyPath funding key path + * @param fundingTxIndex funding tx index + * @return a signing nonce that can be used to create a musig2 signature with the funding private key that matches the provided key path and key index. + * Each call to this methode will return a different, randomized signing nonce. + */ def signingNonce(fundingKeyPath: DeterministicWallet.KeyPath, fundingTxIndex: Long): (SecretNonce, IndividualNonce) - def closingNonce(fundingKeyPath: DeterministicWallet.KeyPath, fundingTxIndex: Long): (SecretNonce, IndividualNonce) - def keyPath(localParams: LocalParams, channelConfig: ChannelConfig): DeterministicWallet.KeyPath = { if (channelConfig.hasOption(ChannelConfig.FundingPubKeyBasedChannelKeyPath)) { // deterministic mode: use the funding pubkey to compute the channel key path diff --git a/eclair-core/src/main/scala/fr/acinq/eclair/crypto/keymanager/LocalChannelKeyManager.scala b/eclair-core/src/main/scala/fr/acinq/eclair/crypto/keymanager/LocalChannelKeyManager.scala index e4e463bd39..1d4ec6b393 100644 --- a/eclair-core/src/main/scala/fr/acinq/eclair/crypto/keymanager/LocalChannelKeyManager.scala +++ b/eclair-core/src/main/scala/fr/acinq/eclair/crypto/keymanager/LocalChannelKeyManager.scala @@ -117,12 +117,6 @@ class LocalChannelKeyManager(seed: ByteVector, chainHash: BlockHash) extends Cha Musig2.generateNonce(sessionId, fundingPrivateKey.privateKey, Seq(fundingPrivateKey.publicKey)) } - override def closingNonce(fundingKeyPath: KeyPath, fundingTxIndex: Long): (SecretNonce, IndividualNonce) = { - val fundingPrivateKey = privateKeys.get(internalKeyPath(fundingKeyPath, hardened(fundingTxIndex))) - val sessionId = randomBytes32() - Musig2.generateNonce(sessionId, fundingPrivateKey.privateKey, Seq(fundingPrivateKey.publicKey)) - } - /** * @param tx input transaction * @param publicKey extended public key