From cc808803ca385bcbacb34aa6341a39d85115d547 Mon Sep 17 00:00:00 2001 From: Olaoluwa Osuntokun Date: Sat, 10 Jan 2026 15:43:12 -0800 Subject: [PATCH] signer: add MuSig2 combined nonce registration methods This commit adds two new methods to the SignerClient interface: - MuSig2RegisterCombinedNonce: Registers a pre-aggregated combined nonce for a session. This is an alternative to MuSig2RegisterNonces and is used when a coordinator has already aggregated all individual nonces. - MuSig2GetCombinedNonce: Retrieves the combined nonce for a session after it becomes available. These methods are needed for coordinator-based MuSig2 signing workflows. Also updates lnd dependency to include sqldb v1.0.12. --- go.mod | 6 ++-- go.sum | 12 +++---- signer_client.go | 71 +++++++++++++++++++++++++++++++++++++++ testdata/permissions.json | 16 +++++++++ 4 files changed, 96 insertions(+), 9 deletions(-) diff --git a/go.mod b/go.mod index a07e762..e7ad82e 100644 --- a/go.mod +++ b/go.mod @@ -2,14 +2,14 @@ module github.com/lightninglabs/lndclient require ( github.com/btcsuite/btcd v0.24.3-0.20250318170759-4f4ea81776d6 - github.com/btcsuite/btcd/btcec/v2 v2.3.4 + github.com/btcsuite/btcd/btcec/v2 v2.3.6 github.com/btcsuite/btcd/btcutil v1.1.5 github.com/btcsuite/btcd/btcutil/psbt v1.1.8 github.com/btcsuite/btcd/chaincfg/chainhash v1.1.0 github.com/btcsuite/btclog/v2 v2.0.1-0.20250728225537-6090e87c6c5b github.com/btcsuite/btcwallet v0.16.17 github.com/btcsuite/btcwallet/wtxmgr v1.5.6 - github.com/lightningnetwork/lnd v0.20.0-beta + github.com/lightningnetwork/lnd v0.20.0-beta.rc4.0.20260110233730-15227a4ff50a github.com/lightningnetwork/lnd/kvdb v1.4.16 github.com/stretchr/testify v1.10.0 google.golang.org/grpc v1.59.0 @@ -103,7 +103,7 @@ require ( github.com/lightningnetwork/lnd/fn/v2 v2.0.9 // indirect github.com/lightningnetwork/lnd/healthcheck v1.2.6 // indirect github.com/lightningnetwork/lnd/queue v1.1.1 // indirect - github.com/lightningnetwork/lnd/sqldb v1.0.11 // indirect + github.com/lightningnetwork/lnd/sqldb v1.0.12 // indirect github.com/lightningnetwork/lnd/ticker v1.1.1 // indirect github.com/lightningnetwork/lnd/tlv v1.3.2 // indirect github.com/lightningnetwork/lnd/tor v1.1.6 // indirect diff --git a/go.sum b/go.sum index 400b036..a329dc4 100644 --- a/go.sum +++ b/go.sum @@ -39,8 +39,8 @@ github.com/btcsuite/btcd v0.24.3-0.20250318170759-4f4ea81776d6 h1:8n9k3I7e8DkpdQ github.com/btcsuite/btcd v0.24.3-0.20250318170759-4f4ea81776d6/go.mod h1:OmM4kFtB0klaG/ZqT86rQiyw/1iyXlJgc3UHClPhhbs= github.com/btcsuite/btcd/btcec/v2 v2.1.0/go.mod h1:2VzYrv4Gm4apmbVVsSq5bqf1Ec8v56E48Vt0Y/umPgA= github.com/btcsuite/btcd/btcec/v2 v2.1.3/go.mod h1:ctjw4H1kknNJmRN4iP1R7bTQ+v3GJkZBd6mui8ZsAZE= -github.com/btcsuite/btcd/btcec/v2 v2.3.4 h1:3EJjcN70HCu/mwqlUsGK8GcNVyLVxFDlWurTXGPFfiQ= -github.com/btcsuite/btcd/btcec/v2 v2.3.4/go.mod h1:zYzJ8etWJQIv1Ogk7OzpWjowwOdXY1W/17j2MW85J04= +github.com/btcsuite/btcd/btcec/v2 v2.3.6 h1:IzlsEr9olcSRKB/n7c4351F3xHKxS2lma+1UFGCYd4E= +github.com/btcsuite/btcd/btcec/v2 v2.3.6/go.mod h1:m22FrOAiuxl/tht9wIqAoGHcbnCCaPWyauO8y2LGGtQ= 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.5 h1:+wER79R5670vs/ZusMTF1yTcRYE5GUsFbdjdisflzM8= @@ -356,8 +356,8 @@ github.com/lightninglabs/protobuf-go-hex-display v1.33.0-hex-display h1:Y2WiPkBS github.com/lightninglabs/protobuf-go-hex-display v1.33.0-hex-display/go.mod h1:c6P6GXX6sHbq/GpV6MGZEdwhWPcYBgnhAHhKbcUYpos= github.com/lightningnetwork/lightning-onion v1.2.1-0.20240815225420-8b40adf04ab9 h1:6D3LrdagJweLLdFm1JNodZsBk6iU4TTsBBFLQ4yiXfI= github.com/lightningnetwork/lightning-onion v1.2.1-0.20240815225420-8b40adf04ab9/go.mod h1:EDqJ3MuZIbMq0QI1czTIKDJ/GS8S14RXPwapHw8cw6w= -github.com/lightningnetwork/lnd v0.20.0-beta h1:ML+jgJ3UKDGJdUf0m73ZeR/szJKWVtHxpQP+yFC79b8= -github.com/lightningnetwork/lnd v0.20.0-beta/go.mod h1:8hc55AnE3mMSJ/UAEJZgmhgNCcH0yWaPg0olpxhhp4M= +github.com/lightningnetwork/lnd v0.20.0-beta.rc4.0.20260110233730-15227a4ff50a h1:iRR8gWsS7rPTz7GRmyBu/QU0kXBAPi/FYxfnrhuh9Y4= +github.com/lightningnetwork/lnd v0.20.0-beta.rc4.0.20260110233730-15227a4ff50a/go.mod h1:OycW7yPCaApWsIqLthe8QHxk4dM5wOw0LPcUXjr3a5s= github.com/lightningnetwork/lnd/clock v1.1.1 h1:OfR3/zcJd2RhH0RU+zX/77c0ZiOnIMsDIBjgjWdZgA0= github.com/lightningnetwork/lnd/clock v1.1.1/go.mod h1:mGnAhPyjYZQJmebS7aevElXKTFDuO+uNFFfMXK1W8xQ= github.com/lightningnetwork/lnd/fn/v2 v2.0.9 h1:ZytG4ltPac/sCyg1EJDn10RGzPIDJeyennUMRdOw7Y8= @@ -368,8 +368,8 @@ github.com/lightningnetwork/lnd/kvdb v1.4.16 h1:9BZgWdDfjmHRHLS97cz39bVuBAqMc4/p github.com/lightningnetwork/lnd/kvdb v1.4.16/go.mod h1:HW+bvwkxNaopkz3oIgBV6NEnV4jCEZCACFUcNg4xSjM= github.com/lightningnetwork/lnd/queue v1.1.1 h1:99ovBlpM9B0FRCGYJo6RSFDlt8/vOkQQZznVb18iNMI= github.com/lightningnetwork/lnd/queue v1.1.1/go.mod h1:7A6nC1Qrm32FHuhx/mi1cieAiBZo5O6l8IBIoQxvkz4= -github.com/lightningnetwork/lnd/sqldb v1.0.11 h1:X8J3OvdIhJVniQG78Qsp3niErl1zdGMTPvzgiLMWOOo= -github.com/lightningnetwork/lnd/sqldb v1.0.11/go.mod h1:oOdZ7vjmAUmI9He+aFHTunnxKVefHZAfJttZdz16hSg= +github.com/lightningnetwork/lnd/sqldb v1.0.12 h1:cNJsL+ymCtTn9DqroszZixKaD96GN32ujpHUYvrkN30= +github.com/lightningnetwork/lnd/sqldb v1.0.12/go.mod h1:Ic65SUa2pJzc3sWSZqDTrWo5qdKIS1zu/blhSddF7X8= github.com/lightningnetwork/lnd/ticker v1.1.1 h1:J/b6N2hibFtC7JLV77ULQp++QLtCwT6ijJlbdiZFbSM= github.com/lightningnetwork/lnd/ticker v1.1.1/go.mod h1:waPTRAAcwtu7Ji3+3k+u/xH5GHovTsCoSVpho0KDvdA= github.com/lightningnetwork/lnd/tlv v1.3.2 h1:MO4FCk7F4k5xPMqVZF6Nb/kOpxlwPrUQpYjmyKny5s0= diff --git a/signer_client.go b/signer_client.go index 802468e..0a605b4 100644 --- a/signer_client.go +++ b/signer_client.go @@ -101,6 +101,25 @@ type SignerClient interface { // MuSig2Cleanup removes a session from memory to free up resources. MuSig2Cleanup(ctx context.Context, sessionID [32]byte) error + + // MuSig2RegisterCombinedNonce registers a pre-aggregated combined nonce + // for a session identified by its ID. This is an alternative to + // MuSig2RegisterNonces and is used when a coordinator has already + // aggregated all individual nonces and wants to distribute the combined + // nonce to participants. + // + // NOTE: This method is mutually exclusive with MuSig2RegisterNonces for + // the same session. Once this method is called, MuSig2RegisterNonces + // will return an error if called later for the same session. + MuSig2RegisterCombinedNonce(ctx context.Context, sessionID [32]byte, + combinedNonce [66]byte) error + + // MuSig2GetCombinedNonce retrieves the combined nonce for a session + // identified by its ID. This will be available after either all + // individual nonces have been registered via MuSig2RegisterNonces, or a + // combined nonce has been registered via MuSig2RegisterCombinedNonce. + MuSig2GetCombinedNonce(ctx context.Context, + sessionID [32]byte) ([66]byte, error) } // SignDescriptor houses the necessary information required to successfully @@ -765,3 +784,55 @@ func (s *signerClient) MuSig2Cleanup(ctx context.Context, return err } + +// MuSig2RegisterCombinedNonce registers a pre-aggregated combined nonce for a +// session identified by its ID. This is an alternative to MuSig2RegisterNonces +// and is used when a coordinator has already aggregated all individual nonces +// and wants to distribute the combined nonce to participants. +func (s *signerClient) MuSig2RegisterCombinedNonce(ctx context.Context, + sessionID [32]byte, combinedNonce [66]byte) error { + + req := &signrpc.MuSig2RegisterCombinedNonceRequest{ + SessionId: sessionID[:], + CombinedPublicNonce: combinedNonce[:], + } + + rpcCtx, cancel := context.WithTimeout(ctx, s.timeout) + defer cancel() + + rpcCtx = s.signerMac.WithMacaroonAuth(rpcCtx) + _, err := s.client.MuSig2RegisterCombinedNonce(rpcCtx, req) + + return err +} + +// MuSig2GetCombinedNonce retrieves the combined nonce for a session identified +// by its ID. This will be available after either all individual nonces have +// been registered via MuSig2RegisterNonces, or a combined nonce has been +// registered via MuSig2RegisterCombinedNonce. +func (s *signerClient) MuSig2GetCombinedNonce(ctx context.Context, + sessionID [32]byte) ([66]byte, error) { + + req := &signrpc.MuSig2GetCombinedNonceRequest{ + SessionId: sessionID[:], + } + + rpcCtx, cancel := context.WithTimeout(ctx, s.timeout) + defer cancel() + + rpcCtx = s.signerMac.WithMacaroonAuth(rpcCtx) + resp, err := s.client.MuSig2GetCombinedNonce(rpcCtx, req) + if err != nil { + return [66]byte{}, err + } + + if len(resp.CombinedPublicNonce) != 66 { + return [66]byte{}, fmt.Errorf("unexpected combined nonce "+ + "size: %v", len(resp.CombinedPublicNonce)) + } + + var combinedNonce [66]byte + copy(combinedNonce[:], resp.CombinedPublicNonce) + + return combinedNonce, nil +} diff --git a/testdata/permissions.json b/testdata/permissions.json index f3dc691..e159028 100644 --- a/testdata/permissions.json +++ b/testdata/permissions.json @@ -984,6 +984,22 @@ } ] }, + "/signrpc.Signer/MuSig2RegisterCombinedNonce": { + "permissions": [ + { + "entity": "signer", + "action": "generate" + } + ] + }, + "/signrpc.Signer/MuSig2GetCombinedNonce": { + "permissions": [ + { + "entity": "signer", + "action": "generate" + } + ] + }, "/signrpc.Signer/SignMessage": { "permissions": [ {