diff --git a/keychain/btcwallet.go b/keychain/btcwallet.go index 4efb9fd61..0df679df9 100644 --- a/keychain/btcwallet.go +++ b/keychain/btcwallet.go @@ -458,8 +458,8 @@ func (b *BtcWalletKeyRing) SignMessageCompact(keyLoc KeyLocator, // // NOTE: This is part of the keychain.MessageSignerRing interface. func (b *BtcWalletKeyRing) SignMessageSchnorr(keyLoc KeyLocator, - msg []byte, doubleHash bool, taprootTweak []byte) (*schnorr.Signature, - error) { + msg []byte, doubleHash bool, taprootTweak []byte, + tag []byte) (*schnorr.Signature, error) { privKey, err := b.DerivePrivKey(KeyDescriptor{ KeyLocator: keyLoc, @@ -472,10 +472,15 @@ func (b *BtcWalletKeyRing) SignMessageSchnorr(keyLoc KeyLocator, privKey = txscript.TweakTaprootPrivKey(*privKey, taprootTweak) } + // If a tag was provided, we need to take the tagged hash of the input. var digest []byte - if doubleHash { + switch { + case len(tag) > 0: + taggedHash := chainhash.TaggedHash(tag, msg) + digest = taggedHash[:] + case doubleHash: digest = chainhash.DoubleHashB(msg) - } else { + default: digest = chainhash.HashB(msg) } return schnorr.Sign(privKey, digest) diff --git a/keychain/derivation.go b/keychain/derivation.go index 21996c650..2b1c43444 100644 --- a/keychain/derivation.go +++ b/keychain/derivation.go @@ -239,8 +239,8 @@ type MessageSignerRing interface { // hashing it first, with the private key described in the key locator // and the optional Taproot tweak applied to the private key. SignMessageSchnorr(keyLoc KeyLocator, msg []byte, - doubleHash bool, taprootTweak []byte) (*schnorr.Signature, - error) + doubleHash bool, taprootTweak []byte, + tag []byte) (*schnorr.Signature, error) } // SingleKeyMessageSigner is an abstraction interface that hides the diff --git a/lnrpc/signrpc/signer_server.go b/lnrpc/signrpc/signer_server.go index b92ad3023..c01c2d77a 100644 --- a/lnrpc/signrpc/signer_server.go +++ b/lnrpc/signrpc/signer_server.go @@ -633,7 +633,7 @@ func (s *Server) SignMessage(_ context.Context, if in.SchnorrSig { sig, err := s.cfg.KeyRing.SignMessageSchnorr( keyLocator, in.Msg, in.DoubleHash, - in.SchnorrSigTapTweak, + in.SchnorrSigTapTweak, in.Tag, ) if err != nil { return nil, fmt.Errorf("can't sign the hash: %v", err) diff --git a/lntest/mock/secretkeyring.go b/lntest/mock/secretkeyring.go index 770b0e4d3..56c0fac94 100644 --- a/lntest/mock/secretkeyring.go +++ b/lntest/mock/secretkeyring.go @@ -74,13 +74,17 @@ func (s *SecretKeyRing) SignMessageCompact(_ keychain.KeyLocator, // SignMessageSchnorr signs the passed message and ignores the KeyDescriptor. func (s *SecretKeyRing) SignMessageSchnorr(_ keychain.KeyLocator, - msg []byte, doubleHash bool, taprootTweak []byte) (*schnorr.Signature, - error) { + msg []byte, doubleHash bool, taprootTweak []byte, + tag []byte) (*schnorr.Signature, error) { var digest []byte - if doubleHash { + switch { + case len(tag) > 0: + taggedHash := chainhash.TaggedHash(tag, msg) + digest = taggedHash[:] + case doubleHash: digest = chainhash.DoubleHashB(msg) - } else { + default: digest = chainhash.HashB(msg) } diff --git a/lnwallet/rpcwallet/rpcwallet.go b/lnwallet/rpcwallet/rpcwallet.go index 69e1f25b7..0ee8b215c 100644 --- a/lnwallet/rpcwallet/rpcwallet.go +++ b/lnwallet/rpcwallet/rpcwallet.go @@ -513,8 +513,8 @@ func (r *RPCKeyRing) SignMessageCompact(keyLoc keychain.KeyLocator, // // NOTE: This method is part of the keychain.MessageSignerRing interface. func (r *RPCKeyRing) SignMessageSchnorr(keyLoc keychain.KeyLocator, - msg []byte, doubleHash bool, taprootTweak []byte) (*schnorr.Signature, - error) { + msg []byte, doubleHash bool, taprootTweak []byte, + tag []byte) (*schnorr.Signature, error) { ctxt, cancel := context.WithTimeout(context.Background(), r.rpcTimeout) defer cancel() @@ -528,6 +528,7 @@ func (r *RPCKeyRing) SignMessageSchnorr(keyLoc keychain.KeyLocator, DoubleHash: doubleHash, SchnorrSig: true, SchnorrSigTapTweak: taprootTweak, + Tag: tag, }) if err != nil { considerShutdown(err)