@@ -45,9 +45,9 @@ func (e EncrypterType) IsBlinded() bool {
4545 return e == EncrypterTypeIntroduction || e == EncrypterTypeRelaying
4646}
4747
48- // ErrorEncrypterExtracter defines a function signature that extracts an
49- // ErrorEncrypter from an sphinx OnionPacket.
50- type ErrorEncrypterExtracter func (* btcec.PublicKey ) (ErrorEncrypter ,
48+ // SharedSecretGenerator defines a function signature that extracts a shared
49+ // secret from an sphinx OnionPacket.
50+ type SharedSecretGenerator func (* btcec.PublicKey ) (sphinx. Hash256 ,
5151 lnwire.FailCode )
5252
5353// ErrorEncrypter is an interface that is used to encrypt HTLC related errors
@@ -87,12 +87,13 @@ type ErrorEncrypter interface {
8787 // given io.Reader.
8888 Decode (io.Reader ) error
8989
90- // Reextract rederives the encrypter using the extracter, performing an
91- // ECDH with the sphinx router's key and the ephemeral public key.
90+ // Reextract rederives the encrypter using the shared secret generator,
91+ // performing an ECDH with the sphinx router's key and the ephemeral
92+ // public key.
9293 //
9394 // NOTE: This should be called shortly after Decode to properly
9495 // reinitialize the error encrypter.
95- Reextract (ErrorEncrypterExtracter ) error
96+ Reextract (SharedSecretGenerator ) error
9697}
9798
9899// SphinxErrorEncrypter is a concrete implementation of both the ErrorEncrypter
@@ -105,20 +106,43 @@ type SphinxErrorEncrypter struct {
105106 EphemeralKey * btcec.PublicKey
106107}
107108
108- // NewSphinxErrorEncrypter initializes a blank sphinx error encrypter, that
109- // should be used to deserialize an encoded SphinxErrorEncrypter. Since the
110- // actual encrypter is not stored in plaintext while at rest, reconstructing the
111- // error encrypter requires:
109+ // NewSphinxErrorEncrypterUninitialized initializes a blank sphinx error
110+ // encrypter, that should be used to deserialize an encoded
111+ // SphinxErrorEncrypter. Since the actual encrypter is not stored in plaintext
112+ // while at rest, reconstructing the error encrypter requires:
112113// 1. Decode: to deserialize the ephemeral public key.
113114// 2. Reextract: to "unlock" the actual error encrypter using an active
114115// OnionProcessor.
115- func NewSphinxErrorEncrypter () * SphinxErrorEncrypter {
116+ func NewSphinxErrorEncrypterUninitialized () * SphinxErrorEncrypter {
116117 return & SphinxErrorEncrypter {
117118 OnionErrorEncrypter : nil ,
118119 EphemeralKey : & btcec.PublicKey {},
119120 }
120121}
121122
123+ // NewSphinxErrorEncrypter creates a new instance of a SphinxErrorEncrypter,
124+ // initialized with the provided shared secret. To deserialize an encoded
125+ // SphinxErrorEncrypter, use the NewSphinxErrorEncrypterUninitialized
126+ // constructor.
127+ func NewSphinxErrorEncrypter (ephemeralKey * btcec.PublicKey ,
128+ sharedSecret sphinx.Hash256 ) * SphinxErrorEncrypter {
129+
130+ encrypter := & SphinxErrorEncrypter {
131+ EphemeralKey : ephemeralKey ,
132+ }
133+
134+ encrypter .initialize (sharedSecret )
135+
136+ return encrypter
137+ }
138+
139+ // initialize creates the underlying instance of the sphinx error encrypter.
140+ func (s * SphinxErrorEncrypter ) initialize (sharedSecret sphinx.Hash256 ) {
141+ s .OnionErrorEncrypter = sphinx .NewOnionErrorEncrypter (
142+ sharedSecret , nil ,
143+ )
144+ }
145+
122146// EncryptFirstHop transforms a concrete failure message into an encrypted
123147// opaque failure reason. This method will be used at the source that the error
124148// occurs. It differs from BackwardObfuscate slightly, in that it computes a
@@ -198,10 +222,8 @@ func (s *SphinxErrorEncrypter) Decode(r io.Reader) error {
198222// Reextract rederives the error encrypter from the currently held EphemeralKey.
199223// This intended to be used shortly after Decode, to fully initialize a
200224// SphinxErrorEncrypter.
201- func (s * SphinxErrorEncrypter ) Reextract (
202- extract ErrorEncrypterExtracter ) error {
203-
204- obfuscator , failcode := extract (s .EphemeralKey )
225+ func (s * SphinxErrorEncrypter ) Reextract (extract SharedSecretGenerator ) error {
226+ sharedSecret , failcode := extract (s .EphemeralKey )
205227 if failcode != lnwire .CodeNone {
206228 // This should never happen, since we already validated that
207229 // this obfuscator can be extracted when it was received in the
@@ -210,13 +232,7 @@ func (s *SphinxErrorEncrypter) Reextract(
210232 "obfuscator, got failcode: %d" , failcode )
211233 }
212234
213- sphinxEncrypter , ok := obfuscator .(* SphinxErrorEncrypter )
214- if ! ok {
215- return fmt .Errorf ("incorrect onion error extracter" )
216- }
217-
218- // Copy the freshly extracted encrypter.
219- s .OnionErrorEncrypter = sphinxEncrypter .OnionErrorEncrypter
235+ s .initialize (sharedSecret )
220236
221237 return nil
222238}
@@ -239,9 +255,25 @@ type IntroductionErrorEncrypter struct {
239255}
240256
241257// NewIntroductionErrorEncrypter returns a blank IntroductionErrorEncrypter.
242- func NewIntroductionErrorEncrypter () * IntroductionErrorEncrypter {
258+ func NewIntroductionErrorEncrypter (ephemeralKey * btcec.PublicKey ,
259+ sharedSecret sphinx.Hash256 ) * IntroductionErrorEncrypter {
260+
261+ return & IntroductionErrorEncrypter {
262+ ErrorEncrypter : NewSphinxErrorEncrypter (
263+ ephemeralKey , sharedSecret ,
264+ ),
265+ }
266+ }
267+
268+ // NewIntroductionErrorEncrypter returns a blank IntroductionErrorEncrypter.
269+ // Since the actual encrypter is not stored in plaintext
270+ // while at rest, reconstructing the error encrypter requires:
271+ // 1. Decode: to deserialize the ephemeral public key.
272+ // 2. Reextract: to "unlock" the actual error encrypter using an active
273+ // OnionProcessor.
274+ func NewIntroductionErrorEncrypterUninitialized () * IntroductionErrorEncrypter {
243275 return & IntroductionErrorEncrypter {
244- ErrorEncrypter : NewSphinxErrorEncrypter (),
276+ ErrorEncrypter : NewSphinxErrorEncrypterUninitialized (),
245277 }
246278}
247279
@@ -253,7 +285,7 @@ func (i *IntroductionErrorEncrypter) Type() EncrypterType {
253285// Reextract rederives the error encrypter from the currently held EphemeralKey,
254286// relying on the logic in the underlying SphinxErrorEncrypter.
255287func (i * IntroductionErrorEncrypter ) Reextract (
256- extract ErrorEncrypterExtracter ) error {
288+ extract SharedSecretGenerator ) error {
257289
258290 return i .ErrorEncrypter .Reextract (extract )
259291}
@@ -270,9 +302,26 @@ type RelayingErrorEncrypter struct {
270302
271303// NewRelayingErrorEncrypter returns a blank RelayingErrorEncrypter with
272304// an underlying SphinxErrorEncrypter.
273- func NewRelayingErrorEncrypter () * RelayingErrorEncrypter {
305+ func NewRelayingErrorEncrypter (ephemeralKey * btcec.PublicKey ,
306+ sharedSecret sphinx.Hash256 ) * RelayingErrorEncrypter {
307+
308+ return & RelayingErrorEncrypter {
309+ ErrorEncrypter : NewSphinxErrorEncrypter (
310+ ephemeralKey , sharedSecret ,
311+ ),
312+ }
313+ }
314+
315+ // NewRelayingErrorEncrypterUninitialized returns a blank RelayingErrorEncrypter
316+ // with an underlying SphinxErrorEncrypter.
317+ // Since the actual encrypter is not stored in plaintext
318+ // while at rest, reconstructing the error encrypter requires:
319+ // 1. Decode: to deserialize the ephemeral public key.
320+ // 2. Reextract: to "unlock" the actual error encrypter using an active
321+ // OnionProcessor.
322+ func NewRelayingErrorEncrypterUninitialized () * RelayingErrorEncrypter {
274323 return & RelayingErrorEncrypter {
275- ErrorEncrypter : NewSphinxErrorEncrypter (),
324+ ErrorEncrypter : NewSphinxErrorEncrypterUninitialized (),
276325 }
277326}
278327
@@ -284,7 +333,7 @@ func (r *RelayingErrorEncrypter) Type() EncrypterType {
284333// Reextract rederives the error encrypter from the currently held EphemeralKey,
285334// relying on the logic in the underlying SphinxErrorEncrypter.
286335func (r * RelayingErrorEncrypter ) Reextract (
287- extract ErrorEncrypterExtracter ) error {
336+ extract SharedSecretGenerator ) error {
288337
289338 return r .ErrorEncrypter .Reextract (extract )
290339}
0 commit comments