• Home
  • Features
  • Pricing
  • Docs
  • Announcements
  • Sign In

lightningnetwork / lnd / 13236757158

10 Feb 2025 08:39AM UTC coverage: 57.649% (-1.2%) from 58.815%
13236757158

Pull #9493

github

ziggie1984
lncli: for some cmds we don't replace the data of the response.

For some cmds it is not very practical to replace the json output
because we might pipe it into other commands. For example when
creating the route we want to pipe it into sendtoRoute.
Pull Request #9493: For some lncli cmds we should not replace the content with other data

0 of 9 new or added lines in 2 files covered. (0.0%)

19535 existing lines in 252 files now uncovered.

103517 of 179563 relevant lines covered (57.65%)

24878.49 hits per line

Source File
Press 'n' to go to next uncovered line, 'b' for previous

42.86
/keychain/derivation.go
1
package keychain
2

3
import (
4
        "fmt"
5

6
        "github.com/btcsuite/btcd/btcec/v2"
7
        "github.com/btcsuite/btcd/btcec/v2/ecdsa"
8
        "github.com/btcsuite/btcd/btcec/v2/schnorr"
9
)
10

11
const (
12
        // KeyDerivationVersionLegacy is the previous version of the key
13
        // derivation schema defined below. We use a version as this means that
14
        // we'll be able to accept new seed in the future and be able to discern
15
        // if the software is compatible with the version of the seed.
16
        KeyDerivationVersionLegacy = 0
17

18
        // KeyDerivationVersionTaproot is the most recent version of the key
19
        // derivation scheme that marks the introduction of the Taproot
20
        // derivation with BIP0086 support.
21
        KeyDerivationVersionTaproot = 1
22

23
        // CurrentKeyDerivationVersion is the current default key derivation
24
        // version that is used for new seeds.
25
        CurrentKeyDerivationVersion = KeyDerivationVersionTaproot
26

27
        // BIP0043Purpose is the "purpose" value that we'll use for the first
28
        // version or our key derivation scheme. All keys are expected to be
29
        // derived from this purpose, then the particular coin type of the
30
        // chain where the keys are to be used.  Slightly adhering to BIP0043
31
        // allows us to not deviate too far from a widely used standard, and
32
        // also fits into existing implementations of the BIP's template.
33
        //
34
        // NOTE: BRICK SQUUUUUAD.
35
        BIP0043Purpose = 1017
36
)
37

38
// IsKnownVersion returns true if the given version is one of the known
39
// derivation scheme versions as defined by this package.
UNCOV
40
func IsKnownVersion(internalVersion uint8) bool {
×
UNCOV
41
        return internalVersion == KeyDerivationVersionLegacy ||
×
UNCOV
42
                internalVersion == KeyDerivationVersionTaproot
×
UNCOV
43
}
×
44

45
var (
46
        // MaxKeyRangeScan is the maximum number of keys that we'll attempt to
47
        // scan with if a caller knows the public key, but not the KeyLocator
48
        // and wishes to derive a private key.
49
        MaxKeyRangeScan = 100000
50

51
        // ErrCannotDerivePrivKey is returned when DerivePrivKey is unable to
52
        // derive a private key given only the public key and target key
53
        // family.
54
        ErrCannotDerivePrivKey = fmt.Errorf("unable to derive private key")
55
)
56

57
// KeyFamily represents a "family" of keys that will be used within various
58
// contracts created by lnd. These families are meant to be distinct branches
59
// within the HD key chain of the backing wallet. Usage of key families within
60
// the interface below are strict in order to promote integrability and the
61
// ability to restore all keys given a user master seed backup.
62
//
63
// The key derivation in this file follows the following hierarchy based on
64
// BIP43:
65
//
66
//   - m/1017'/coinType'/keyFamily'/0/index
67
type KeyFamily uint32
68

69
const (
70
        // KeyFamilyMultiSig are keys to be used within multi-sig scripts.
71
        KeyFamilyMultiSig KeyFamily = 0
72

73
        // KeyFamilyRevocationBase are keys that are used within channels to
74
        // create revocation basepoints that the remote party will use to
75
        // create revocation keys for us.
76
        KeyFamilyRevocationBase KeyFamily = 1
77

78
        // KeyFamilyHtlcBase are keys used within channels that will be
79
        // combined with per-state randomness to produce public keys that will
80
        // be used in HTLC scripts.
81
        KeyFamilyHtlcBase KeyFamily = 2
82

83
        // KeyFamilyPaymentBase are keys used within channels that will be
84
        // combined with per-state randomness to produce public keys that will
85
        // be used in scripts that pay directly to us without any delay.
86
        KeyFamilyPaymentBase KeyFamily = 3
87

88
        // KeyFamilyDelayBase are keys used within channels that will be
89
        // combined with per-state randomness to produce public keys that will
90
        // be used in scripts that pay to us, but require a CSV delay before we
91
        // can sweep the funds.
92
        KeyFamilyDelayBase KeyFamily = 4
93

94
        // KeyFamilyRevocationRoot is a family of keys which will be used to
95
        // derive the root of a revocation tree for a particular channel.
96
        KeyFamilyRevocationRoot KeyFamily = 5
97

98
        // KeyFamilyNodeKey is a family of keys that will be used to derive
99
        // keys that will be advertised on the network to represent our current
100
        // "identity" within the network. Peers will need our latest node key
101
        // in order to establish a transport session with us on the Lightning
102
        // p2p level (BOLT-0008).
103
        KeyFamilyNodeKey KeyFamily = 6
104

105
        // KeyFamilyBaseEncryption is the family of keys that will be used to
106
        // derive keys that we use to encrypt and decrypt any general blob data
107
        // like static channel backups and the TLS private key. Often used when
108
        // encrypting files on disk.
109
        KeyFamilyBaseEncryption KeyFamily = 7
110

111
        // KeyFamilyTowerSession is the family of keys that will be used to
112
        // derive session keys when negotiating sessions with watchtowers. The
113
        // session keys are limited to the lifetime of the session and are used
114
        // to increase privacy in the watchtower protocol.
115
        KeyFamilyTowerSession KeyFamily = 8
116

117
        // KeyFamilyTowerID is the family of keys used to derive the public key
118
        // of a watchtower. This made distinct from the node key to offer a form
119
        // of rudimentary whitelisting, i.e. via knowledge of the pubkey,
120
        // preventing others from having full access to the tower just as a
121
        // result of knowing the node key.
122
        KeyFamilyTowerID KeyFamily = 9
123
)
124

125
// VersionZeroKeyFamilies is a slice of all the known key families for first
126
// version of the key derivation schema defined in this package.
127
var VersionZeroKeyFamilies = []KeyFamily{
128
        KeyFamilyMultiSig,
129
        KeyFamilyRevocationBase,
130
        KeyFamilyHtlcBase,
131
        KeyFamilyPaymentBase,
132
        KeyFamilyDelayBase,
133
        KeyFamilyRevocationRoot,
134
        KeyFamilyNodeKey,
135
        KeyFamilyBaseEncryption,
136
        KeyFamilyTowerSession,
137
        KeyFamilyTowerID,
138
}
139

140
// KeyLocator is a two-tuple that can be used to derive *any* key that has ever
141
// been used under the key derivation mechanisms described in this file.
142
// Version 0 of our key derivation schema uses the following BIP43-like
143
// derivation:
144
//
145
//   - m/1017'/coinType'/keyFamily'/0/index
146
//
147
// Our purpose is 1017 (chosen arbitrary for now), and the coin type will vary
148
// based on which coin/chain the channels are being created on. The key family
149
// are actually just individual "accounts" in the nomenclature of BIP43. By
150
// default we assume a branch of 0 (external). Finally, the key index (which
151
// will vary per channel and use case) is the final element which allows us to
152
// deterministically derive keys.
153
type KeyLocator struct {
154
        // TODO(roasbeef): add the key scope as well??
155

156
        // Family is the family of key being identified.
157
        Family KeyFamily
158

159
        // Index is the precise index of the key being identified.
160
        Index uint32
161
}
162

163
// IsEmpty returns true if a KeyLocator is "empty". This may be the case where
164
// we learn of a key from a remote party for a contract, but don't know the
165
// precise details of its derivation (as we don't know the private key!).
166
func (k KeyLocator) IsEmpty() bool {
1,100✔
167
        return k.Family == 0 && k.Index == 0
1,100✔
168
}
1,100✔
169

170
// KeyDescriptor wraps a KeyLocator and also optionally includes a public key.
171
// Either the KeyLocator must be non-empty, or the public key pointer be
172
// non-nil. This will be used by the KeyRing interface to lookup arbitrary
173
// private keys, and also within the SignDescriptor struct to locate precisely
174
// which keys should be used for signing.
175
type KeyDescriptor struct {
176
        // KeyLocator is the internal KeyLocator of the descriptor.
177
        KeyLocator
178

179
        // PubKey is an optional public key that fully describes a target key.
180
        // If this is nil, the KeyLocator MUST NOT be empty.
181
        PubKey *btcec.PublicKey
182
}
183

184
// KeyRing is the primary interface that will be used to perform public
185
// derivation of various keys used within the peer-to-peer network, and also
186
// within any created contracts. All derivation required by the KeyRing is
187
// based off of public derivation, so a system with only an extended public key
188
// (for the particular purpose+family) can derive this set of keys.
189
type KeyRing interface {
190
        // DeriveNextKey attempts to derive the *next* key within the key
191
        // family (account in BIP43) specified. This method should return the
192
        // next external child within this branch.
193
        DeriveNextKey(keyFam KeyFamily) (KeyDescriptor, error)
194

195
        // DeriveKey attempts to derive an arbitrary key specified by the
196
        // passed KeyLocator. This may be used in several recovery scenarios,
197
        // or when manually rotating something like our current default node
198
        // key.
199
        DeriveKey(keyLoc KeyLocator) (KeyDescriptor, error)
200
}
201

202
// SecretKeyRing is a ring similar to the regular KeyRing interface, but it is
203
// also able to derive *private keys*. As this is a super-set of the regular
204
// KeyRing, we also expect the SecretKeyRing to implement the fully KeyRing
205
// interface. The methods in this struct may be used to extract the node key in
206
// order to accept inbound network connections, or to do manual signing for
207
// recovery purposes.
208
type SecretKeyRing interface {
209
        KeyRing
210

211
        ECDHRing
212

213
        MessageSignerRing
214

215
        // DerivePrivKey attempts to derive the private key that corresponds to
216
        // the passed key descriptor.  If the public key is set, then this
217
        // method will perform an in-order scan over the key set, with a max of
218
        // MaxKeyRangeScan keys. In order for this to work, the caller MUST set
219
        // the KeyFamily within the partially populated KeyLocator.
220
        DerivePrivKey(keyDesc KeyDescriptor) (*btcec.PrivateKey, error)
221
}
222

223
// MessageSignerRing is an interface that abstracts away basic low-level ECDSA
224
// signing on keys within a key ring.
225
type MessageSignerRing interface {
226
        // SignMessage signs the given message, single or double SHA256 hashing
227
        // it first, with the private key described in the key locator.
228
        SignMessage(keyLoc KeyLocator, msg []byte,
229
                doubleHash bool) (*ecdsa.Signature, error)
230

231
        // SignMessageCompact signs the given message, single or double SHA256
232
        // hashing it first, with the private key described in the key locator
233
        // and returns the signature in the compact, public key recoverable
234
        // format.
235
        SignMessageCompact(keyLoc KeyLocator, msg []byte,
236
                doubleHash bool) ([]byte, error)
237

238
        // SignMessageSchnorr signs the given message, single or double SHA256
239
        // hashing it first, with the private key described in the key locator
240
        // and the optional Taproot tweak applied to the private key.
241
        SignMessageSchnorr(keyLoc KeyLocator, msg []byte,
242
                doubleHash bool, taprootTweak []byte,
243
                tag []byte) (*schnorr.Signature, error)
244
}
245

246
// SingleKeyMessageSigner is an abstraction interface that hides the
247
// implementation of the low-level ECDSA signing operations by wrapping a
248
// single, specific private key.
249
type SingleKeyMessageSigner interface {
250
        // PubKey returns the public key of the wrapped private key.
251
        PubKey() *btcec.PublicKey
252

253
        // KeyLocator returns the locator that describes the wrapped private
254
        // key.
255
        KeyLocator() KeyLocator
256

257
        // SignMessage signs the given message, single or double SHA256 hashing
258
        // it first, with the wrapped private key.
259
        SignMessage(message []byte, doubleHash bool) (*ecdsa.Signature, error)
260

261
        // SignMessageCompact signs the given message, single or double SHA256
262
        // hashing it first, with the wrapped private key and returns the
263
        // signature in the compact, public key recoverable format.
264
        SignMessageCompact(message []byte, doubleHash bool) ([]byte, error)
265
}
266

267
// ECDHRing is an interface that abstracts away basic low-level ECDH shared key
268
// generation on keys within a key ring.
269
type ECDHRing interface {
270
        // ECDH performs a scalar multiplication (ECDH-like operation) between
271
        // the target key descriptor and remote public key. The output
272
        // returned will be the sha256 of the resulting shared point serialized
273
        // in compressed format. If k is our private key, and P is the public
274
        // key, we perform the following operation:
275
        //
276
        //  sx := k*P
277
        //  s := sha256(sx.SerializeCompressed())
278
        ECDH(keyDesc KeyDescriptor, pubKey *btcec.PublicKey) ([32]byte, error)
279
}
280

281
// SingleKeyECDH is an abstraction interface that hides the implementation of an
282
// ECDH operation by wrapping a single, specific private key.
283
type SingleKeyECDH interface {
284
        // PubKey returns the public key of the wrapped private key.
285
        PubKey() *btcec.PublicKey
286

287
        // ECDH performs a scalar multiplication (ECDH-like operation) between
288
        // the wrapped private key and remote public key. The output returned
289
        // will be the sha256 of the resulting shared point serialized in
290
        // compressed format.
291
        ECDH(pubKey *btcec.PublicKey) ([32]byte, error)
292
}
293

294
// TODO(roasbeef): extend to actually support scalar mult of key?
295
//  * would allow to push in initial handshake auth into interface as well
STATUS · Troubleshooting · Open an Issue · Sales · Support · CAREERS · ENTERPRISE · START FREE · SCHEDULE DEMO
ANNOUNCEMENTS · TWITTER · TOS & SLA · Supported CI Services · What's a CI service? · Automated Testing

© 2025 Coveralls, Inc