@@ -414,12 +414,20 @@ func verifyHtlcSignature(chainParams *address.ChainParams,
414414 "verify second level: %w" , err )
415415 }
416416
417+ // Because we're verifying an HTLC first-level output, we need
418+ // to apply the same tweak to the key as we did when creating
419+ // the script key in the allocation. That tweak was applied to
420+ // the script key to guarantee uniqueness on the asset level.
421+ verifyKey := TweakPubKeyWithIndex (
422+ keyRing .RemoteHtlcKey , baseJob .HTLC .HtlcIndex ,
423+ )
424+
417425 leafToVerify := txscript.TapLeaf {
418426 Script : htlcScript .WitnessScriptToSign (),
419427 LeafVersion : txscript .BaseLeafVersion ,
420428 }
421429 validator := & schnorrSigValidator {
422- pubKey : * keyRing . RemoteHtlcKey ,
430+ pubKey : * verifyKey ,
423431 tapLeaf : lfn .Some (leafToVerify ),
424432 signMethod : input .TaprootScriptSpendSignMethod ,
425433 }
@@ -439,8 +447,9 @@ func verifyHtlcSignature(chainParams *address.ChainParams,
439447// that should be used to verify the generated signature, and also the leaf to
440448// be signed.
441449func applySignDescToVIn (signDesc input.SignDescriptor , vIn * tappsbt.VInput ,
442- chainParams * address.ChainParams ,
443- tapscriptRoot []byte ) (btcec.PublicKey , txscript.TapLeaf ) {
450+ chainParams * address.ChainParams , tapscriptRoot []byte ,
451+ index input.HtlcIndex , tweakWithIndex bool ) (btcec.PublicKey ,
452+ txscript.TapLeaf ) {
444453
445454 leafToSign := txscript.TapLeaf {
446455 Script : signDesc .WitnessScript ,
@@ -466,20 +475,26 @@ func applySignDescToVIn(signDesc input.SignDescriptor, vIn *tappsbt.VInput,
466475 vIn .SighashType = signDesc .HashType
467476 vIn .TaprootMerkleRoot = tapscriptRoot
468477
478+ // We might need to apply another tweak to the public key if this is an
479+ // HTLC first-level output, where we've applied a tweak to the script
480+ // key to guarantee uniqueness.
481+ singleTweak := signDesc .SingleTweak
482+ if tweakWithIndex {
483+ singleTweak = AddTweakWithIndex (singleTweak , index )
484+ }
485+
469486 // Apply single or double tweaks if present in the sign
470487 // descriptor. At the same time, we apply the tweaks to a copy
471488 // of the public key, so we can validate the produced signature.
472489 signingKey := signDesc .KeyDesc .PubKey
473- if len (signDesc . SingleTweak ) > 0 {
490+ if len (singleTweak ) > 0 {
474491 key := btcwallet .PsbtKeyTypeInputSignatureTweakSingle
475492 vIn .Unknowns = append (vIn .Unknowns , & psbt.Unknown {
476493 Key : key ,
477- Value : signDesc . SingleTweak ,
494+ Value : singleTweak ,
478495 })
479496
480- signingKey = input .TweakPubKeyWithTweak (
481- signingKey , signDesc .SingleTweak ,
482- )
497+ signingKey = input .TweakPubKeyWithTweak (signingKey , singleTweak )
483498 }
484499 if signDesc .DoubleTweak != nil {
485500 key := btcwallet .PsbtKeyTypeInputSignatureTweakDouble
@@ -542,6 +557,7 @@ func (s *AuxLeafSigner) generateHtlcSignature(chanState lnwallet.AuxChanState,
542557
543558 signingKey , leafToSign := applySignDescToVIn (
544559 signDesc , vIn , s .cfg .ChainParams , tapscriptRoot ,
560+ baseJob .HTLC .HtlcIndex , true ,
545561 )
546562
547563 // We can now sign this virtual packet, as we've given the
@@ -832,3 +848,23 @@ func TweakHtlcTree(tree input.ScriptTree,
832848 TapscriptRoot : tree .TapscriptRoot ,
833849 }
834850}
851+
852+ // AddTweakWithIndex adds the given index to the given tweak. If the tweak is
853+ // empty, the index is used as the tweak directly. The value of 1 is always
854+ // added to the index to make sure this value is always non-zero.
855+ func AddTweakWithIndex (maybeTweak []byte , index input.HtlcIndex ) []byte {
856+ indexTweak := HtlcIndexAsScriptKeyTweak (index )
857+
858+ // If we don't already have a tweak, we just use the index as the tweak.
859+ if len (maybeTweak ) == 0 {
860+ return fn .ByteSlice (indexTweak .Bytes ())
861+ }
862+
863+ // If we have a tweak, we need to parse/decode it as a scalar, then add
864+ // the index as a scalar, and encode it back to a byte slice.
865+ tweak := new (secp256k1.ModNScalar )
866+ _ = tweak .SetByteSlice (maybeTweak )
867+ newTweak := tweak .Add (indexTweak )
868+
869+ return fn .ByteSlice (newTweak .Bytes ())
870+ }
0 commit comments