<p>As far as I understand (but I did not double check the code) the answer is yes. The error messages in the onion seem to be encrypted in a way so that only the origanal sender of the onion can decrypt it. Since the error also had to be padded to keep the error onion of constant length the key derivation scheme for sending onions is kind of reused. In that sense the receiver of the error message unwraps all the envelopes and thus should know from which node the error arose. </p>

CC BY-SA 4.0
2020-01-14T07:24:57.657Z
2020-01-14T07:24:57.657Z
Rene Pickhardt
<p>When an intermediate or the final node (intended recepient) wants to send an error message they create an error packet which contains the (1) error message; (2) padding to conceal length and (3) HMAC that authenticates the packet using key <code>um</code>. This erring node then generates a key <code>ammag</code> that is used to generate a pseudo-random stream which in turn is applied to the error packet using XOR to obfuscate it. This error packet is then sent using the error message <code>update_fail_htlc</code> which includes the failure message <code>temporary_channel_failure</code> (this failure message is used in case of lack of channel funds or too many htlcs in flight).</p>

<p>This erring node will then forward this error packet to the node that forwarded the htlc to it. Intermediate nodes store the shared secret from the forward path and reuse it to obfuscate any corresponding return packet during each hop. The obfuscation step is repeated by every hop along the return path which generates its own <code>ammag</code>, generates the pseudo-random byte stream, and applies the result to the return packet before return-forwarding it. The error messages includes an <code>id</code> to let the peer know the htlc to which the error message is being referred.</p>

<p>When the error message arrives at the origin node, it is able to detect that this error message is intended of itself using the <code>id</code> as it was the one that created it. When an origin node receives an error message matching a transfer it initiated it generates the <code>ammag</code> and <code>um</code> keys for each hop in the route. It then iteratively decrypts the error message, using each hop's <code>ammag</code> key, and computes the HMAC, using each hop's <code>um</code> key. The origin node can hence detect the sender of the error message by matching the hmac field with the computed HMAC of the error packet.</p>

CC BY-SA 4.0
2020-01-20T09:12:30.663Z
2020-01-20T09:19:18.077Z
2020-01-20T09:19:18.077Z
Ugam Kamat
<p>According to information in <a href="https://github.com/lightningnetwork/lnd/pull/3256" rel="nofollow noreferrer">this LND PR</a> the sender of an <code>TemporaryChannelFailure</code> can be determined:</p>

<blockquote>
  <p>In many cases it is impossible for the sender to determine which of the two nodes in a pair is responsible for the failure. In this situation, we now penalize bidirectionally. This does not hurt the good node of the pair, because only its connection to a bad node is penalized.</p>
</blockquote>

<p>So my understanding of this comment is, the channel, or at least the node next to one of the exhausted channels can be identified quite easily. Is it really that easy? Can <code>TemporaryChannelFailure</code> and therefore channel exhaustions always be assigned to two nodes or one channel?</p>

<p>I always assumed, the error cannot be assigned to a node or channel at all.</p>

<p>This might simplify the work of some papers, such as <a href="https://eprint.iacr.org/2019/328" rel="nofollow noreferrer">On the Difficulty of Hiding the Balance
of Lightning Network Channels by J Herrera-Joancomarti et al.</a>, or open new attack vectors.</p>

<h3>Edit: more links for further research</h3>

<p>In case someone wants to give a more in-depth answer or do research on top of this, here are some links to the code in the <code>lnd</code> client github code base:</p>

<ul>
<li><p>In <a href="https://github.com/lightningnetwork/lightning-onion/blob/ecc936dc56c9ed8167a560b9a1fed0f9653abfc0/crypto.go#L249-L252" rel="nofollow noreferrer">lightningnetwork/lightning-onion crypto.go, function <code>DecryptError</code></a>, the client cycles through the secrets to unwrap the error and identify the <code>sender</code> index.</p></li>
<li><p>In <a href="https://github.com/lightningnetwork/lnd/blob/7d356458e334adc5128ba6e5218ee802d52ecd38/htlcswitch/switch.go#L951" rel="nofollow noreferrer">lightningnetwork/lnd htlcswitch/switch.go, function <code>parseFailedPayment</code></a> this <code>DecryptError</code> function is used to access the failure.</p></li>
<li><p>Later this value will be accessed e. g. in <code>missioncontrol.go</code> or <code>result_interpretation.go</code> as <code>FailureSourceIdx</code>, <code>failureSourceIdx</code> or <code>failureSrcIdx</code>.</p></li>
</ul>

<lightning-network><privacy><balance>
Can failed Transactions figure out which Channel is exhausted?
wtho
# Can failed Transactions figure out which Channel is exhausted?

(Asked by: username_0 on 2020-01-12)

According to information in [this LND PR](https://github.com/lightningnetwork/lnd/pull/3256) the sender of an `TemporaryChannelFailure` can be determined:

> In many cases it is impossible for the sender to determine which of the two nodes in a pair is responsible for the failure. In this situation, we now penalize bidirectionally. This does not hurt the good node of the pair, because only its connection to a bad node is penalized.

So my understanding of this comment is, the channel, or at least the node next to one of the exhausted channels can be identified quite easily. Is it really that easy? Can `TemporaryChannelFailure` and therefore channel exhaustions always be assigned to two nodes or one channel?

I always assumed, the error cannot be assigned to a node or channel at all.

This might simplify the work of some papers, such as [On the Difficulty of Hiding the Balance
of Lightning Network Channels by J Herrera-Joancomarti et al.](https://eprint.iacr.org/2019/328), or open new attack vectors.

### Edit: more links for further research

In case someone wants to give a more in-depth answer or do research on top of this, here are some links to the code in the `lnd` client github code base:

* In [lightningnetwork/lightning-onion crypto.go, function `DecryptError`](https://github.com/lightningnetwork/lightning-onion/blob/ecc936dc56c9ed8167a560b9a1fed0f9653abfc0/crypto.go#L249-L252), the client cycles through the secrets to unwrap the error and identify the `sender` index.
* In [lightningnetwork/lnd htlcswitch/switch.go, function `parseFailedPayment`](https://github.com/lightningnetwork/lnd/blob/7d356458e334adc5128ba6e5218ee802d52ecd38/htlcswitch/switch.go#L951) this `DecryptError` function is used to access the failure.
* Later this value will be accessed e. g. in `missioncontrol.go` or `result_interpretation.go` as `FailureSourceIdx`, `failureSourceIdx` or `failureSrcIdx`.

**Tags:** lightning-network, privacy, balance


---

## 2 answers

### Answer by username_1 on 2020-01-14. Score: 1

As far as I understand (but I did not double check the code) the answer is yes. The error messages in the onion seem to be encrypted in a way so that only the origanal sender of the onion can decrypt it. Since the error also had to be padded to keep the error onion of constant length the key derivation scheme for sending onions is kind of reused. In that sense the receiver of the error message unwraps all the envelopes and thus should know from which node the error arose.


---

### Answer by username_2 on 2020-01-20. Score: 0

When an intermediate or the final node (intended recepient) wants to send an error message they create an error packet which contains the (1) error message; (2) padding to conceal length and (3) HMAC that authenticates the packet using key `um`. This erring node then generates a key `ammag` that is used to generate a pseudo-random stream which in turn is applied to the error packet using XOR to obfuscate it. This error packet is then sent using the error message `update_fail_htlc` which includes the failure message `temporary_channel_failure` (this failure message is used in case of lack of channel funds or too many htlcs in flight).

This erring node will then forward this error packet to the node that forwarded the htlc to it. Intermediate nodes store the shared secret from the forward path and reuse it to obfuscate any corresponding return packet during each hop. The obfuscation step is repeated by every hop along the return path which generates its own `ammag`, generates the pseudo-random byte stream, and applies the result to the return packet before return-forwarding it. The error messages includes an `id` to let the peer know the htlc to which the error message is being referred.

When the error message arrives at the origin node, it is able to detect that this error message is intended of itself using the `id` as it was the one that created it. When an origin node receives an error message matching a transfer it initiated it generates the `ammag` and `um` keys for each hop in the route. It then iteratively decrypts the error message, using each hop's `ammag` key, and computes the HMAC, using each hop's `um` key. The origin node can hence detect the sender of the error message by matching the hmac field with the computed HMAC of the error packet.


---

