forked from lightningnetwork/lightning-onion
-
Notifications
You must be signed in to change notification settings - Fork 0
/
packetfiller.go
61 lines (51 loc) · 2.2 KB
/
packetfiller.go
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
package sphinx
import (
"crypto/rand"
"github.com/aead/chacha20"
"github.com/ltcsuite/ltcd/btcec/v2"
)
// PacketFiller is a function type to be specified by the caller to provide a
// stream of random bytes derived from a CSPRNG to fill out the starting packet
// in order to ensure we don't leak information on the true route length to the
// receiver. The packet filler may also use the session key to generate a set
// of filler bytes if it wishes to be deterministic.
type PacketFiller func(*btcec.PrivateKey, *[routingInfoSize]byte) error
// RandPacketFiller is a packet filler that reads a set of random bytes from a
// CSPRNG.
func RandPacketFiller(_ *btcec.PrivateKey, mixHeader *[routingInfoSize]byte) error {
// Read out random bytes to fill out the rest of the starting packet
// after the hop payload for the final node. This mitigates a privacy
// leak that may reveal a lower bound on the true path length to the
// receiver.
if _, err := rand.Read(mixHeader[:]); err != nil {
return err
}
return nil
}
// BlankPacketFiller is a packet filler that doesn't attempt to fill out the
// packet at all. It should ONLY be used for generating test vectors or other
// instances that required deterministic packet generation.
func BlankPacketFiller(_ *btcec.PrivateKey, _ *[routingInfoSize]byte) error {
return nil
}
// DeterministicPacketFiller is a packet filler that generates a deterministic
// set of filler bytes by using chacha20 with a key derived from the session
// key.
func DeterministicPacketFiller(sessionKey *btcec.PrivateKey,
mixHeader *[routingInfoSize]byte) error {
// First, we'll generate a new key that'll be used to generate some
// random bytes for our padding purposes. To derive this new key, we
// essentially calculate: HMAC("pad", sessionKey).
var sessionKeyBytes Hash256
copy(sessionKeyBytes[:], sessionKey.Serialize())
paddingKey := generateKey("pad", &sessionKeyBytes)
// Now that we have our target key, we'll use chacha20 to generate a
// series of random bytes directly into the passed mixHeader packet.
var nonce [8]byte
padCipher, err := chacha20.NewCipher(nonce[:], paddingKey[:])
if err != nil {
return err
}
padCipher.XORKeyStream(mixHeader[:], mixHeader[:])
return nil
}