Skip to content

Commit b11558f

Browse files
committed
Rework nonce generation
1 parent 5547f41 commit b11558f

File tree

10 files changed

+143
-80
lines changed

10 files changed

+143
-80
lines changed

eclair-core/src/main/scala/fr/acinq/eclair/channel/Commitments.scala

Lines changed: 19 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -247,7 +247,7 @@ case class LocalCommit(index: Long, spec: CommitmentSpec, commitTxAndRemoteSig:
247247
object LocalCommit {
248248
def fromCommitSig(keyManager: ChannelKeyManager, params: ChannelParams, fundingTxId: TxId,
249249
fundingTxIndex: Long, remoteFundingPubKey: PublicKey, commitInput: InputInfo,
250-
commit: CommitSig, localCommitIndex: Long, spec: CommitmentSpec, localPerCommitmentPoint: PublicKey, localNonce_opt: Option[(SecretNonce, IndividualNonce)])(implicit log: LoggingAdapter): Either[ChannelException, LocalCommit] = {
250+
commit: CommitSig, localCommitIndex: Long, spec: CommitmentSpec, localPerCommitmentPoint: PublicKey)(implicit log: LoggingAdapter): Either[ChannelException, LocalCommit] = {
251251
val (localCommitTx, htlcTxs) = Commitment.makeLocalTxs(keyManager, params.channelConfig, params.channelFeatures, localCommitIndex, params.localParams, params.remoteParams, fundingTxIndex, remoteFundingPubKey, commitInput, localPerCommitmentPoint, spec)
252252
commit.sigOrPartialSig match {
253253
case Left(sig) =>
@@ -256,12 +256,9 @@ object LocalCommit {
256256
}
257257
case Right(psig) =>
258258
val fundingPubkey = keyManager.fundingPublicKey(params.localParams.fundingKeyPath, fundingTxIndex).publicKey
259-
val Some(localNonce) = localNonce_opt
259+
val localNonce = keyManager.verificationNonce(fundingPubkey, localCommitIndex)
260260
if (!localCommitTx.checkPartialSignature(psig, fundingPubkey, localNonce._2, remoteFundingPubKey)) {
261261
log.debug(s"fromCommitSig: invalid partial signature $psig fundingPubkey = $fundingPubkey, fundingTxIndex = $fundingTxIndex localCommitIndex = $localCommitIndex localNonce = $localNonce remoteFundingPubKey = $remoteFundingPubKey")
262-
263-
val localNonce1 = keyManager.verificationNonce(params.localParams.fundingKeyPath, fundingTxIndex, keyManager.keyPath(params.localParams, params.channelConfig), localCommitIndex)
264-
log.debug(s"with $localNonce1 ${localCommitTx.checkPartialSignature(psig, fundingPubkey, localNonce1._2, remoteFundingPubKey)}")
265262
return Left(InvalidCommitmentSignature(params.channelId, fundingTxId, fundingTxIndex, localCommitTx.tx))
266263
}
267264
}
@@ -289,15 +286,16 @@ object LocalCommit {
289286
case class RemoteCommit(index: Long, spec: CommitmentSpec, txid: TxId, remotePerCommitmentPoint: PublicKey) {
290287
def sign(keyManager: ChannelKeyManager, params: ChannelParams, fundingTxIndex: Long, remoteFundingPubKey: PublicKey, commitInput: InputInfo, remoteNonce_opt: Option[IndividualNonce])(implicit log: LoggingAdapter): CommitSig = {
291288
val (remoteCommitTx, htlcTxs) = Commitment.makeRemoteTxs(keyManager, params.channelConfig, params.channelFeatures, index, params.localParams, params.remoteParams, fundingTxIndex, remoteFundingPubKey, commitInput, remotePerCommitmentPoint, spec)
289+
val localFundingPubKey = keyManager.fundingPublicKey(params.localParams.fundingKeyPath, fundingTxIndex)
292290
val (sig, tlvStream) = if (params.commitmentFormat.useTaproot) {
293-
val localNonce = keyManager.signingNonce(params.localParams.fundingKeyPath, fundingTxIndex)
291+
val localNonce = keyManager.signingNonce(localFundingPubKey.publicKey)
294292
val Some(remoteNonce) = remoteNonce_opt
295-
val Right(localPartialSigOfRemoteTx) = keyManager.partialSign(remoteCommitTx, keyManager.fundingPublicKey(params.localParams.fundingKeyPath, fundingTxIndex), remoteFundingPubKey, TxOwner.Remote, localNonce, remoteNonce)
293+
val Right(localPartialSigOfRemoteTx) = keyManager.partialSign(remoteCommitTx, localFundingPubKey, remoteFundingPubKey, TxOwner.Remote, localNonce, remoteNonce)
296294
log.debug(s"RemoteCommit.sign localPartialSigOfRemoteTx = $localPartialSigOfRemoteTx fundingTxIndex = $fundingTxIndex remote commit index = $index remote nonce = $remoteNonce")
297295
val tlvStream: TlvStream[CommitSigTlv] = TlvStream(CommitSigTlv.PartialSignatureWithNonceTlv(PartialSignatureWithNonce(localPartialSigOfRemoteTx, localNonce._2)))
298296
(ByteVector64.Zeroes, tlvStream)
299297
} else {
300-
val sig = keyManager.sign(remoteCommitTx, keyManager.fundingPublicKey(params.localParams.fundingKeyPath, fundingTxIndex), TxOwner.Remote, params.commitmentFormat)
298+
val sig = keyManager.sign(remoteCommitTx, localFundingPubKey, TxOwner.Remote, params.commitmentFormat)
301299
(sig, TlvStream[CommitSigTlv]())
302300
}
303301
val channelKeyPath = keyManager.keyPath(params.localParams, params.channelConfig)
@@ -703,15 +701,16 @@ case class Commitment(fundingTxIndex: Long,
703701
// remote commitment will include all local proposed changes + remote acked changes
704702
val spec = CommitmentSpec.reduce(remoteCommit.spec, changes.remoteChanges.acked, changes.localChanges.proposed)
705703
val (remoteCommitTx, htlcTxs) = Commitment.makeRemoteTxs(keyManager, params.channelConfig, params.channelFeatures, remoteCommit.index + 1, params.localParams, params.remoteParams, fundingTxIndex, remoteFundingPubKey, commitInput, remoteNextPerCommitmentPoint, spec)
704+
val localFundingPubKey = keyManager.fundingPublicKey(params.localParams.fundingKeyPath, fundingTxIndex)
706705
val sig = if (params.commitmentFormat.useTaproot) {
707706
ByteVector64.Zeroes
708707
} else {
709-
keyManager.sign(remoteCommitTx, keyManager.fundingPublicKey(params.localParams.fundingKeyPath, fundingTxIndex), TxOwner.Remote, params.commitmentFormat)
708+
keyManager.sign(remoteCommitTx, localFundingPubKey, TxOwner.Remote, params.commitmentFormat)
710709
}
711710
val partialSig: Set[CommitSigTlv] = if (params.commitmentFormat.useTaproot) {
712-
val localNonce = keyManager.signingNonce(params.localParams.fundingKeyPath, fundingTxIndex)
711+
val localNonce = keyManager.signingNonce(localFundingPubKey.publicKey)
713712
val Some(remoteNonce) = nextRemoteNonce_opt
714-
val Right(psig) = keyManager.partialSign(remoteCommitTx, keyManager.fundingPublicKey(params.localParams.fundingKeyPath, fundingTxIndex), remoteFundingPubKey, TxOwner.Remote, localNonce, remoteNonce)
713+
val Right(psig) = keyManager.partialSign(remoteCommitTx, localFundingPubKey, remoteFundingPubKey, TxOwner.Remote, localNonce, remoteNonce)
715714
log.debug(s"sendCommit: creating partial sig $psig for remote commit tx ${remoteCommitTx.tx.txid} with fundingTxIndex = $fundingTxIndex remoteCommit.index (should add +1) = ${remoteCommit.index} remote nonce $remoteNonce and remoteNextPerCommitmentPoint = $remoteNextPerCommitmentPoint")
716715
Set(CommitSigTlv.PartialSignatureWithNonceTlv(PartialSignatureWithNonce(psig, localNonce._2)))
717716
} else {
@@ -733,7 +732,7 @@ case class Commitment(fundingTxIndex: Long,
733732
(copy(nextRemoteCommit_opt = Some(nextRemoteCommit)), commitSig)
734733
}
735734

736-
def receiveCommit(keyManager: ChannelKeyManager, params: ChannelParams, changes: CommitmentChanges, localPerCommitmentPoint: PublicKey, commit: CommitSig, localNonce_opt: Option[(SecretNonce, IndividualNonce)])(implicit log: LoggingAdapter): Either[ChannelException, Commitment] = {
735+
def receiveCommit(keyManager: ChannelKeyManager, params: ChannelParams, changes: CommitmentChanges, localPerCommitmentPoint: PublicKey, commit: CommitSig)(implicit log: LoggingAdapter): Either[ChannelException, Commitment] = {
737736
// they sent us a signature for *their* view of *our* next commit tx
738737
// so in terms of rev.hashes and indexes we have:
739738
// ourCommit.index -> our current revocation hash, which is about to become our old revocation hash
@@ -744,7 +743,7 @@ case class Commitment(fundingTxIndex: Long,
744743
// and will increment our index
745744
val localCommitIndex = localCommit.index + 1
746745
val spec = CommitmentSpec.reduce(localCommit.spec, changes.localChanges.acked, changes.remoteChanges.proposed)
747-
LocalCommit.fromCommitSig(keyManager, params, fundingTxId, fundingTxIndex, remoteFundingPubKey, commitInput, commit, localCommitIndex, spec, localPerCommitmentPoint, localNonce_opt).map { localCommit1 =>
746+
LocalCommit.fromCommitSig(keyManager, params, fundingTxId, fundingTxIndex, remoteFundingPubKey, commitInput, commit, localCommitIndex, spec, localPerCommitmentPoint).map { localCommit1 =>
748747
log.info(s"built local commit number=$localCommitIndex toLocalMsat=${spec.toLocal.toLong} toRemoteMsat=${spec.toRemote.toLong} htlc_in={} htlc_out={} feeratePerKw=${spec.commitTxFeerate} txid=${localCommit1.commitTxAndRemoteSig.commitTx.tx.txid} fundingTxId=$fundingTxId", spec.htlcs.collect(DirectedHtlc.incoming).map(_.id).mkString(","), spec.htlcs.collect(DirectedHtlc.outgoing).map(_.id).mkString(","))
749748
copy(localCommit = localCommit1)
750749
}
@@ -760,7 +759,7 @@ case class Commitment(fundingTxIndex: Long,
760759
case RemoteSignature.PartialSignatureWithNonce(remotePsig, remoteNonce) =>
761760
val fundingPubKey = keyManager.fundingPublicKey(params.localParams.fundingKeyPath, fundingTxIndex)
762761
val channelKeyPath = ChannelKeyManager.keyPath(keyManager.fundingPublicKey(params.localParams.fundingKeyPath, fundingTxIndex = 0L))
763-
val localNonce = keyManager.verificationNonce(params.localParams.fundingKeyPath, fundingTxIndex, channelKeyPath, localCommit.index)
762+
val localNonce = keyManager.verificationNonce(fundingPubKey.publicKey, localCommit.index)
764763
val Right(partialSig) = keyManager.partialSign(unsignedCommitTx,
765764
keyManager.fundingPublicKey(params.localParams.fundingKeyPath, fundingTxIndex), remoteFundingPubKey,
766765
TxOwner.Local,
@@ -1151,12 +1150,7 @@ case class Commitments(params: ChannelParams,
11511150

11521151
// Signatures are sent in order (most recent first), calling `zip` will drop trailing sigs that are for deactivated/pruned commitments.
11531152
val active1 = active.zip(commits).map { case (commitment, commit) =>
1154-
val localNonce_opt = if (params.commitmentFormat.useTaproot) {
1155-
Some(keyManager.verificationNonce(params.localParams.fundingKeyPath, commitment.fundingTxIndex, channelKeyPath, localCommitIndex + 1))
1156-
} else {
1157-
None
1158-
}
1159-
commitment.receiveCommit(keyManager, params, changes, localPerCommitmentPoint, commit, localNonce_opt) match {
1153+
commitment.receiveCommit(keyManager, params, changes, localPerCommitmentPoint, commit) match {
11601154
case Left(f) => return Left(f)
11611155
case Right(commitment1) => commitment1
11621156
}
@@ -1166,7 +1160,8 @@ case class Commitments(params: ChannelParams,
11661160
val localNextPerCommitmentPoint = keyManager.commitmentPoint(channelKeyPath, localCommitIndex + 2)
11671161
val tlvStream: TlvStream[RevokeAndAckTlv] = if (params.commitmentFormat.useTaproot) {
11681162
val nonces = this.active.map(c => {
1169-
val n = keyManager.verificationNonce(params.localParams.fundingKeyPath, c.fundingTxIndex, channelKeyPath, localCommitIndex + 2)
1163+
val fundingPubkey = keyManager.fundingPublicKey(params.localParams.fundingKeyPath, c.fundingTxIndex).publicKey
1164+
val n = keyManager.verificationNonce(fundingPubkey, localCommitIndex + 2)
11701165
log.debug(s"revokeandack: creating verification nonce ${n._2} fundingIndex = ${c.fundingTxIndex} commit index = ${localCommitIndex + 2}")
11711166
n
11721167
})
@@ -1307,7 +1302,7 @@ case class Commitments(params: ChannelParams,
13071302
// we cannot compare partial signatures directly as they are not deterministic (a new signing nonce is used every time a signature is computed)
13081303
// => instead we simply check that the provided partial signature is valid for our latest commit tx
13091304
val localFundingKey = keyManager.fundingPublicKey(params.localParams.fundingKeyPath, latest.fundingTxIndex).publicKey
1310-
val Some(localNonce) = generateLocalNonce(keyManager, latest.fundingTxIndex, latest.localCommit.index)
1305+
val (_, localNonce) = keyManager.verificationNonce(localFundingKey, latest.localCommit.index)
13111306
latest.localCommit.commitTxAndRemoteSig.commitTx.checkPartialSignature(psig, localFundingKey, localNonce, latest.remoteFundingPubKey)
13121307
}
13131308

@@ -1456,7 +1451,8 @@ case class Commitments(params: ChannelParams,
14561451
*/
14571452
def generateLocalNonce(keyManager: ChannelKeyManager, fundingIndex: Long, commitIndex: Long): Option[IndividualNonce] = {
14581453
if (latest.params.commitmentFormat.useTaproot) {
1459-
Some(keyManager.verificationNonce(params.localParams.fundingKeyPath, fundingIndex, keyManager.keyPath(params.localParams, params.channelConfig), commitIndex)._2)
1454+
val localFundingKey = keyManager.fundingPublicKey(params.localParams.fundingKeyPath, latest.fundingTxIndex).publicKey
1455+
Some(keyManager.verificationNonce(localFundingKey, commitIndex)._2)
14601456
} else {
14611457
None
14621458
}

eclair-core/src/main/scala/fr/acinq/eclair/channel/Helpers.scala

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -527,7 +527,10 @@ object Helpers {
527527
val localPerCommitmentSecret = keyManager.commitmentSecret(channelKeyPath, commitments.localCommitIndex - 1)
528528
val localNextPerCommitmentPoint = keyManager.commitmentPoint(channelKeyPath, commitments.localCommitIndex + 1)
529529
val tlvStream: TlvStream[RevokeAndAckTlv] = if (commitments.params.commitmentFormat.useTaproot) {
530-
val nonces = commitments.active.map(c => keyManager.verificationNonce(commitments.params.localParams.fundingKeyPath, c.fundingTxIndex, channelKeyPath, commitments.localCommitIndex + 1))
530+
val nonces = commitments.active.map(c => {
531+
val fundingPubkey = keyManager.fundingPublicKey(commitments.params.localParams.fundingKeyPath, c.fundingTxIndex).publicKey
532+
keyManager.verificationNonce(fundingPubkey, commitments.localCommitIndex + 1)
533+
})
531534
TlvStream(RevokeAndAckTlv.NextLocalNoncesTlv(nonces.map(_._2).toList))
532535
} else {
533536
TlvStream.empty

0 commit comments

Comments
 (0)