11package sphinx
22
33import (
4- "bytes"
54 "crypto/hmac"
65 "crypto/sha256"
76 "errors"
@@ -11,6 +10,7 @@ import (
1110)
1211
1312// onionObfuscation obfuscates the data with compliance with BOLT#4.
13+ //
1414// In context of Lightning Network this function is used by sender to obfuscate
1515// the onion failure and by receiver to unwrap the failure data.
1616func onionObfuscation (sharedSecret [sha256 .Size ]byte ,
@@ -23,7 +23,9 @@ func onionObfuscation(sharedSecret [sha256.Size]byte,
2323}
2424
2525// OnionObfuscator represent serializable object which is able to convert the
26- // data to the obfuscated blob.
26+ // data to the obfuscated blob, by applying the stream of data generated by
27+ // the shared secret.
28+ //
2729// In context of Lightning Network the obfuscated data is usually a failure
2830// which will be propagated back to payment sender, and obfuscated by the
2931// forwarding nodes.
@@ -45,7 +47,8 @@ func NewOnionObfuscator(router *Router, ephemeralKey *btcec.PublicKey) (*OnionOb
4547 }, nil
4648}
4749
48- // Obfuscate is used to make data obfuscation.
50+ // Obfuscate is used to make data obfuscation using the generated shared secret.
51+ //
4952// In context of Lightning Network is either used by the nodes in order to
5053// make initial obfuscation with the creation of the hmac or by the forwarding
5154// nodes for backward failure obfuscation of the onion failure blob. By
@@ -78,54 +81,18 @@ func (o *OnionObfuscator) Encode(w io.Writer) error {
7881 return err
7982}
8083
81- // OnionDeobfuscator represents the serializable object which encapsulate the
82- // all necessary data to properly de-obfuscate previously obfuscated data.
83- // In context of Lightning Network the data which have to be deobfuscated
84- // usually is onion failure.
85- type OnionDeobfuscator struct {
86- sessionKey * btcec.PrivateKey
87- paymentPath []* btcec.PublicKey
88- }
84+ // Circuit is used encapsulate the data which is needed for data deobfuscation.
85+ type Circuit struct {
86+ // SessionKey is the key which have been used during generation of the
87+ // shared secrets.
88+ SessionKey * btcec.PrivateKey
8989
90- // NewOnionDeobfuscator creates new instance of onion deobfuscator.
91- func NewOnionDeobfuscator (sessionKey * btcec.PrivateKey ,
92- paymentPath []* btcec.PublicKey ) (* OnionDeobfuscator , error ) {
93- return & OnionDeobfuscator {
94- sessionKey : sessionKey ,
95- paymentPath : paymentPath ,
96- }, nil
90+ // PaymentPath is the pub keys of the nodes in the payment path.
91+ PaymentPath []* btcec.PublicKey
9792}
9893
99- // Deobfuscate makes data deobfuscation. The onion failure is obfuscated in
100- // backward manner, starting from the node where error have occurred, so in
101- // order to deobfuscate the error we need get all shared secret and apply
102- // obfuscation in reverse order.
103- func (o * OnionDeobfuscator ) Deobfuscate (obfuscatedData []byte ) (* btcec.PublicKey ,
104- []byte , error ) {
105- for i , sharedSecret := range generateSharedSecrets (o .paymentPath ,
106- o .sessionKey ) {
107- obfuscatedData = onionObfuscation (sharedSecret , obfuscatedData )
108- umKey := generateKey ("um" , sharedSecret )
109-
110- // Split the data and hmac.
111- expectedMac := obfuscatedData [:sha256 .Size ]
112- data := obfuscatedData [sha256 .Size :]
113-
114- // Calculate the real hmac.
115- h := hmac .New (sha256 .New , umKey [:])
116- h .Write (data )
117- realMac := h .Sum (nil )
118-
119- if bytes .Equal (realMac , expectedMac ) {
120- return o .paymentPath [i ], data , nil
121- }
122- }
123-
124- return nil , nil , errors .New ("unable to retrieve onion failure" )
125- }
126-
127- // Decode initializes the deobfuscator from the byte stream.
128- func (o * OnionDeobfuscator ) Decode (r io.Reader ) error {
94+ // Decode initializes the circuit from the byte stream.
95+ func (c * Circuit ) Decode (r io.Reader ) error {
12996 var keyLength [1 ]byte
13097 if _ , err := r .Read (keyLength [:]); err != nil {
13198 return err
@@ -136,14 +103,14 @@ func (o *OnionDeobfuscator) Decode(r io.Reader) error {
136103 return err
137104 }
138105
139- o . sessionKey , _ = btcec .PrivKeyFromBytes (btcec .S256 (), sessionKeyData )
106+ c . SessionKey , _ = btcec .PrivKeyFromBytes (btcec .S256 (), sessionKeyData )
140107 var pathLength [1 ]byte
141108 if _ , err := r .Read (pathLength [:]); err != nil {
142109 return err
143110 }
144- o . paymentPath = make ([]* btcec.PublicKey , uint8 (pathLength [0 ]))
111+ c . PaymentPath = make ([]* btcec.PublicKey , uint8 (pathLength [0 ]))
145112
146- for i := 0 ; i < len (o . paymentPath ); i ++ {
113+ for i := 0 ; i < len (c . PaymentPath ); i ++ {
147114 var pubKeyData [btcec .PubKeyBytesLenCompressed ]byte
148115 if _ , err := r .Read (pubKeyData [:]); err != nil {
149116 return err
@@ -153,35 +120,88 @@ func (o *OnionDeobfuscator) Decode(r io.Reader) error {
153120 if err != nil {
154121 return err
155122 }
156- o . paymentPath [i ] = pubKey
123+ c . PaymentPath [i ] = pubKey
157124 }
158125
159126 return nil
160127}
161128
162- // Encode writes converted deobfuscator in the byte stream.
163- func (o * OnionDeobfuscator ) Encode (w io.Writer ) error {
129+ // Encode writes converted circuit in the byte stream.
130+ func (c * Circuit ) Encode (w io.Writer ) error {
164131 var keyLength [1 ]byte
165- keyLength [0 ] = uint8 (len (o . sessionKey .Serialize ()))
132+ keyLength [0 ] = uint8 (len (c . SessionKey .Serialize ()))
166133 if _ , err := w .Write (keyLength [:]); err != nil {
167134 return err
168135 }
169136
170- if _ , err := w .Write (o . sessionKey .Serialize ()); err != nil {
137+ if _ , err := w .Write (c . SessionKey .Serialize ()); err != nil {
171138 return err
172139 }
173140
174141 var pathLength [1 ]byte
175- pathLength [0 ] = uint8 (len (o . paymentPath ))
142+ pathLength [0 ] = uint8 (len (c . PaymentPath ))
176143 if _ , err := w .Write (pathLength [:]); err != nil {
177144 return err
178145 }
179146
180- for _ , pubKey := range o . paymentPath {
147+ for _ , pubKey := range c . PaymentPath {
181148 if _ , err := w .Write (pubKey .SerializeCompressed ()); err != nil {
182149 return err
183150 }
184151 }
185152
186153 return nil
187154}
155+
156+ // OnionDeobfuscator represents the serializable object which encapsulate the
157+ // all necessary data to properly de-obfuscate previously obfuscated data.
158+ // In context of Lightning Network the data which have to be deobfuscated
159+ // usually is onion failure.
160+ type OnionDeobfuscator struct {
161+ circuit * Circuit
162+ }
163+
164+ // NewOnionDeobfuscator creates new instance of onion deobfuscator.
165+ func NewOnionDeobfuscator (circuit * Circuit ) * OnionDeobfuscator {
166+ return & OnionDeobfuscator {
167+ circuit : circuit ,
168+ }
169+ }
170+
171+ // Deobfuscate makes data deobfuscation. The onion failure is obfuscated in
172+ // backward manner, starting from the node where error have occurred, so in
173+ // order to deobfuscate the error we need get all shared secret and apply
174+ // obfuscation in reverse order.
175+ func (o * OnionDeobfuscator ) Deobfuscate (obfuscatedData []byte ) (* btcec.PublicKey ,
176+ []byte , error ) {
177+ for i , sharedSecret := range generateSharedSecrets (o .circuit .PaymentPath ,
178+ o .circuit .SessionKey ) {
179+ obfuscatedData = onionObfuscation (sharedSecret , obfuscatedData )
180+ umKey := generateKey ("um" , sharedSecret )
181+
182+ // Split the data and hmac.
183+ expectedMac := obfuscatedData [:sha256 .Size ]
184+ data := obfuscatedData [sha256 .Size :]
185+
186+ // Calculate the real hmac.
187+ h := hmac .New (sha256 .New , umKey [:])
188+ h .Write (data )
189+ realMac := h .Sum (nil )
190+
191+ if hmac .Equal (realMac , expectedMac ) {
192+ return o .circuit .PaymentPath [i ], data , nil
193+ }
194+ }
195+
196+ return nil , nil , errors .New ("unable to retrieve onion failure" )
197+ }
198+
199+ // Decode writes converted deobfucator in the byte stream.
200+ func (o * OnionDeobfuscator ) Decode (r io.Reader ) error {
201+ return o .circuit .Decode (r )
202+ }
203+
204+ // Encode writes converted deobfucator in the byte stream.
205+ func (o * OnionDeobfuscator ) Encode (w io.Writer ) error {
206+ return o .circuit .Encode (w )
207+ }
0 commit comments