@@ -6,10 +6,12 @@ import (
66 "errors"
77 "fmt"
88
9- btcec "github.com/btcsuite/btcd/btcec/v2"
9+ "github.com/btcsuite/btcd/btcec/v2"
1010 "github.com/btcsuite/btcd/btcec/v2/schnorr"
11+ "github.com/btcsuite/btcd/btcec/v2/schnorr/musig2"
1112 "github.com/btcsuite/btcd/btcutil"
1213 "github.com/btcsuite/btcd/chaincfg"
14+ "github.com/btcsuite/btcd/chaincfg/chainhash"
1315 "github.com/btcsuite/btcd/txscript"
1416 "github.com/btcsuite/btcd/wire"
1517 secp "github.com/decred/dcrd/dcrec/secp256k1/v4"
@@ -106,7 +108,7 @@ var (
106108 // script size.
107109 QuoteHtlc , _ = NewHtlc (
108110 HtlcV2 ,
109- ^ int32 (0 ), quoteKey , quoteKey , nil , quoteHash , HtlcP2WSH ,
111+ ^ int32 (0 ), quoteKey , quoteKey , quoteHash , HtlcP2WSH ,
110112 & chaincfg .MainNetParams ,
111113 )
112114
@@ -119,17 +121,6 @@ var (
119121 // selected for a v1 or v2 script.
120122 ErrInvalidOutputSelected = fmt .Errorf ("taproot output selected for " +
121123 "non taproot htlc" )
122-
123- // ErrSharedKeyNotNeeded is returned when a shared key is provided for
124- // either the v1 or v2 script. Shared key is only necessary for the v3
125- // script.
126- ErrSharedKeyNotNeeded = fmt .Errorf ("shared key not supported for " +
127- "script version" )
128-
129- // ErrSharedKeyRequired is returned when a script version requires a
130- // shared key.
131- ErrSharedKeyRequired = fmt .Errorf ("shared key required for script " +
132- "version" )
133124)
134125
135126// String returns the string value of HtlcOutputType.
@@ -152,9 +143,8 @@ func (h HtlcOutputType) String() string {
152143// NewHtlc returns a new instance. For v3 scripts, an internal pubkey generated
153144// by both participants must be provided.
154145func NewHtlc (version ScriptVersion , cltvExpiry int32 ,
155- senderKey , receiverKey [33 ]byte , sharedKey * btcec.PublicKey ,
156- hash lntypes.Hash , outputType HtlcOutputType ,
157- chainParams * chaincfg.Params ) (* Htlc , error ) {
146+ senderKey , receiverKey [33 ]byte , hash lntypes.Hash ,
147+ outputType HtlcOutputType , chainParams * chaincfg.Params ) (* Htlc , error ) {
158148
159149 var (
160150 err error
@@ -163,28 +153,18 @@ func NewHtlc(version ScriptVersion, cltvExpiry int32,
163153
164154 switch version {
165155 case HtlcV1 :
166- if sharedKey != nil {
167- return nil , ErrSharedKeyNotNeeded
168- }
169156 htlc , err = newHTLCScriptV1 (
170157 cltvExpiry , senderKey , receiverKey , hash ,
171158 )
172159
173160 case HtlcV2 :
174- if sharedKey != nil {
175- return nil , ErrSharedKeyNotNeeded
176- }
177161 htlc , err = newHTLCScriptV2 (
178162 cltvExpiry , senderKey , receiverKey , hash ,
179163 )
180164
181165 case HtlcV3 :
182- if sharedKey == nil {
183- return nil , ErrSharedKeyRequired
184- }
185166 htlc , err = newHTLCScriptV3 (
186- cltvExpiry , senderKey , receiverKey ,
187- sharedKey , hash ,
167+ cltvExpiry , senderKey , receiverKey , hash ,
188168 )
189169
190170 default :
@@ -646,49 +626,51 @@ func (h *HtlcScriptV2) lockingConditions(htlcOutputType HtlcOutputType,
646626
647627// HtlcScriptV3 encapsulates the htlc v3 script.
648628type HtlcScriptV3 struct {
649- // The final locking script for the timeout path which is available to
650- // the sender after the set blockheight.
629+ // TimeoutScript is the final locking script for the timeout path which
630+ // is available to the sender after the set blockheight.
651631 TimeoutScript []byte
652632
653- // The final locking script for the success path in which the receiver
654- // reveals the preimage.
633+ // SuccessScript is the final locking script for the success path in
634+ // which the receiver reveals the preimage.
655635 SuccessScript []byte
656636
657- // The public key for the keyspend path which bypasses the above two
658- // locking scripts.
637+ // InternalPubKey is the public key for the keyspend path which bypasses
638+ // the above two locking scripts.
659639 InternalPubKey * btcec.PublicKey
660640
661- // The taproot public key which is created with the above 3 inputs.
641+ // TaprootKey is the taproot public key which is created with the above
642+ // 3 inputs.
662643 TaprootKey * btcec.PublicKey
644+
645+ // RootHash is the root hash of the taptree.
646+ RootHash chainhash.Hash
663647}
664648
665649// newHTLCScriptV3 constructs a HtlcScipt with the HTLC V3 taproot script.
666- func newHTLCScriptV3 (cltvExpiry int32 , senderHtlcKey ,
667- receiverHtlcKey [33 ]byte , sharedKey * btcec.PublicKey ,
650+ func newHTLCScriptV3 (cltvExpiry int32 , senderHtlcKey , receiverHtlcKey [33 ]byte ,
668651 swapHash lntypes.Hash ) (* HtlcScriptV3 , error ) {
669652
670- receiverPubKey , err := btcec .ParsePubKey (
671- receiverHtlcKey [:],
672- )
653+ senderPubKey , err := schnorr .ParsePubKey (senderHtlcKey [1 :])
673654 if err != nil {
674655 return nil , err
675656 }
676657
677- senderPubKey , err := btcec .ParsePubKey (
678- senderHtlcKey [:],
679- )
658+ receiverPubKey , err := schnorr .ParsePubKey (receiverHtlcKey [1 :])
680659 if err != nil {
681660 return nil , err
682661 }
683662
684- var schnorrSenderKey , schnorrReceiverKey [32 ]byte
685- copy (schnorrSenderKey [:], schnorr .SerializePubKey (senderPubKey ))
686- copy (schnorrReceiverKey [:], schnorr .SerializePubKey (receiverPubKey ))
663+ aggregateKey , _ , _ , err := musig2 .AggregateKeys (
664+ []* btcec.PublicKey {senderPubKey , receiverPubKey }, true ,
665+ )
666+ if err != nil {
667+ return nil , err
668+ }
687669
688670 // Create our success path script, we'll use this separately
689671 // to generate the success path leaf.
690672 successPathScript , err := GenSuccessPathScript (
691- schnorrReceiverKey , swapHash ,
673+ receiverPubKey , swapHash ,
692674 )
693675 if err != nil {
694676 return nil , err
@@ -697,7 +679,7 @@ func newHTLCScriptV3(cltvExpiry int32, senderHtlcKey,
697679 // Create our timeout path leaf, we'll use this separately
698680 // to generate the timeout path leaf.
699681 timeoutPathScript , err := GenTimeoutPathScript (
700- schnorrSenderKey , int64 (cltvExpiry ),
682+ senderPubKey , int64 (cltvExpiry ),
701683 )
702684 if err != nil {
703685 return nil , err
@@ -713,26 +695,27 @@ func newHTLCScriptV3(cltvExpiry int32, senderHtlcKey,
713695
714696 // Calculate top level taproot key.
715697 taprootKey := txscript .ComputeTaprootOutputKey (
716- sharedKey , rootHash [:],
698+ aggregateKey . PreTweakedKey , rootHash [:],
717699 )
718700
719701 return & HtlcScriptV3 {
720702 TimeoutScript : timeoutPathScript ,
721703 SuccessScript : successPathScript ,
722- InternalPubKey : sharedKey ,
704+ InternalPubKey : aggregateKey . PreTweakedKey ,
723705 TaprootKey : taprootKey ,
706+ RootHash : rootHash ,
724707 }, nil
725708}
726709
727710// GenTimeoutPathScript constructs an HtlcScript for the timeout payment path.
728711// Largest possible bytesize of the script is 32 + 1 + 2 + 1 = 36.
729712//
730713// <senderHtlcKey> OP_CHECKSIGVERIFY <cltvExpiry> OP_CHECKLOCKTIMEVERIFY
731- func GenTimeoutPathScript (
732- senderHtlcKey [ 32 ] byte , cltvExpiry int64 ) ( []byte , error ) {
714+ func GenTimeoutPathScript (senderHtlcKey * btcec. PublicKey , cltvExpiry int64 ) (
715+ []byte , error ) {
733716
734717 builder := txscript .NewScriptBuilder ()
735- builder .AddData (senderHtlcKey [:] )
718+ builder .AddData (schnorr . SerializePubKey ( senderHtlcKey ) )
736719 builder .AddOp (txscript .OP_CHECKSIGVERIFY )
737720 builder .AddInt64 (cltvExpiry )
738721 builder .AddOp (txscript .OP_CHECKLOCKTIMEVERIFY )
@@ -746,12 +729,12 @@ func GenTimeoutPathScript(
746729// OP_SIZE 32 OP_EQUALVERIFY
747730// OP_HASH160 <ripemd160h(swapHash)> OP_EQUALVERIFY
748731// 1 OP_CHECKSEQUENCEVERIFY
749- func GenSuccessPathScript (receiverHtlcKey [ 32 ] byte ,
732+ func GenSuccessPathScript (receiverHtlcKey * btcec. PublicKey ,
750733 swapHash lntypes.Hash ) ([]byte , error ) {
751734
752735 builder := txscript .NewScriptBuilder ()
753736
754- builder .AddData (receiverHtlcKey [:] )
737+ builder .AddData (schnorr . SerializePubKey ( receiverHtlcKey ) )
755738 builder .AddOp (txscript .OP_CHECKSIGVERIFY )
756739 builder .AddOp (txscript .OP_SIZE )
757740 builder .AddInt64 (32 )
0 commit comments