-
Notifications
You must be signed in to change notification settings - Fork 127
/
obfuscation.go
132 lines (108 loc) · 3.25 KB
/
obfuscation.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
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
package sphinx
import (
"io"
"github.com/btcsuite/btcd/btcec/v2"
)
// OnionErrorEncrypter is a struct that's used to implement onion error
// encryption as defined within BOLT0004.
type OnionErrorEncrypter struct {
sharedSecret Hash256
}
// NewOnionErrorEncrypter creates new instance of the onion encrypter backed by
// the passed router, with encryption to be done using the passed ephemeralKey.
func NewOnionErrorEncrypter(router *Router, ephemeralKey *btcec.PublicKey,
opts ...ProcessOnionOpt) (*OnionErrorEncrypter, error) {
cfg := &processOnionCfg{}
for _, o := range opts {
o(cfg)
}
sharedSecret, err := router.generateSharedSecret(
ephemeralKey, cfg.blindingPoint,
)
if err != nil {
return nil, err
}
return &OnionErrorEncrypter{
sharedSecret: sharedSecret,
}, nil
}
// Encode writes the encrypter's shared secret to the provided io.Writer.
func (o *OnionErrorEncrypter) Encode(w io.Writer) error {
_, err := w.Write(o.sharedSecret[:])
return err
}
// Decode restores the encrypter's share secret from the provided io.Reader.
func (o *OnionErrorEncrypter) Decode(r io.Reader) error {
_, err := io.ReadFull(r, o.sharedSecret[:])
return err
}
// Circuit is used encapsulate the data which is needed for data deobfuscation.
type Circuit struct {
// SessionKey is the key which have been used during generation of the
// shared secrets.
SessionKey *btcec.PrivateKey
// PaymentPath is the pub keys of the nodes in the payment path.
PaymentPath []*btcec.PublicKey
}
// Decode initializes the circuit from the byte stream.
func (c *Circuit) Decode(r io.Reader) error {
var keyLength [1]byte
if _, err := r.Read(keyLength[:]); err != nil {
return err
}
sessionKeyData := make([]byte, uint8(keyLength[0]))
if _, err := r.Read(sessionKeyData[:]); err != nil {
return err
}
c.SessionKey, _ = btcec.PrivKeyFromBytes(sessionKeyData)
var pathLength [1]byte
if _, err := r.Read(pathLength[:]); err != nil {
return err
}
c.PaymentPath = make([]*btcec.PublicKey, uint8(pathLength[0]))
for i := 0; i < len(c.PaymentPath); i++ {
var pubKeyData [btcec.PubKeyBytesLenCompressed]byte
if _, err := r.Read(pubKeyData[:]); err != nil {
return err
}
pubKey, err := btcec.ParsePubKey(pubKeyData[:])
if err != nil {
return err
}
c.PaymentPath[i] = pubKey
}
return nil
}
// Encode writes converted circuit in the byte stream.
func (c *Circuit) Encode(w io.Writer) error {
var keyLength [1]byte
keyLength[0] = uint8(len(c.SessionKey.Serialize()))
if _, err := w.Write(keyLength[:]); err != nil {
return err
}
if _, err := w.Write(c.SessionKey.Serialize()); err != nil {
return err
}
var pathLength [1]byte
pathLength[0] = uint8(len(c.PaymentPath))
if _, err := w.Write(pathLength[:]); err != nil {
return err
}
for _, pubKey := range c.PaymentPath {
if _, err := w.Write(pubKey.SerializeCompressed()); err != nil {
return err
}
}
return nil
}
// OnionErrorDecrypter is a struct that's used to decrypt onion errors in
// response to failed HTLC routing attempts according to BOLT#4.
type OnionErrorDecrypter struct {
circuit *Circuit
}
// NewOnionErrorDecrypter creates new instance of onion decrypter.
func NewOnionErrorDecrypter(circuit *Circuit) *OnionErrorDecrypter {
return &OnionErrorDecrypter{
circuit: circuit,
}
}