signrpc: implement combined nonce RPC server handlers

Add server-side RPC handlers for MuSig2RegisterCombinedNonce and
MuSig2GetCombinedNonce.

The handlers:
- Delegate to the Signer interface methods
- Validate input (session ID format, combined nonce length)
- Include macaroon permissions (generate for register, read for get)

These handlers complete the server-side RPC implementation.
This commit is contained in:
Elle Mouton committed 2025-12-10 07:15:06 +02:00
1 parent c945f6749e
commit 16b9192dad
1 file changed
+64
+64
View File
@@ -86,6 +86,14 @@ var (
Entity: "signer",
Action: "generate",
}},
"/signrpc.Signer/MuSig2RegisterCombinedNonce": {{
Entity: "signer",
Action: "generate",
}},
"/signrpc.Signer/MuSig2GetCombinedNonce": {{
Entity: "signer",
Action: "read",
}},
"/signrpc.Signer/MuSig2Sign": {{
Entity: "signer",
Action: "generate",
@@ -1080,6 +1088,62 @@ func (s *Server) MuSig2RegisterNonces(_ context.Context,
return &MuSig2RegisterNoncesResponse{HaveAllNonces: haveAllNonces}, nil
}
// 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.
func (s *Server) MuSig2RegisterCombinedNonce(_ context.Context,
in *MuSig2RegisterCombinedNonceRequest) (
*MuSig2RegisterCombinedNonceResponse, error) {
// Check session ID length.
sessionID, err := parseMuSig2SessionID(in.SessionId)
if err != nil {
return nil, fmt.Errorf("error parsing session ID: %w", err)
}
// Validate the combined nonce length.
if len(in.CombinedPublicNonce) != musig2.PubNonceSize {
return nil, fmt.Errorf("invalid combined nonce length, got "+
"%d wanted %d", len(in.CombinedPublicNonce),
musig2.PubNonceSize)
}
// Convert to the expected fixed-size array.
var combinedNonce [musig2.PubNonceSize]byte
copy(combinedNonce[:], in.CombinedPublicNonce)
// Register the combined nonce.
err = s.cfg.Signer.MuSig2RegisterCombinedNonce(sessionID, combinedNonce)
if err != nil {
return nil, fmt.Errorf("error registering combined nonce: %w",
err)
}
return &MuSig2RegisterCombinedNonceResponse{}, nil
}
// MuSig2GetCombinedNonce retrieves the combined nonce for a signing session.
func (s *Server) MuSig2GetCombinedNonce(_ context.Context,
in *MuSig2GetCombinedNonceRequest) (
*MuSig2GetCombinedNonceResponse, error) {
// Check session ID length.
sessionID, err := parseMuSig2SessionID(in.SessionId)
if err != nil {
return nil, fmt.Errorf("error parsing session ID: %w", err)
}
// Get the combined nonce from the signer.
combinedNonce, err := s.cfg.Signer.MuSig2GetCombinedNonce(sessionID)
if err != nil {
return nil, fmt.Errorf("error getting combined nonce: %w", err)
}
return &MuSig2GetCombinedNonceResponse{
CombinedPublicNonce: combinedNonce[:],
}, nil
}
// MuSig2Sign creates a partial signature using the local signing key that was
// specified when the session was created. This can only be called when all
// public nonces of all participants are known and have been registered with