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

lightningnetwork / lnd / 11216766535

07 Oct 2024 01:37PM UTC coverage: 57.817% (-1.0%) from 58.817%
11216766535

Pull #9148

github

ProofOfKeags
lnwire: remove kickoff feerate from propose/commit
Pull Request #9148: DynComms [2/n]: lnwire: add authenticated wire messages for Dyn*

571 of 879 new or added lines in 16 files covered. (64.96%)

23253 existing lines in 251 files now uncovered.

99022 of 171268 relevant lines covered (57.82%)

38420.67 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,116✔
167
        return k.Family == 0 && k.Index == 0
1,116✔
168
}
1,116✔
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