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

lightningnetwork / lnd / 13035292482

29 Jan 2025 03:59PM UTC coverage: 49.3% (-9.5%) from 58.777%
13035292482

Pull #9456

github

mohamedawnallah
docs: update release-notes-0.19.0.md

In this commit, we warn users about the removal
of RPCs `SendToRoute`, `SendToRouteSync`, `SendPayment`,
and `SendPaymentSync` in the next release 0.20.
Pull Request #9456: lnrpc+docs: deprecate warning `SendToRoute`, `SendToRouteSync`, `SendPayment`, and `SendPaymentSync` in Release 0.19

100634 of 204126 relevant lines covered (49.3%)

1.54 hits per line

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

60.26
/lnencrypt/crypto.go
1
package lnencrypt
2

3
import (
4
        "crypto/rand"
5
        "crypto/sha256"
6
        "fmt"
7
        "io"
8

9
        "github.com/btcsuite/btcd/btcec/v2"
10
        "github.com/lightningnetwork/lnd/keychain"
11
        "golang.org/x/crypto/chacha20poly1305"
12
)
13

14
// baseEncryptionKeyLoc is the KeyLocator that we'll use to derive the base
15
// encryption key used for encrypting all payloads. We use this to then
16
// derive the actual key that we'll use for encryption. We do this
17
// rather than using the raw key, as we assume that we can't obtain the raw
18
// keys, and we don't want to require that the HSM know our target cipher for
19
// encryption.
20
//
21
// TODO(roasbeef): possibly unique encrypt?
22
var baseEncryptionKeyLoc = keychain.KeyLocator{
23
        Family: keychain.KeyFamilyBaseEncryption,
24
        Index:  0,
25
}
26

27
// EncrypterDecrypter is an interface representing an object that encrypts or
28
// decrypts data.
29
type EncrypterDecrypter interface {
30
        // EncryptPayloadToWriter attempts to write the set of provided bytes
31
        // into the passed io.Writer in an encrypted form.
32
        EncryptPayloadToWriter([]byte, io.Writer) error
33

34
        // DecryptPayloadFromReader attempts to decrypt the encrypted bytes
35
        // within the passed io.Reader instance using the key derived from
36
        // the passed keyRing.
37
        DecryptPayloadFromReader(io.Reader) ([]byte, error)
38
}
39

40
// Encrypter is a struct responsible for encrypting and decrypting data.
41
type Encrypter struct {
42
        encryptionKey []byte
43
}
44

45
// KeyRingEncrypter derives an encryption key to encrypt all our files that are
46
// written to disk and returns an Encrypter object holding the key.
47
//
48
// The key itself, is the sha2 of a base key that we get from the keyring. We
49
// derive the key this way as we don't force the HSM (or any future
50
// abstractions) to be able to derive and know of the cipher that we'll use
51
// within our protocol.
52
func KeyRingEncrypter(keyRing keychain.KeyRing) (*Encrypter, error) {
3✔
53
        //  key = SHA256(baseKey)
3✔
54
        baseKey, err := keyRing.DeriveKey(
3✔
55
                baseEncryptionKeyLoc,
3✔
56
        )
3✔
57
        if err != nil {
3✔
58
                return nil, err
×
59
        }
×
60

61
        encryptionKey := sha256.Sum256(
3✔
62
                baseKey.PubKey.SerializeCompressed(),
3✔
63
        )
3✔
64

3✔
65
        // TODO(roasbeef): throw back in ECDH?
3✔
66

3✔
67
        return &Encrypter{
3✔
68
                encryptionKey: encryptionKey[:],
3✔
69
        }, nil
3✔
70
}
71

72
// ECDHEncrypter derives an encryption key by performing an ECDH operation on
73
// the passed keys. The resulting key is used to encrypt or decrypt files with
74
// sensitive content.
75
func ECDHEncrypter(localKey *btcec.PrivateKey,
76
        remoteKey *btcec.PublicKey) (*Encrypter, error) {
×
77

×
78
        ecdh := keychain.PrivKeyECDH{
×
79
                PrivKey: localKey,
×
80
        }
×
81
        encryptionKey, err := ecdh.ECDH(remoteKey)
×
82
        if err != nil {
×
83
                return nil, fmt.Errorf("error deriving encryption key: %w", err)
×
84
        }
×
85

86
        return &Encrypter{
×
87
                encryptionKey: encryptionKey[:],
×
88
        }, nil
×
89
}
90

91
// EncryptPayloadToWriter attempts to write the set of provided bytes into the
92
// passed io.Writer in an encrypted form. We use a 24-byte chachapoly AEAD
93
// instance with a randomized nonce that's pre-pended to the final payload and
94
// used as associated data in the AEAD.
95
func (e Encrypter) EncryptPayloadToWriter(payload []byte,
96
        w io.Writer) error {
3✔
97

3✔
98
        // Before encryption, we'll initialize our cipher with the target
3✔
99
        // encryption key, and also read out our random 24-byte nonce we use
3✔
100
        // for encryption. Note that we use NewX, not New, as the latter
3✔
101
        // version requires a 12-byte nonce, not a 24-byte nonce.
3✔
102
        cipher, err := chacha20poly1305.NewX(e.encryptionKey)
3✔
103
        if err != nil {
3✔
104
                return err
×
105
        }
×
106
        var nonce [chacha20poly1305.NonceSizeX]byte
3✔
107
        if _, err := rand.Read(nonce[:]); err != nil {
3✔
108
                return err
×
109
        }
×
110

111
        // Finally, we encrypted the final payload, and write out our
112
        // ciphertext with nonce pre-pended.
113
        ciphertext := cipher.Seal(nil, nonce[:], payload, nonce[:])
3✔
114

3✔
115
        if _, err := w.Write(nonce[:]); err != nil {
3✔
116
                return err
×
117
        }
×
118
        if _, err := w.Write(ciphertext); err != nil {
3✔
119
                return err
×
120
        }
×
121

122
        return nil
3✔
123
}
124

125
// DecryptPayloadFromReader attempts to decrypt the encrypted bytes within the
126
// passed io.Reader instance using the key derived from the passed keyRing. For
127
// further details regarding the key derivation protocol, see the
128
// KeyRingEncrypter function.
129
func (e Encrypter) DecryptPayloadFromReader(payload io.Reader) ([]byte,
130
        error) {
3✔
131

3✔
132
        // Next, we'll read out the entire blob as we need to isolate the nonce
3✔
133
        // from the rest of the ciphertext.
3✔
134
        packedPayload, err := io.ReadAll(payload)
3✔
135
        if err != nil {
3✔
136
                return nil, err
×
137
        }
×
138
        if len(packedPayload) < chacha20poly1305.NonceSizeX {
3✔
139
                return nil, fmt.Errorf("payload size too small, must be at "+
×
140
                        "least %v bytes", chacha20poly1305.NonceSizeX)
×
141
        }
×
142

143
        nonce := packedPayload[:chacha20poly1305.NonceSizeX]
3✔
144
        ciphertext := packedPayload[chacha20poly1305.NonceSizeX:]
3✔
145

3✔
146
        // Now that we have the cipher text and the nonce separated, we can go
3✔
147
        // ahead and decrypt the final blob so we can properly serialize.
3✔
148
        cipher, err := chacha20poly1305.NewX(e.encryptionKey)
3✔
149
        if err != nil {
3✔
150
                return nil, err
×
151
        }
×
152
        plaintext, err := cipher.Open(nil, nonce, ciphertext, nonce)
3✔
153
        if err != nil {
3✔
154
                return nil, err
×
155
        }
×
156

157
        return plaintext, nil
3✔
158
}
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