diff --git a/go.mod b/go.mod index 91f2df835..778ce9059 100644 --- a/go.mod +++ b/go.mod @@ -4,7 +4,7 @@ require ( github.com/NebulousLabs/go-upnp v0.0.0-20180202185039-29b680b06c82 github.com/Yawning/aez v0.0.0-20211027044916-e49e68abd344 github.com/btcsuite/btcd v0.23.5-0.20230125025938-be056b0a0b2f - github.com/btcsuite/btcd/btcec/v2 v2.2.2 + github.com/btcsuite/btcd/btcec/v2 v2.3.2 github.com/btcsuite/btcd/btcutil v1.1.3 github.com/btcsuite/btcd/btcutil/psbt v1.1.5 github.com/btcsuite/btcd/chaincfg/chainhash v1.0.2 diff --git a/go.sum b/go.sum index c4ff6bd96..4d1654116 100644 --- a/go.sum +++ b/go.sum @@ -76,8 +76,9 @@ github.com/btcsuite/btcd v0.23.5-0.20230125025938-be056b0a0b2f/go.mod h1:0QJIIN1 github.com/btcsuite/btcd/btcec/v2 v2.1.0/go.mod h1:2VzYrv4Gm4apmbVVsSq5bqf1Ec8v56E48Vt0Y/umPgA= github.com/btcsuite/btcd/btcec/v2 v2.1.1/go.mod h1:ctjw4H1kknNJmRN4iP1R7bTQ+v3GJkZBd6mui8ZsAZE= github.com/btcsuite/btcd/btcec/v2 v2.1.3/go.mod h1:ctjw4H1kknNJmRN4iP1R7bTQ+v3GJkZBd6mui8ZsAZE= -github.com/btcsuite/btcd/btcec/v2 v2.2.2 h1:5uxe5YjoCq+JeOpg0gZSNHuFgeogrocBYxvg6w9sAgc= github.com/btcsuite/btcd/btcec/v2 v2.2.2/go.mod h1:9/CSmJxmuvqzX9Wh2fXMWToLOHhPd11lSPuIupwTkI8= +github.com/btcsuite/btcd/btcec/v2 v2.3.2 h1:5n0X6hX0Zk+6omWcihdYvdAlGf2DfasC0GMf7DClJ3U= +github.com/btcsuite/btcd/btcec/v2 v2.3.2/go.mod h1:zYzJ8etWJQIv1Ogk7OzpWjowwOdXY1W/17j2MW85J04= github.com/btcsuite/btcd/btcutil v1.0.0/go.mod h1:Uoxwv0pqYWhD//tfTiipkxNfdhG9UrLwaeswfjfdF0A= github.com/btcsuite/btcd/btcutil v1.1.0/go.mod h1:5OapHB7A2hBBWLm48mmw4MOHNJCcUBTwmWH/0Jn8VHE= github.com/btcsuite/btcd/btcutil v1.1.1/go.mod h1:nbKlBMNm9FGsdvKvu0essceubPiAcI57pYBNnsLAa34= @@ -405,8 +406,6 @@ github.com/lightninglabs/protobuf-hex-display v1.4.3-hex-display h1:RZJ8H4ueU/aQ github.com/lightninglabs/protobuf-hex-display v1.4.3-hex-display/go.mod h1:2oKOBU042GKFHrdbgGiKax4xVrFiZu51lhacUZQ9MnE= github.com/lightningnetwork/lightning-onion v1.2.1-0.20221202012345-ca23184850a1 h1:Wm0g70gkcAu2pGpNZwfWPSVOY21j8IyYsNewwK4OkT4= github.com/lightningnetwork/lightning-onion v1.2.1-0.20221202012345-ca23184850a1/go.mod h1:7dDx73ApjEZA0kcknI799m2O5kkpfg4/gr7N092ojNo= -github.com/lightningnetwork/lnd/cert v1.1.1 h1:Nsav0RlIDRbOnzz2Yu69SQlK939IKya3Q2S0mDviIN8= -github.com/lightningnetwork/lnd/cert v1.1.1/go.mod h1:1P46svkkd73oSoeI4zjkVKgZNwGq8bkGuPR8z+5vQUs= github.com/lightningnetwork/lnd/cert v1.2.0 h1:IWfjHNMI5JgQZU5fdvDptF3DkVI38f4jO/s3tYgWFbE= github.com/lightningnetwork/lnd/cert v1.2.0/go.mod h1:04JhIEodoR6usBN5+XBRtLEEmEHsclLi0tEyxZQNP+w= github.com/lightningnetwork/lnd/clock v1.0.1/go.mod h1:KnQudQ6w0IAMZi1SgvecLZQZ43ra2vpDNj7H/aasemg= diff --git a/input/musig2.go b/input/musig2.go index 4c69dea87..1ae73d8ce 100644 --- a/input/musig2.go +++ b/input/musig2.go @@ -8,9 +8,26 @@ import ( "github.com/btcsuite/btcd/btcec/v2" "github.com/btcsuite/btcd/btcec/v2/schnorr" "github.com/btcsuite/btcd/btcec/v2/schnorr/musig2" + "github.com/lightningnetwork/lnd/internal/musig2v040" "github.com/lightningnetwork/lnd/keychain" ) +// MuSig2Version is a type that defines the different versions of the MuSig2 +// as defined in the BIP draft: +// (https://github.com/jonasnick/bips/blob/musig2/bip-musig2.mediawiki) +type MuSig2Version uint8 + +const ( + // MuSig2Version040 is version 0.4.0 of the MuSig2 BIP draft. This will + // use the lnd internal/musig2v040 package. + MuSig2Version040 MuSig2Version = 0 + + // MuSig2Version100RC2 is version 1.0.0rc2 of the MuSig2 BIP draft. This + // uses the github.com/btcsuite/btcd/btcec/v2/schnorr/musig2 package + // at git tag `btcec/v2.3.1`. + MuSig2Version100RC2 MuSig2Version = 1 +) + const ( // MuSig2PartialSigSize is the size of a MuSig2 partial signature. // Because a partial signature is just the s value, this corresponds to @@ -31,9 +48,9 @@ type MuSig2Signer interface { // public key of the local signing key. If nonces of other parties are // already known, they can be submitted as well to reduce the number of // method calls necessary later on. - MuSig2CreateSession(keychain.KeyLocator, []*btcec.PublicKey, - *MuSig2Tweaks, [][musig2.PubNonceSize]byte) (*MuSig2SessionInfo, - error) + MuSig2CreateSession(MuSig2Version, keychain.KeyLocator, + []*btcec.PublicKey, *MuSig2Tweaks, + [][musig2.PubNonceSize]byte) (*MuSig2SessionInfo, error) // MuSig2RegisterNonces registers one or more public nonces of other // signing participants for a session identified by its ID. This method @@ -117,6 +134,10 @@ type MuSig2SessionInfo struct { // is the hash over the combined public key and the local public nonces. SessionID [32]byte + // Version is the version of the MuSig2 BIP this signing session is + // using. + Version MuSig2Version + // PublicNonce contains the public nonce of the local signer session. PublicNonce [musig2.PubNonceSize]byte @@ -192,21 +213,71 @@ func (t *MuSig2Tweaks) ToContextOptions() []musig2.ContextOption { return tweakOpts } +// ToV040ContextOptions converts the tweak descriptor to v0.4.0 context options. +func (t *MuSig2Tweaks) ToV040ContextOptions() []musig2v040.ContextOption { + var tweakOpts []musig2v040.ContextOption + if len(t.GenericTweaks) > 0 { + genericTweaksCopy := make( + []musig2v040.KeyTweakDesc, len(t.GenericTweaks), + ) + for idx := range t.GenericTweaks { + genericTweaksCopy[idx] = musig2v040.KeyTweakDesc{ + Tweak: t.GenericTweaks[idx].Tweak, + IsXOnly: t.GenericTweaks[idx].IsXOnly, + } + } + tweakOpts = append(tweakOpts, musig2v040.WithTweakedContext( + genericTweaksCopy..., + )) + } + + // The BIP0086 tweak and the taproot script tweak are mutually + // exclusive. + if t.TaprootBIP0086Tweak { + tweakOpts = append(tweakOpts, musig2v040.WithBip86TweakCtx()) + } else if len(t.TaprootTweak) > 0 { + tweakOpts = append(tweakOpts, musig2v040.WithTaprootTweakCtx( + t.TaprootTweak, + )) + } + + return tweakOpts +} + // MuSig2ParsePubKeys parses a list of raw public keys as the signing keys of a // MuSig2 signing session. -func MuSig2ParsePubKeys(rawPubKeys [][]byte) ([]*btcec.PublicKey, error) { +func MuSig2ParsePubKeys(bipVersion MuSig2Version, + rawPubKeys [][]byte) ([]*btcec.PublicKey, error) { + allSignerPubKeys := make([]*btcec.PublicKey, len(rawPubKeys)) if len(rawPubKeys) < 2 { return nil, fmt.Errorf("need at least two signing public keys") } for idx, pubKeyBytes := range rawPubKeys { - pubKey, err := schnorr.ParsePubKey(pubKeyBytes) - if err != nil { - return nil, fmt.Errorf("error parsing signer public "+ - "key %d: %v", idx, err) + switch bipVersion { + case MuSig2Version040: + pubKey, err := schnorr.ParsePubKey(pubKeyBytes) + if err != nil { + return nil, fmt.Errorf("error parsing signer "+ + "public key %d for v0.4.0 (x-only "+ + "format): %v", idx, err) + } + allSignerPubKeys[idx] = pubKey + + case MuSig2Version100RC2: + pubKey, err := btcec.ParsePubKey(pubKeyBytes) + if err != nil { + return nil, fmt.Errorf("error parsing signer "+ + "public key %d for v1.0.0rc2 ("+ + "compressed format): %v", idx, err) + } + allSignerPubKeys[idx] = pubKey + + default: + return nil, fmt.Errorf("unknown MuSig2 version: <%d>", + bipVersion) } - allSignerPubKeys[idx] = pubKey } return allSignerPubKeys, nil @@ -214,7 +285,26 @@ func MuSig2ParsePubKeys(rawPubKeys [][]byte) ([]*btcec.PublicKey, error) { // MuSig2CombineKeys combines the given set of public keys into a single // combined MuSig2 combined public key, applying the given tweaks. -func MuSig2CombineKeys(allSignerPubKeys []*btcec.PublicKey, sortKeys bool, +func MuSig2CombineKeys(bipVersion MuSig2Version, + allSignerPubKeys []*btcec.PublicKey, sortKeys bool, + tweaks *MuSig2Tweaks) (*musig2.AggregateKey, error) { + + switch bipVersion { + case MuSig2Version040: + return combineKeysV040(allSignerPubKeys, sortKeys, tweaks) + + case MuSig2Version100RC2: + return combineKeysV100RC2(allSignerPubKeys, sortKeys, tweaks) + + default: + return nil, fmt.Errorf("unknown MuSig2 version: <%d>", + bipVersion) + } +} + +// combineKeysV100rc1 implements the MuSigCombineKeys logic for the MuSig2 BIP +// draft version 1.0.0rc2. +func combineKeysV100RC2(allSignerPubKeys []*btcec.PublicKey, sortKeys bool, tweaks *MuSig2Tweaks) (*musig2.AggregateKey, error) { // Convert the tweak options into the appropriate MuSig2 API functional @@ -240,8 +330,69 @@ func MuSig2CombineKeys(allSignerPubKeys []*btcec.PublicKey, sortKeys bool, return combinedKey, err } +// combineKeysV040 implements the MuSigCombineKeys logic for the MuSig2 BIP +// draft version 0.4.0. +func combineKeysV040(allSignerPubKeys []*btcec.PublicKey, sortKeys bool, + tweaks *MuSig2Tweaks) (*musig2.AggregateKey, error) { + + // Convert the tweak options into the appropriate MuSig2 API functional + // options. + var keyAggOpts []musig2v040.KeyAggOption + switch { + case tweaks.TaprootBIP0086Tweak: + keyAggOpts = append(keyAggOpts, musig2v040.WithBIP86KeyTweak()) + case len(tweaks.TaprootTweak) > 0: + keyAggOpts = append(keyAggOpts, musig2v040.WithTaprootKeyTweak( + tweaks.TaprootTweak, + )) + case len(tweaks.GenericTweaks) > 0: + genericTweaksCopy := make( + []musig2v040.KeyTweakDesc, len(tweaks.GenericTweaks), + ) + for idx := range tweaks.GenericTweaks { + genericTweaksCopy[idx] = musig2v040.KeyTweakDesc{ + Tweak: tweaks.GenericTweaks[idx].Tweak, + IsXOnly: tweaks.GenericTweaks[idx].IsXOnly, + } + } + keyAggOpts = append(keyAggOpts, musig2v040.WithKeyTweaks( + genericTweaksCopy..., + )) + } + + // Then we'll use this information to compute the aggregated public key. + combinedKey, _, _, err := musig2v040.AggregateKeys( + allSignerPubKeys, sortKeys, keyAggOpts..., + ) + + // Copy the result back into the default version's native type. + return &musig2.AggregateKey{ + FinalKey: combinedKey.FinalKey, + PreTweakedKey: combinedKey.PreTweakedKey, + }, err +} + // MuSig2CreateContext creates a new MuSig2 signing context. -func MuSig2CreateContext(privKey *btcec.PrivateKey, +func MuSig2CreateContext(bipVersion MuSig2Version, privKey *btcec.PrivateKey, + allSignerPubKeys []*btcec.PublicKey, + tweaks *MuSig2Tweaks) (MuSig2Context, MuSig2Session, error) { + + switch bipVersion { + case MuSig2Version040: + return createContextV040(privKey, allSignerPubKeys, tweaks) + + case MuSig2Version100RC2: + return createContextV100RC2(privKey, allSignerPubKeys, tweaks) + + default: + return nil, nil, fmt.Errorf("unknown MuSig2 version: <%d>", + bipVersion) + } +} + +// createContextV100RC2 implements the MuSig2CreateContext logic for the MuSig2 +// BIP draft version 1.0.0rc2. +func createContextV100RC2(privKey *btcec.PrivateKey, allSignerPubKeys []*btcec.PublicKey, tweaks *MuSig2Tweaks) (*musig2.Context, *musig2.Session, error) { @@ -267,6 +418,35 @@ func MuSig2CreateContext(privKey *btcec.PrivateKey, return muSigContext, muSigSession, nil } +// createContextV040 implements the MuSig2CreateContext logic for the MuSig2 BIP +// draft version 0.4.0. +func createContextV040(privKey *btcec.PrivateKey, + allSignerPubKeys []*btcec.PublicKey, + tweaks *MuSig2Tweaks) (*musig2v040.Context, *musig2v040.Session, + error) { + + // The context keeps track of all signing keys and our local key. + allOpts := append( + []musig2v040.ContextOption{ + musig2v040.WithKnownSigners(allSignerPubKeys), + }, + tweaks.ToV040ContextOptions()..., + ) + muSigContext, err := musig2v040.NewContext(privKey, true, allOpts...) + if err != nil { + return nil, nil, fmt.Errorf("error creating MuSig2 signing "+ + "context: %v", err) + } + + muSigSession, err := muSigContext.NewSession() + if err != nil { + return nil, nil, fmt.Errorf("error creating MuSig2 signing "+ + "session: %v", err) + } + + return muSigContext, muSigSession, nil +} + // MuSig2Sign calls the Sign() method on the given versioned signing session and // returns the result in the most recent version of the MuSig2 API. func MuSig2Sign(session MuSig2Session, msg [32]byte, @@ -286,6 +466,22 @@ func MuSig2Sign(session MuSig2Session, msg [32]byte, return partialSig, nil + case *musig2v040.Session: + var opts []musig2v040.SignOption + if withSortedKeys { + opts = append(opts, musig2v040.WithSortedKeys()) + } + partialSig, err := s.Sign(msg, opts...) + if err != nil { + return nil, fmt.Errorf("error signing with local key: "+ + "%v", err) + } + + return &musig2.PartialSignature{ + S: partialSig.S, + R: partialSig.R, + }, nil + default: return nil, fmt.Errorf("invalid session type <%T>", s) } @@ -306,6 +502,18 @@ func MuSig2CombineSig(session MuSig2Session, return haveAllSigs, nil + case *musig2v040.Session: + haveAllSigs, err := s.CombineSig(&musig2v040.PartialSignature{ + S: otherPartialSig.S, + R: otherPartialSig.R, + }) + if err != nil { + return false, fmt.Errorf("error combining partial "+ + "signature: %v", err) + } + + return haveAllSigs, nil + default: return false, fmt.Errorf("invalid session type <%T>", s) } diff --git a/input/musig2_test.go b/input/musig2_test.go index 994a7f659..1fccd1686 100644 --- a/input/musig2_test.go +++ b/input/musig2_test.go @@ -40,6 +40,19 @@ var ( "CA66", )) + testVector100Key1, _ = btcec.ParsePubKey(hexDecode( + "02F9308A019258C31049344F85F89D5229B531C845836F99B08601F113BC" + + "E036F9", + )) + testVector100Key2, _ = btcec.ParsePubKey(hexDecode( + "03DFF1D77F2A671C5F36183726DB2341BE58FEAE1DA2DECED843240F7B50" + + "2BA659", + )) + testVector100Key3, _ = btcec.ParsePubKey(hexDecode( + "023590A94E768F8E1815C2F24B4D80A8E3149316C3518CE7B7AD338368D0" + + "38CA66", + )) + bip86Tweak = &MuSig2Tweaks{TaprootBIP0086Tweak: true} ) @@ -48,6 +61,7 @@ func TestMuSig2CombineKeys(t *testing.T) { testCases := []struct { name string + version MuSig2Version keys []*btcec.PublicKey sortKeys bool tweak *MuSig2Tweaks @@ -55,16 +69,21 @@ func TestMuSig2CombineKeys(t *testing.T) { expectedFinalKey string expectedPreTweakKey string }{{ + name: "invalid version", + version: 7, + expectedErr: "unknown MuSig2 version: <7>", + }, { name: "v0.4.0 two dummy keys BIP86", + version: MuSig2Version040, keys: []*btcec.PublicKey{dummyPubKey1, dummyPubKey2}, - sortKeys: true, - tweak: bip86Tweak, + sortKeys: true, tweak: bip86Tweak, expectedFinalKey: "03b54fb320a8fc3589e86a1559c6aaa774fbab4e4d" + "9fbf31e2fd836b661ac6a132", expectedPreTweakKey: "0279c76a15dcf6786058a571e4022b78633e1bf" + "8a7a4ca440bcbbeeaea772228a2", }, { - name: "v0.4.0 three dummy keys BIP86", + name: "v0.4.0 three dummy keys BIP86", + version: MuSig2Version040, keys: []*btcec.PublicKey{ dummyPubKey1, dummyPubKey2, dummyPubKey3, }, @@ -75,12 +94,13 @@ func TestMuSig2CombineKeys(t *testing.T) { expectedPreTweakKey: "03e615b8aad4ed10544537bc48b1d6600e15773" + "476a675c6cbba6808f21b1988e5", }, { - name: "v0.4.0 three test vector keys BIP86", + name: "v0.4.0 three test vector keys BIP86", + version: MuSig2Version040, keys: []*btcec.PublicKey{ testVector040Key1, testVector040Key2, testVector040Key3, }, - sortKeys: true, tweak: bip86Tweak, + sortKeys: true, expectedFinalKey: "025b257b4e785d61157ef5303051f45184bd5cb47b" + "c4b4069ed4dd4536459cb83b", expectedPreTweakKey: "02d70cd69a2647f7390973df48cbfa2ccc407b8" + @@ -107,6 +127,54 @@ func TestMuSig2CombineKeys(t *testing.T) { "dfdb788b3735b76a55538179", expectedPreTweakKey: "03e5830140512195d74c8307e39637cbe5fb730" + "ebeab80ec514cf88a877ceeee0b", + }, { + name: "v1.0.0rc2 three dummy keys BIP86", + version: MuSig2Version100RC2, + keys: []*btcec.PublicKey{ + dummyPubKey1, dummyPubKey2, dummyPubKey3, + }, + sortKeys: true, + tweak: bip86Tweak, + expectedFinalKey: "029d11a433e446276c88ee099cecfda1e4234dc486" + + "49e2b07f9b159176731eb68a", + expectedPreTweakKey: "03f0bacfef76086c519b6db216a252f1435336f" + + "d23fc86cfb51f67056439c256d4", + }, { + name: "v1.0.0rc2 three test vector keys BIP86", + version: MuSig2Version100RC2, + keys: []*btcec.PublicKey{ + testVector100Key1, testVector100Key2, testVector100Key3, + }, + sortKeys: false, + tweak: bip86Tweak, + expectedFinalKey: "03f79d14149ecd4bb74921865906a8e4f1333439a9" + + "1b96610d72caa7495dcf2376", + expectedPreTweakKey: "0290539eede565f5d054f32cc0c220126889ed1" + + "e5d193baf15aef344fe59d4610c", + }, { + name: "v1.0.0rc2 three test vector keys BIP86 sorted", + version: MuSig2Version100RC2, + keys: []*btcec.PublicKey{ + testVector100Key1, testVector100Key2, testVector100Key3, + }, + sortKeys: true, + tweak: bip86Tweak, + expectedFinalKey: "0379e6c3e628c9bfbce91de6b7fb28e2aec7713d37" + + "7cf260ab599dcbc40e542312", + expectedPreTweakKey: "03789d937bade6673538f3e28d8368dda4d0512" + + "f94da44cf477a505716d26a1575", + }, { + name: "v1.0.0rc2 three test vector keys BIP86 reverse order", + version: MuSig2Version100RC2, + keys: []*btcec.PublicKey{ + testVector100Key3, testVector100Key2, testVector100Key1, + }, + sortKeys: false, + tweak: bip86Tweak, + expectedFinalKey: "03d61d333ab8c53c330290c144f406ce0c0dc3564b" + + "8e3dee6d1daa6288609bfc75", + expectedPreTweakKey: "036204de8b083426dc6eaf9502d27024d53fc82" + + "6bf7d2012148a0575435df54b2b", }} for _, tc := range testCases { @@ -115,7 +183,7 @@ func TestMuSig2CombineKeys(t *testing.T) { tt.Parallel() res, err := MuSig2CombineKeys( - tc.keys, tc.sortKeys, tc.tweak, + tc.version, tc.keys, tc.sortKeys, tc.tweak, ) if tc.expectedErr != "" { diff --git a/input/test_utils.go b/input/test_utils.go index 99b8e050f..c7e26f9e7 100644 --- a/input/test_utils.go +++ b/input/test_utils.go @@ -139,7 +139,7 @@ func (m *MockSigner) ComputeInputScript(tx *wire.MsgTx, signDesc *SignDescriptor // all signing parties must be provided, including the public key of the local // signing key. If nonces of other parties are already known, they can be // submitted as well to reduce the number of method calls necessary later on. -func (m *MockSigner) MuSig2CreateSession(keychain.KeyLocator, +func (m *MockSigner) MuSig2CreateSession(MuSig2Version, keychain.KeyLocator, []*btcec.PublicKey, *MuSig2Tweaks, [][musig2.PubNonceSize]byte) (*MuSig2SessionInfo, error) { diff --git a/lnrpc/signrpc/signer_server.go b/lnrpc/signrpc/signer_server.go index 6e3dc8347..5542445e7 100644 --- a/lnrpc/signrpc/signer_server.go +++ b/lnrpc/signrpc/signer_server.go @@ -826,7 +826,9 @@ func (s *Server) MuSig2CombineKeys(_ context.Context, // Parse the public keys of all signing participants. This must also // include our own, local key. - allSignerPubKeys, err := input.MuSig2ParsePubKeys(in.AllSignerPubkeys) + allSignerPubKeys, err := input.MuSig2ParsePubKeys( + input.MuSig2Version040, in.AllSignerPubkeys, + ) if err != nil { return nil, fmt.Errorf("error parsing all signer public "+ "keys: %w", err) @@ -841,7 +843,7 @@ func (s *Server) MuSig2CombineKeys(_ context.Context, // Combine the keys now without creating a session in memory. combinedKey, err := input.MuSig2CombineKeys( - allSignerPubKeys, true, tweaks, + input.MuSig2Version040, allSignerPubKeys, true, tweaks, ) if err != nil { return nil, fmt.Errorf("error combining keys: %v", err) @@ -881,7 +883,9 @@ func (s *Server) MuSig2CreateSession(_ context.Context, // Parse the public keys of all signing participants. This must also // include our own, local key. - allSignerPubKeys, err := input.MuSig2ParsePubKeys(in.AllSignerPubkeys) + allSignerPubKeys, err := input.MuSig2ParsePubKeys( + input.MuSig2Version040, in.AllSignerPubkeys, + ) if err != nil { return nil, fmt.Errorf("error parsing all signer public "+ "keys: %w", err) @@ -913,7 +917,8 @@ func (s *Server) MuSig2CreateSession(_ context.Context, // Register the session with the internal wallet/signer now. session, err := s.cfg.Signer.MuSig2CreateSession( - keyLoc, allSignerPubKeys, tweaks, otherSignerNonces, + input.MuSig2Version040, keyLoc, allSignerPubKeys, tweaks, + otherSignerNonces, ) if err != nil { return nil, fmt.Errorf("error registering session: %v", err) diff --git a/lntest/mock/signer.go b/lntest/mock/signer.go index 4dd465cd8..ddcef3598 100644 --- a/lntest/mock/signer.go +++ b/lntest/mock/signer.go @@ -55,8 +55,8 @@ func (d *DummySigner) ComputeInputScript(tx *wire.MsgTx, // all signing parties must be provided, including the public key of the local // signing key. If nonces of other parties are already known, they can be // submitted as well to reduce the number of method calls necessary later on. -func (d *DummySigner) MuSig2CreateSession(keychain.KeyLocator, - []*btcec.PublicKey, *input.MuSig2Tweaks, +func (d *DummySigner) MuSig2CreateSession(input.MuSig2Version, + keychain.KeyLocator, []*btcec.PublicKey, *input.MuSig2Tweaks, [][musig2.PubNonceSize]byte) (*input.MuSig2SessionInfo, error) { return nil, nil @@ -194,8 +194,8 @@ func (s *SingleSigner) SignMessage(keyLoc keychain.KeyLocator, // all signing parties must be provided, including the public key of the local // signing key. If nonces of other parties are already known, they can be // submitted as well to reduce the number of method calls necessary later on. -func (s *SingleSigner) MuSig2CreateSession(keychain.KeyLocator, - []*btcec.PublicKey, *input.MuSig2Tweaks, +func (s *SingleSigner) MuSig2CreateSession(input.MuSig2Version, + keychain.KeyLocator, []*btcec.PublicKey, *input.MuSig2Tweaks, [][musig2.PubNonceSize]byte) (*input.MuSig2SessionInfo, error) { return nil, nil diff --git a/lnwallet/btcwallet/signer.go b/lnwallet/btcwallet/signer.go index 9c220e1e6..ea45556d7 100644 --- a/lnwallet/btcwallet/signer.go +++ b/lnwallet/btcwallet/signer.go @@ -488,8 +488,9 @@ type muSig2State struct { // all signing parties must be provided, including the public key of the local // signing key. If nonces of other parties are already known, they can be // submitted as well to reduce the number of method calls necessary later on. -func (b *BtcWallet) MuSig2CreateSession(keyLoc keychain.KeyLocator, - allSignerPubKeys []*btcec.PublicKey, tweaks *input.MuSig2Tweaks, +func (b *BtcWallet) MuSig2CreateSession(bipVersion input.MuSig2Version, + keyLoc keychain.KeyLocator, allSignerPubKeys []*btcec.PublicKey, + tweaks *input.MuSig2Tweaks, otherSignerNonces [][musig2.PubNonceSize]byte) (*input.MuSig2SessionInfo, error) { @@ -503,10 +504,10 @@ func (b *BtcWallet) MuSig2CreateSession(keyLoc keychain.KeyLocator, return nil, fmt.Errorf("error deriving private key: %v", err) } - // Create a signing context with the given private key and list of all - // known signer public keys. + // Create a signing context and session with the given private key and + // list of all known signer public keys. muSigContext, muSigSession, err := input.MuSig2CreateContext( - privKey, allSignerPubKeys, tweaks, + bipVersion, privKey, allSignerPubKeys, tweaks, ) if err != nil { return nil, fmt.Errorf("error creating signing context: %v", @@ -535,6 +536,7 @@ func (b *BtcWallet) MuSig2CreateSession(keyLoc keychain.KeyLocator, SessionID: input.NewMuSig2SessionID( combinedKey, muSigSession.PublicNonce(), ), + Version: bipVersion, PublicNonce: muSigSession.PublicNonce(), CombinedKey: combinedKey, TaprootTweak: tweaks.HasTaprootTweak(), diff --git a/lnwallet/rpcwallet/rpcwallet.go b/lnwallet/rpcwallet/rpcwallet.go index 9172c2525..ed7f6c366 100644 --- a/lnwallet/rpcwallet/rpcwallet.go +++ b/lnwallet/rpcwallet/rpcwallet.go @@ -640,8 +640,9 @@ func (r *RPCKeyRing) ComputeInputScript(tx *wire.MsgTx, // all signing parties must be provided, including the public key of the local // signing key. If nonces of other parties are already known, they can be // submitted as well to reduce the number of method calls necessary later on. -func (r *RPCKeyRing) MuSig2CreateSession(keyLoc keychain.KeyLocator, - pubKeys []*btcec.PublicKey, tweaks *input.MuSig2Tweaks, +func (r *RPCKeyRing) MuSig2CreateSession(bipVersion input.MuSig2Version, + keyLoc keychain.KeyLocator, pubKeys []*btcec.PublicKey, + tweaks *input.MuSig2Tweaks, otherNonces [][musig2.PubNonceSize]byte) (*input.MuSig2SessionInfo, error) { @@ -690,6 +691,7 @@ func (r *RPCKeyRing) MuSig2CreateSession(keyLoc keychain.KeyLocator, // De-Serialize all the info back into our native struct. info := &input.MuSig2SessionInfo{ + Version: bipVersion, TaprootTweak: tweaks.HasTaprootTweak(), HaveAllNonces: resp.HaveAllNonces, } diff --git a/watchtower/wtmock/signer.go b/watchtower/wtmock/signer.go index b41d8ceb5..6454871ce 100644 --- a/watchtower/wtmock/signer.go +++ b/watchtower/wtmock/signer.go @@ -69,8 +69,8 @@ func (s *MockSigner) ComputeInputScript(tx *wire.MsgTx, // all signing parties must be provided, including the public key of the local // signing key. If nonces of other parties are already known, they can be // submitted as well to reduce the number of method calls necessary later on. -func (s *MockSigner) MuSig2CreateSession(keychain.KeyLocator, - []*btcec.PublicKey, *input.MuSig2Tweaks, +func (s *MockSigner) MuSig2CreateSession(input.MuSig2Version, + keychain.KeyLocator, []*btcec.PublicKey, *input.MuSig2Tweaks, [][musig2.PubNonceSize]byte) (*input.MuSig2SessionInfo, error) { return nil, nil