@@ -20,8 +20,8 @@ import fr.acinq.bitcoin.scalacompat.Crypto.{PrivateKey, PublicKey}
2020import fr .acinq .bitcoin .scalacompat .{ByteVector32 , Crypto }
2121import fr .acinq .eclair .wire .protocol ._
2222import grizzled .slf4j .Logging
23+ import scodec .Attempt
2324import scodec .bits .ByteVector
24- import scodec .{Attempt , Codec }
2525
2626import scala .annotation .tailrec
2727import scala .collection .mutable .ArrayBuffer
@@ -343,14 +343,14 @@ object Sphinx extends Logging {
343343 private val payloadAndPadLength = 256
344344 private val hopPayloadLength = 9
345345 private val maxNumHop = 27
346- private val codec : Codec [ FatError ] = fatErrorCodec(payloadAndPadLength, hopPayloadLength, maxNumHop)
346+ private val totalLength = 12599
347347
348348 def create (sharedSecret : ByteVector32 , failure : FailureMessage ): ByteVector = {
349349 val failurePayload = FailureMessageCodecs .failureOnionPayload(payloadAndPadLength).encode(failure).require.toByteVector
350350 val hopPayload = HopPayload (ErrorSource , 0 millis)
351351 val zeroPayloads = Seq .fill(maxNumHop)(ByteVector .fill(hopPayloadLength)(0 ))
352352 val zeroHmacs = (maxNumHop.to(1 , - 1 )).map(Seq .fill(_)(ByteVector32 .Zeroes ))
353- val plainError = codec .encode(FatError (failurePayload, zeroPayloads, zeroHmacs)).require.bytes
353+ val plainError = fatErrorCodec(totalLength, hopPayloadLength, maxNumHop) .encode(FatError (failurePayload, zeroPayloads, zeroHmacs)).require.bytes
354354 wrap(plainError, sharedSecret, hopPayload).get
355355 }
356356
@@ -366,10 +366,10 @@ object Sphinx extends Logging {
366366
367367 def wrap (errorPacket : ByteVector , sharedSecret : ByteVector32 , hopPayload : HopPayload ): Try [ByteVector ] = Try {
368368 val um = generateKey(" um" , sharedSecret)
369- val error = codec .decode(errorPacket.bits).require.value
369+ val error = fatErrorCodec(errorPacket.length.toInt, hopPayloadLength, maxNumHop) .decode(errorPacket.bits).require.value
370370 val hopPayloads = hopPayloadCodec.encode(hopPayload).require.bytes +: error.hopPayloads.dropRight(1 )
371- val hmacs = computeHmacs(Hmac256 (um), error.failurePayload, hopPayloads, error.hmacs, 0 ) +: error.hmacs.dropRight(1 ).map(_.drop(1 ))
372- val newError = codec .encode(FatError (error.failurePayload, hopPayloads, hmacs)).require.bytes
371+ val hmacs = computeHmacs(Hmac256 (um), error.failurePayload, hopPayloads, error.hmacs.map(_.drop( 1 )) , 0 ) +: error.hmacs.dropRight(1 ).map(_.drop(1 ))
372+ val newError = fatErrorCodec(errorPacket.length.toInt, hopPayloadLength, maxNumHop) .encode(FatError (error.failurePayload, hopPayloads, hmacs)).require.bytes
373373 val key = generateKey(" ammag" , sharedSecret)
374374 val stream = generateStream(key, newError.length.toInt)
375375 newError xor stream
@@ -378,20 +378,20 @@ object Sphinx extends Logging {
378378 private def unwrap (errorPacket : ByteVector , sharedSecret : ByteVector32 , minNumHop : Int ): Try [(ByteVector , HopPayload )] = Try {
379379 val key = generateKey(" ammag" , sharedSecret)
380380 val stream = generateStream(key, errorPacket.length.toInt)
381- val error = codec .decode((errorPacket xor stream).bits).require.value
381+ val error = fatErrorCodec(errorPacket.length.toInt, hopPayloadLength, maxNumHop) .decode((errorPacket xor stream).bits).require.value
382382 val um = generateKey(" um" , sharedSecret)
383383 val shiftedHmacs = error.hmacs.tail.map(ByteVector32 .Zeroes +: _) :+ Seq (ByteVector32 .Zeroes )
384- val hmacs = computeHmacs(Hmac256 (um), error.failurePayload, error.hopPayloads, shiftedHmacs , minNumHop)
384+ val hmacs = computeHmacs(Hmac256 (um), error.failurePayload, error.hopPayloads, error.hmacs.tail , minNumHop)
385385 require(hmacs == error.hmacs.head.drop(minNumHop), " Invalid HMAC" )
386386 val shiftedHopPayloads = error.hopPayloads.tail :+ ByteVector .fill(hopPayloadLength)(0 )
387387 val unwrapedError = FatError (error.failurePayload, shiftedHopPayloads, shiftedHmacs)
388- (codec .encode(unwrapedError).require.bytes,
388+ (fatErrorCodec(errorPacket.length.toInt, hopPayloadLength, maxNumHop) .encode(unwrapedError).require.bytes,
389389 hopPayloadCodec.decode(error.hopPayloads.head.bits).require.value)
390390 }
391391
392392 def decrypt (errorPacket : ByteVector , sharedSecrets : Seq [(ByteVector32 , PublicKey )]): Either [InvalidFatErrorPacket , DecryptedFailurePacket ] = {
393393 var packet = errorPacket
394- var minNumHop = 1
394+ var minNumHop = 0
395395 val hopPayloads = ArrayBuffer .empty[(PublicKey , HopPayload )]
396396 for ((sharedSecret, nodeId) <- sharedSecrets) {
397397 unwrap(packet, sharedSecret, minNumHop) match {
@@ -403,7 +403,7 @@ object Sphinx extends Logging {
403403 minNumHop += 1
404404 hopPayloads += ((nodeId, hopPayload))
405405 case FatError .ErrorSource =>
406- val failurePayload = codec .decode(unwrapedPacket.bits).require.value.failurePayload
406+ val failurePayload = fatErrorCodec(errorPacket.length.toInt, hopPayloadLength, maxNumHop) .decode(unwrapedPacket.bits).require.value.failurePayload
407407 FailureMessageCodecs .failureOnionPayload(payloadAndPadLength).decode(failurePayload.bits) match {
408408 case Attempt .Successful (failureMessage) =>
409409 return Right (DecryptedFailurePacket (nodeId, failureMessage.value))
0 commit comments