Skip to content

Commit 306f18b

Browse files
committed
sphinx: OnionObfuscator -> OnionErrorEncrypter, OnionDeobfuscator -> OnionErrorDecrypter
1 parent a6d3a55 commit 306f18b

File tree

2 files changed

+58
-64
lines changed

2 files changed

+58
-64
lines changed

obfuscation.go

Lines changed: 44 additions & 50 deletions
Original file line numberDiff line numberDiff line change
@@ -10,56 +10,54 @@ import (
1010
"github.com/roasbeef/btcd/btcec"
1111
)
1212

13-
// onionObfuscation obfuscates the data with compliance with BOLT#4.
14-
//
15-
// In context of Lightning Network this function is used by sender to obfuscate
16-
// the onion failure and by receiver to unwrap the failure data.
17-
func onionObfuscation(sharedSecret [sha256.Size]byte,
18-
data []byte) []byte {
19-
obfuscatedData := make([]byte, len(data))
13+
// onionEncrypt obfuscates the data with compliance with BOLT#4. As we use a
14+
// stream cipher, calling onionEncrypt on an already encrypted piece of data
15+
// will decrypt it.
16+
func onionEncrypt(sharedSecret [sha256.Size]byte, data []byte) []byte {
17+
18+
p := make([]byte, len(data))
2019

2120
ammagKey := generateKey("ammag", sharedSecret)
2221
streamBytes := generateCipherStream(ammagKey, uint(len(data)))
23-
xor(obfuscatedData, data, streamBytes)
24-
return obfuscatedData
22+
xor(p, data, streamBytes)
23+
24+
return p
2525
}
2626

27-
// OnionObfuscator represent serializable object which is able to convert the
28-
// data to the obfuscated blob, by applying the stream of data generated by
29-
// the shared secret.
30-
//
31-
// In context of Lightning Network the obfuscated data is usually a failure
32-
// which will be propagated back to payment sender, and obfuscated by the
33-
// forwarding nodes.
34-
type OnionObfuscator struct {
27+
// OnionErrorEncrypter is a struct that's used to implement onion error
28+
// encryption as defined within BOLT0004.
29+
type OnionErrorEncrypter struct {
3530
sharedSecret [sha256.Size]byte
3631
}
3732

38-
// NewOnionObfuscator creates new instance of onion obfuscator.
39-
func NewOnionObfuscator(router *Router, ephemeralKey *btcec.PublicKey) (*OnionObfuscator,
40-
error) {
33+
// NewOnionErrorEncrypter creates new instance of the onion encryper backed by
34+
// the passed router, with encryption to be doing using the passed
35+
// ephemeralKey.
36+
func NewOnionErrorEncrypter(router *Router,
37+
ephemeralKey *btcec.PublicKey) (*OnionErrorEncrypter, error) {
4138

4239
sharedSecret, err := router.generateSharedSecret(ephemeralKey)
4340
if err != nil {
4441
return nil, err
4542
}
4643

47-
return &OnionObfuscator{
44+
return &OnionErrorEncrypter{
4845
sharedSecret: sharedSecret,
4946
}, nil
5047
}
5148

52-
// Obfuscate is used to make data obfuscation using the generated shared secret.
49+
// EncryptError is used to make data obfuscation using the generated shared
50+
// secret.
5351
//
54-
// In context of Lightning Network is either used by the nodes in order to
55-
// make initial obfuscation with the creation of the hmac or by the forwarding
56-
// nodes for backward failure obfuscation of the onion failure blob. By
57-
// obfuscating the onion failure on every node in the path we are adding
58-
// additional step of the security and barrier for malware nodes to retrieve
59-
// valuable information. The reason for using onion obfuscation is to not give
60-
// away to the nodes in the payment path the information about the exact failure
61-
// and its origin.
62-
func (o *OnionObfuscator) Obfuscate(initial bool, data []byte) []byte {
52+
// In context of Lightning Network is either used by the nodes in order to make
53+
// initial obfuscation with the creation of the hmac or by the forwarding nodes
54+
// for backward failure obfuscation of the onion failure blob. By obfuscating
55+
// the onion failure on every node in the path we are adding additional step of
56+
// the security and barrier for malware nodes to retrieve valuable information.
57+
// The reason for using onion obfuscation is to not give
58+
// away to the nodes in the payment path the information about the exact
59+
// failure and its origin.
60+
func (o *OnionErrorEncrypter) EncryptError(initial bool, data []byte) []byte {
6361
if initial {
6462
umKey := generateKey("um", o.sharedSecret)
6563
hash := hmac.New(sha256.New, umKey[:])
@@ -68,9 +66,7 @@ func (o *OnionObfuscator) Obfuscate(initial bool, data []byte) []byte {
6866
data = append(h, data...)
6967
}
7068

71-
return onionObfuscation(o.sharedSecret, data)
72-
}
73-
69+
return onionEncrypt(o.sharedSecret, data)
7470
}
7571

7672
// Circuit is used encapsulate the data which is needed for data deobfuscation.
@@ -145,26 +141,24 @@ func (c *Circuit) Encode(w io.Writer) error {
145141
return nil
146142
}
147143

148-
// OnionDeobfuscator represents the serializable object which encapsulate the
149-
// all necessary data to properly de-obfuscate previously obfuscated data.
150-
// In context of Lightning Network the data which have to be deobfuscated
151-
// usually is onion failure.
152-
type OnionDeobfuscator struct {
144+
// OnionErrorDecrypter is a struct that's used to decrypt onion errors in
145+
// response to failed HTLC routing attempts according to BOLT#4.
146+
type OnionErrorDecrypter struct {
153147
circuit *Circuit
154148
}
155149

156-
// NewOnionDeobfuscator creates new instance of onion deobfuscator.
157-
func NewOnionDeobfuscator(circuit *Circuit) *OnionDeobfuscator {
158-
return &OnionDeobfuscator{
150+
// NewOnionErrorDecrypter creates new instance of onion decrypter.
151+
func NewOnionErrorDecrypter(circuit *Circuit) *OnionErrorDecrypter {
152+
return &OnionErrorDecrypter{
159153
circuit: circuit,
160154
}
161155
}
162156

163-
// Deobfuscate makes data deobfuscation. The onion failure is obfuscated in
164-
// backward manner, starting from the node where error have occurred, so in
165-
// order to deobfuscate the error we need get all shared secret and apply
166-
// obfuscation in reverse order.
167-
func (o *OnionDeobfuscator) Deobfuscate(obfuscatedData []byte) (*btcec.PublicKey, []byte, error) {
157+
// DecryptError attempts to decrypt the passed encrypted error response. The
158+
// onion failure is encrypted in backward manner, starting from the node where
159+
// error have occurred. As a result, in order to decrypt the error we need get
160+
// all shared secret and apply decryption in the reverse order.
161+
func (o *OnionErrorDecrypter) DecryptError(encryptedData []byte) (*btcec.PublicKey, []byte, error) {
168162

169163
sharedSecrets := generateSharedSecrets(
170164
o.circuit.PaymentPath,
@@ -196,12 +190,12 @@ func (o *OnionDeobfuscator) Deobfuscate(obfuscatedData []byte) (*btcec.PublicKey
196190

197191
// With the shared secret, we'll now strip off a layer of
198192
// encryption from the encrypted error payload.
199-
obfuscatedData = onionObfuscation(sharedSecret, obfuscatedData)
193+
encryptedData = onionEncrypt(sharedSecret, encryptedData)
200194

201195
// Next, we'll need to separate the data, from the MAC itself
202196
// so we can reconstruct and verify it.
203-
expectedMac := obfuscatedData[:sha256.Size]
204-
data := obfuscatedData[sha256.Size:]
197+
expectedMac := encryptedData[:sha256.Size]
198+
data := encryptedData[sha256.Size:]
205199

206200
// With the data split, we'll now re-generate the MAC using its
207201
// specified key.

obfuscation_test.go

Lines changed: 14 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -31,33 +31,33 @@ func TestOnionFailure(t *testing.T) {
3131
sharedSecrets := generateSharedSecrets(paymentPath, sessionKey)
3232

3333
// Emulate creation of the obfuscator on node where error have occurred.
34-
obfuscator := &OnionObfuscator{
34+
obfuscator := &OnionErrorEncrypter{
3535
sharedSecret: sharedSecrets[len(errorPath)-1],
3636
}
3737

3838
// Emulate the situation when last hop creates the onion failure
3939
// message and send it back.
40-
obfuscatedData := obfuscator.Obfuscate(true, failureData)
40+
obfuscatedData := obfuscator.EncryptError(true, failureData)
4141

4242
// Emulate that failure message is backward obfuscated on every hop.
4343
for i := len(errorPath) - 2; i >= 0; i-- {
4444
// Emulate creation of the obfuscator on forwarding node which
4545
// propagates the onion failure.
46-
obfuscator = &OnionObfuscator{
46+
obfuscator = &OnionErrorEncrypter{
4747
sharedSecret: sharedSecrets[i],
4848
}
49-
obfuscatedData = obfuscator.Obfuscate(false, obfuscatedData)
49+
obfuscatedData = obfuscator.EncryptError(false, obfuscatedData)
5050
}
5151

5252
// Emulate creation of the deobfuscator on the receiving onion error side.
53-
deobfuscator := NewOnionDeobfuscator(&Circuit{
53+
deobfuscator := NewOnionErrorDecrypter(&Circuit{
5454
SessionKey: sessionKey,
5555
PaymentPath: paymentPath,
5656
})
5757

5858
// Emulate that sender node receive the failure message and trying to
5959
// unwrap it, by applying obfuscation and checking the hmac.
60-
pubKey, deobfuscatedData, err := deobfuscator.Deobfuscate(obfuscatedData)
60+
pubKey, deobfuscatedData, err := deobfuscator.DecryptError(obfuscatedData)
6161
if err != nil {
6262
t.Fatalf("unable to de-obfuscate the onion failure: %v", err)
6363
}
@@ -197,7 +197,7 @@ func TestOnionFailureSpecVector(t *testing.T) {
197197
t.Fatalf("unable to decode spec shared secret: %v",
198198
err)
199199
}
200-
obfuscator := &OnionObfuscator{
200+
obfuscator := &OnionErrorEncrypter{
201201
sharedSecret: sharedSecrets[len(sharedSecrets)-1-i],
202202
}
203203

@@ -210,35 +210,35 @@ func TestOnionFailureSpecVector(t *testing.T) {
210210
if i == 0 {
211211
// Emulate the situation when last hop creates the onion failure
212212
// message and send it back.
213-
obfuscatedData = obfuscator.Obfuscate(true, failureData)
213+
obfuscatedData = obfuscator.EncryptError(true, failureData)
214214
} else {
215215
// Emulate the situation when forward node obfuscates
216216
// the onion failure.
217-
obfuscatedData = obfuscator.Obfuscate(false, obfuscatedData)
217+
obfuscatedData = obfuscator.EncryptError(false, obfuscatedData)
218218
}
219219

220220
// Decode the obfuscated data and check that it matches the
221221
// specification.
222-
expectedObfuscatedData, err := hex.DecodeString(test.obfuscatedData)
222+
expectedEncryptErrordData, err := hex.DecodeString(test.obfuscatedData)
223223
if err != nil {
224224
t.Fatalf("unable to decode spec obfusacted "+
225225
"data: %v", err)
226226
}
227-
if !bytes.Equal(expectedObfuscatedData, obfuscatedData) {
227+
if !bytes.Equal(expectedEncryptErrordData, obfuscatedData) {
228228
t.Fatalf("obfuscated data not match spec: expected %x, "+
229-
"got %x", expectedObfuscatedData[:],
229+
"got %x", expectedEncryptErrordData[:],
230230
obfuscatedData[:])
231231
}
232232
}
233233

234-
deobfuscator := NewOnionDeobfuscator(&Circuit{
234+
deobfuscator := NewOnionErrorDecrypter(&Circuit{
235235
SessionKey: sessionKey,
236236
PaymentPath: paymentPath,
237237
})
238238

239239
// Emulate that sender node receives the failure message and trying to
240240
// unwrap it, by applying obfuscation and checking the hmac.
241-
pubKey, deobfuscatedData, err := deobfuscator.Deobfuscate(obfuscatedData)
241+
pubKey, deobfuscatedData, err := deobfuscator.DecryptError(obfuscatedData)
242242
if err != nil {
243243
t.Fatalf("unable to de-obfuscate the onion failure: %v", err)
244244
}

0 commit comments

Comments
 (0)