mirror of
https://github.com/lightningnetwork/lnd.git
synced 2025-10-05 19:52:39 +02:00
multi: use MessageSignerRing where needed
In this commit, we pass the MessageSignerRing around in places where Schnorr signing will be needed to sign Gossip 1.75 messages.
This commit is contained in:
@@ -262,14 +262,14 @@ type Config struct {
|
||||
// use to determine which messages need to be resent for a given peer.
|
||||
MessageStore GossipMessageStore
|
||||
|
||||
// AnnSigner is an instance of the MessageSigner interface which will
|
||||
// be used to manually sign any outgoing channel updates. The signer
|
||||
// implementation should be backed by the public key of the backing
|
||||
// Lightning node.
|
||||
// AnnSigner is an instance of the MessageSignerRing interface which
|
||||
// will be used to manually sign any outgoing channel updates. The
|
||||
// signer implementation should be backed by the public key of the
|
||||
// backing Lightning node.
|
||||
//
|
||||
// TODO(roasbeef): extract ann crafting + sign from fundingMgr into
|
||||
// here?
|
||||
AnnSigner lnwallet.MessageSigner
|
||||
AnnSigner keychain.MessageSignerRing
|
||||
|
||||
// ScidCloser is an instance of ClosedChannelTracker that helps the
|
||||
// gossiper cut down on spam channel announcements for already closed
|
||||
|
@@ -262,6 +262,12 @@ type SingleKeyMessageSigner interface {
|
||||
// hashing it first, with the wrapped private key and returns the
|
||||
// signature in the compact, public key recoverable format.
|
||||
SignMessageCompact(message []byte, doubleHash bool) ([]byte, error)
|
||||
|
||||
// SignMessageSchnorr signs the given message, single or double SHA256
|
||||
// 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, tag []byte) (*schnorr.Signature, error)
|
||||
}
|
||||
|
||||
// ECDHRing is an interface that abstracts away basic low-level ECDH shared key
|
||||
|
@@ -3,7 +3,9 @@ package keychain
|
||||
import (
|
||||
"github.com/btcsuite/btcd/btcec/v2"
|
||||
"github.com/btcsuite/btcd/btcec/v2/ecdsa"
|
||||
"github.com/btcsuite/btcd/btcec/v2/schnorr"
|
||||
"github.com/btcsuite/btcd/chaincfg/chainhash"
|
||||
"github.com/btcsuite/btcd/txscript"
|
||||
)
|
||||
|
||||
func NewPubKeyMessageSigner(pubKey *btcec.PublicKey, keyLoc KeyLocator,
|
||||
@@ -42,6 +44,14 @@ func (p *PubKeyMessageSigner) SignMessageCompact(msg []byte,
|
||||
return p.digestSigner.SignMessageCompact(p.keyLoc, msg, doubleHash)
|
||||
}
|
||||
|
||||
func (p *PubKeyMessageSigner) SignMessageSchnorr(keyLoc KeyLocator, msg []byte,
|
||||
doubleHash bool, taprootTweak, tag []byte) (*schnorr.Signature, error) {
|
||||
|
||||
return p.digestSigner.SignMessageSchnorr(
|
||||
keyLoc, msg, doubleHash, taprootTweak, tag,
|
||||
)
|
||||
}
|
||||
|
||||
func NewPrivKeyMessageSigner(privKey *btcec.PrivateKey,
|
||||
keyLoc KeyLocator) *PrivKeyMessageSigner {
|
||||
|
||||
@@ -88,5 +98,28 @@ func (p *PrivKeyMessageSigner) SignMessageCompact(msg []byte,
|
||||
return ecdsa.SignCompact(p.privKey, digest, true)
|
||||
}
|
||||
|
||||
func (p *PrivKeyMessageSigner) SignMessageSchnorr(_ KeyLocator, msg []byte,
|
||||
doubleHash bool, taprootTweak, tag []byte) (*schnorr.Signature, error) {
|
||||
|
||||
// If a tag was provided, we need to take the tagged hash of the input.
|
||||
var digest []byte
|
||||
switch {
|
||||
case len(tag) > 0:
|
||||
taggedHash := chainhash.TaggedHash(tag, msg)
|
||||
digest = taggedHash[:]
|
||||
case doubleHash:
|
||||
digest = chainhash.DoubleHashB(msg)
|
||||
default:
|
||||
digest = chainhash.HashB(msg)
|
||||
}
|
||||
|
||||
privKey := p.privKey
|
||||
if len(taprootTweak) > 0 {
|
||||
privKey = txscript.TweakTaprootPrivKey(*privKey, taprootTweak)
|
||||
}
|
||||
|
||||
return schnorr.Sign(privKey, digest)
|
||||
}
|
||||
|
||||
var _ SingleKeyMessageSigner = (*PubKeyMessageSigner)(nil)
|
||||
var _ SingleKeyMessageSigner = (*PrivKeyMessageSigner)(nil)
|
||||
|
@@ -571,7 +571,7 @@ func AddInvoice(ctx context.Context, cfg *AddInvoiceConfig,
|
||||
// key is used to sign the invoice so that the sender
|
||||
// can derive the true pub key of the recipient.
|
||||
if !blind {
|
||||
return cfg.NodeSigner.SignMessageCompact(
|
||||
return cfg.NodeSigner.SignMessageCompactNoKeyLoc( //nolint:lll
|
||||
msg, false,
|
||||
)
|
||||
}
|
||||
|
@@ -205,3 +205,68 @@ func (s *SingleSigner) SignMessage(keyLoc keychain.KeyLocator,
|
||||
}
|
||||
return ecdsa.Sign(s.Privkey, digest), nil
|
||||
}
|
||||
|
||||
// SignMessageCompact signs the given message, single or double SHA256 hashing
|
||||
// it first, with the private key described in the key locator and returns the
|
||||
// signature in the compact, public key recoverable format.
|
||||
//
|
||||
// NOTE: This is part of the keychain.MessageSignerRing interface.
|
||||
func (s *SingleSigner) SignMessageCompact(keyLoc keychain.KeyLocator,
|
||||
msg []byte, doubleHash bool) ([]byte, error) {
|
||||
|
||||
mockKeyLoc := s.KeyLoc
|
||||
if s.KeyLoc.IsEmpty() {
|
||||
mockKeyLoc = idKeyLoc
|
||||
}
|
||||
|
||||
if keyLoc != mockKeyLoc {
|
||||
return nil, fmt.Errorf("unknown public key")
|
||||
}
|
||||
|
||||
var digest []byte
|
||||
if doubleHash {
|
||||
digest = chainhash.DoubleHashB(msg)
|
||||
} else {
|
||||
digest = chainhash.HashB(msg)
|
||||
}
|
||||
|
||||
return ecdsa.SignCompact(s.Privkey, digest, true)
|
||||
}
|
||||
|
||||
// SignMessageSchnorr signs the given message, single or double SHA256 hashing
|
||||
// it first, with the private key described in the key locator and the optional
|
||||
// Taproot tweak applied to the private key.
|
||||
//
|
||||
// NOTE: this is part of the keychain.MessageSignerRing interface.
|
||||
func (s *SingleSigner) SignMessageSchnorr(keyLoc keychain.KeyLocator,
|
||||
msg []byte, doubleHash bool, taprootTweak, tag []byte) (
|
||||
*schnorr.Signature, error) {
|
||||
|
||||
mockKeyLoc := s.KeyLoc
|
||||
if s.KeyLoc.IsEmpty() {
|
||||
mockKeyLoc = idKeyLoc
|
||||
}
|
||||
|
||||
if keyLoc != mockKeyLoc {
|
||||
return nil, fmt.Errorf("unknown public key")
|
||||
}
|
||||
|
||||
privKey := s.Privkey
|
||||
if len(taprootTweak) > 0 {
|
||||
privKey = txscript.TweakTaprootPrivKey(*privKey, taprootTweak)
|
||||
}
|
||||
|
||||
// If a tag was provided, we need to take the tagged hash of the input.
|
||||
var digest []byte
|
||||
switch {
|
||||
case len(tag) > 0:
|
||||
taggedHash := chainhash.TaggedHash(tag, msg)
|
||||
digest = taggedHash[:]
|
||||
case doubleHash:
|
||||
digest = chainhash.DoubleHashB(msg)
|
||||
default:
|
||||
digest = chainhash.HashB(msg)
|
||||
}
|
||||
|
||||
return schnorr.Sign(privKey, digest)
|
||||
}
|
||||
|
@@ -10,7 +10,6 @@ import (
|
||||
"github.com/lightningnetwork/lnd/chainntnfs"
|
||||
"github.com/lightningnetwork/lnd/channeldb"
|
||||
"github.com/lightningnetwork/lnd/keychain"
|
||||
"github.com/lightningnetwork/lnd/lnwallet"
|
||||
"github.com/lightningnetwork/lnd/lnwire"
|
||||
)
|
||||
|
||||
@@ -50,7 +49,7 @@ type ChanStatusConfig struct {
|
||||
OurKeyLoc keychain.KeyLocator
|
||||
|
||||
// MessageSigner signs messages that validate under OurPubKey.
|
||||
MessageSigner lnwallet.MessageSigner
|
||||
MessageSigner keychain.MessageSignerRing
|
||||
|
||||
// BestBlockView gives access to the current best block.
|
||||
BestBlockView chainntnfs.BestBlockView
|
||||
|
@@ -9,7 +9,6 @@ import (
|
||||
"github.com/btcsuite/btcd/chaincfg/chainhash"
|
||||
"github.com/lightningnetwork/lnd/channeldb/models"
|
||||
"github.com/lightningnetwork/lnd/keychain"
|
||||
"github.com/lightningnetwork/lnd/lnwallet"
|
||||
"github.com/lightningnetwork/lnd/lnwire"
|
||||
)
|
||||
|
||||
@@ -57,8 +56,9 @@ func ChanUpdSetTimestamp(update *lnwire.ChannelUpdate1) {
|
||||
// monotonically increase from the prior.
|
||||
//
|
||||
// NOTE: This method modifies the given update.
|
||||
func SignChannelUpdate(signer lnwallet.MessageSigner, keyLoc keychain.KeyLocator,
|
||||
update *lnwire.ChannelUpdate1, mods ...ChannelUpdateModifier) error {
|
||||
func SignChannelUpdate(signer keychain.MessageSignerRing,
|
||||
keyLoc keychain.KeyLocator, update *lnwire.ChannelUpdate1,
|
||||
mods ...ChannelUpdateModifier) error {
|
||||
|
||||
// Apply the requested changes to the channel update.
|
||||
for _, modifier := range mods {
|
||||
|
@@ -14,6 +14,8 @@ import (
|
||||
)
|
||||
|
||||
type mockSigner struct {
|
||||
keychain.MessageSignerRing
|
||||
|
||||
err error
|
||||
}
|
||||
|
||||
@@ -43,7 +45,7 @@ type updateDisableTest struct {
|
||||
startEnabled bool
|
||||
disable bool
|
||||
startTime time.Time
|
||||
signer lnwallet.MessageSigner
|
||||
signer keychain.MessageSignerRing
|
||||
expErr error
|
||||
}
|
||||
|
||||
|
@@ -4,8 +4,8 @@ import (
|
||||
"fmt"
|
||||
|
||||
"github.com/btcsuite/btcd/btcec/v2/ecdsa"
|
||||
"github.com/btcsuite/btcd/btcec/v2/schnorr"
|
||||
"github.com/lightningnetwork/lnd/keychain"
|
||||
"github.com/lightningnetwork/lnd/lnwallet"
|
||||
)
|
||||
|
||||
// NodeSigner is an implementation of the MessageSigner interface backed by the
|
||||
@@ -43,15 +43,52 @@ func (n *NodeSigner) SignMessage(keyLoc keychain.KeyLocator,
|
||||
return sig, nil
|
||||
}
|
||||
|
||||
// SignMessageCompact signs a single or double sha256 digest of the msg
|
||||
// SignMessageCompactNoKeyLoc signs a single or double sha256 digest of the msg
|
||||
// parameter under the resident node's private key. The returned signature is a
|
||||
// pubkey-recoverable signature.
|
||||
func (n *NodeSigner) SignMessageCompact(msg []byte, doubleHash bool) ([]byte,
|
||||
error) {
|
||||
// pubkey-recoverable signature. No key locator is required for this since the
|
||||
// NodeSigner already has the key to sign with.
|
||||
func (n *NodeSigner) SignMessageCompactNoKeyLoc(msg []byte, doubleHash bool) (
|
||||
[]byte, error) {
|
||||
|
||||
return n.keySigner.SignMessageCompact(msg, doubleHash)
|
||||
}
|
||||
|
||||
// SignMessageCompact signs the given message, single or double SHA256 hashing
|
||||
// it first, with the private key described in the key locator and returns the
|
||||
// signature in the compact, public key recoverable format.
|
||||
//
|
||||
// NOTE: this is part of the keychain.MessageSignerRing interface.
|
||||
func (n *NodeSigner) SignMessageCompact(keyLoc keychain.KeyLocator, msg []byte,
|
||||
doubleHash bool) ([]byte, error) {
|
||||
|
||||
// If this isn't our identity public key, then we'll exit early with an
|
||||
// error as we can't sign with this key.
|
||||
if keyLoc != n.keySigner.KeyLocator() {
|
||||
return nil, fmt.Errorf("unknown public key locator")
|
||||
}
|
||||
|
||||
return n.SignMessageCompactNoKeyLoc(msg, doubleHash)
|
||||
}
|
||||
|
||||
// SignMessageSchnorr signs the given message, single or double SHA256 hashing
|
||||
// it first, with the private key described in the key locator and the optional
|
||||
// Taproot tweak applied to the private key.
|
||||
//
|
||||
// NOTE: this is part of the keychain.MessageSignerRing interface.
|
||||
func (n *NodeSigner) SignMessageSchnorr(keyLoc keychain.KeyLocator, msg []byte,
|
||||
doubleHash bool, taprootTweak, tag []byte) (*schnorr.Signature, error) {
|
||||
|
||||
// If this isn't our identity public key, then we'll exit early with an
|
||||
// error as we can't sign with this key.
|
||||
if keyLoc != n.keySigner.KeyLocator() {
|
||||
return nil, fmt.Errorf("unknown public key locator")
|
||||
}
|
||||
|
||||
return n.keySigner.SignMessageSchnorr(
|
||||
keyLoc, msg, doubleHash, taprootTweak, tag,
|
||||
)
|
||||
}
|
||||
|
||||
// A compile time check to ensure that NodeSigner implements the MessageSigner
|
||||
// interface.
|
||||
var _ lnwallet.MessageSigner = (*NodeSigner)(nil)
|
||||
var _ keychain.MessageSignerRing = (*NodeSigner)(nil)
|
||||
|
@@ -1671,7 +1671,7 @@ func (r *rpcServer) SignMessage(_ context.Context,
|
||||
}
|
||||
|
||||
in.Msg = append(signedMsgPrefix, in.Msg...)
|
||||
sigBytes, err := r.server.nodeSigner.SignMessageCompact(
|
||||
sigBytes, err := r.server.nodeSigner.SignMessageCompactNoKeyLoc(
|
||||
in.Msg, !in.SingleHash,
|
||||
)
|
||||
if err != nil {
|
||||
|
Reference in New Issue
Block a user