diff --git a/10 Notes/DHT Bug in Logos Storage.md b/10 Notes/DHT Bug in Logos Storage.md new file mode 100644 index 0000000..bab31fa --- /dev/null +++ b/10 Notes/DHT Bug in Logos Storage.md @@ -0,0 +1,61 @@ +This code in `vendor/logos-storage-nim-dht/codexdht/private/eth/p2p/discoveryv5/spr.nim` + +```nim +proc ip*(r: SignedPeerRecord): Option[array[4, byte]] = + for address in r.data.addresses: + let ma = address.address + let code = ma[0].get.protoCode() + if code.isOk and code.get == multiCodec("ip4"): + var ipbuf: array[4, byte] + let res = ma[0].get.protoArgument(ipbuf) + if res.isOk: + return some(ipbuf) + +# err("Incorrect IPv4 address") +# else: +# if (?(?ma[1]).protoArgument(pbuf)) == 0: +# err("Incorrect port number") +# else: +# res.port = Port(fromBytesBE(uint16, pbuf)) +# ok(res) +# else: + +# else: +# err("MultiAddress must be wire address (tcp, udp or unix)") + +proc udp*(r: SignedPeerRecord): Option[int] = + for address in r.data.addresses: + let ma = address.address + + let code = ma[1].get.protoCode() + if code.isOk and code.get == multiCodec("udp"): + var pbuf: array[2, byte] + let res = ma[1].get.protoArgument(pbuf) + if res.isOk: + let p = fromBytesBE(uint16, pbuf) + return some(p.int) +``` + +```nim +proc ip*(r: SignedPeerRecord): Option[array[4, byte]] = + for address in r.data.addresses: + let ma = address.address + let code = ma[0].get.protoCode() + if code.isOk and code.get == multiCodec("ip4"): + var ipbuf: array[4, byte] + let res = ma[0].get.protoArgument(ipbuf) + if res.isOk: + return some(ipbuf) + +proc udp*(r: SignedPeerRecord): Option[int] = + for address in r.data.addresses: + let ma = address.address + + let code = ma[1].get.protoCode() + if code.isOk and code.get == multiCodec("udp"): + var pbuf: array[2, byte] + let res = ma[1].get.protoArgument(pbuf) + if res.isOk: + let p = fromBytesBE(uint16, pbuf) + return some(p.int) +``` \ No newline at end of file diff --git a/10 Notes/MixNets - Sphinx YouTube video.md b/10 Notes/MixNets - Sphinx YouTube video.md new file mode 100644 index 0000000..5879d24 --- /dev/null +++ b/10 Notes/MixNets - Sphinx YouTube video.md @@ -0,0 +1,72 @@ +A youtube video about Mix and Sphinx: https://youtu.be/34TKXELJa2c?is=J8G4cNyG3djsWdtm + +Notes: + +Mixing strategies and how mixing nodes can add security to the messages: +- buffer the messages and send them or regular intervals, +- Buffer messages till a selected number of the is collected and then send all of them or just a selection of them - pool model +- Messages can be tagged by the sender to indicate special security requirements + +Mix format +- has to hide the length of the message +- where you are in the path - if you just add a layer of encryption, the message gets longer and longer leaking its potential position in the mix path +- includes mechanism that allows the recipient to reply to the message in an anonymous way - it should be indistinguishable from the *forward messages*. It comes from the concept called anonymity set: number of people that use the system - that could have send the given message. E.g. if only, say 10 people use the system it is obviously way easier to figure out the potential recipient and the sender. Thus, the larger the number of people using the system, the bigger the anonymity set and the better protection. If the reply messages are distinguishable from the forward messages, we are effectively dealing with two mix nets with effectively lower corresponding anonymity sets. + +Existing Mix format + +- Mixmaster (1998) + - No replies + - Heuristic security (you define the level of security by how many known attacks the network survives) +- Möller (2003), Camenish & Lysyanskaya (2005) + - provable security - a mathematical proof that if you can break some aspect of the system then you can solve some problems believed to be hard (like factoring or discrete logs) + - still no (indistinguishable) replies + - never actually deployed +- Mixminion (2003) + - a follow-up to Mixmaster + - Heuristic security + - has indistinguishable replies + - deployed +- Minx (2004) + - First attempt of a *compact* mix format - the overhead - the headers you need to route the message through the network - has a certain size (kB or tens of kB), which may not be ideal if your messages are very small + - indistinguishable replies + - heuristic security + - BROKEN +- Shimsock, Staats, Hopper (2008) - ”SSH 08” + - Broke Minx, provided provable security fix + - has indistinguishable replies + - But: very expensive to construct mix messages + - The only way add an e.g. address of the next mix to the message was to share a cryptographic hash with the next mix - that hash has to contain the information (routing info) Alice wants to convey, e.g. to convey a 32 bit address, Alice would have to create mix packets that hash to that 32 bit address (2^32 - 4 billion tries in the worst case) + - to make that easier, the only information that Alice is allowed to convey is the identity of the next hop and there are at most 255 different mix nodes - we store their addresses in a table and Alice just has to convey 8 bits of information (indicating the row in the table) - so 2^8 x number of hops. +- Sphinx takes the best of the all above approaches + - Provable security + - supports indistinguishable replies + - compact + - Computationally cheap + +![[Pasted image 20260331141209.png]] + +- r - maximum length of the path (common value 3, 5, 10) +- s - size of the symmetric key in bytes - how much we choose for s depends on the level of security we want - commonly at that time 80-bit security - 2^80 operations for an attacker to brake the system. Today we prefer to use around 128 bits (16 bytes) +- p - size of the public key - also depends on the security level you want - e.g. for 80 bits security, you may need to have something like 1000-bit public key if you are using RSA or something like that… It also depends on which system you use: for RSA, Elgamal, or Diffie-Hellman, the key size will be rather big, for elliptic curves the key will be much smaller for the same security. + +Some examples: + +RSA-like… + +![[Pasted image 20260331142627.png]] + +EC: + +![[Pasted image 20260331142912.png]] + +Around 100 bytes for 80-bit security. + +### Sphinx message format + +![[Pasted image 20260331143337.png]] + +![[Pasted image 20260331144536.png]] + +Now, we could be tempted to use the same alpha for each hop (and different for different message/recipient), but then the message coming into the mix node and one coming out to the mix node could be correlated. + +![[Pasted image 20260331145433.png]] \ No newline at end of file diff --git a/10 Notes/New Block Exchange Protocol for Logos Storage.md b/10 Notes/New Block Exchange Protocol for Logos Storage.md new file mode 100644 index 0000000..4d01a8e --- /dev/null +++ b/10 Notes/New Block Exchange Protocol for Logos Storage.md @@ -0,0 +1,4 @@ +Giuliano made an excellent analysis: + +- [New Block Protocol - Summary](https://hackmd.io/YKEKMFGgSAaHjVxKcz8n2w) +- [Bandwidth-Delay Product Estimations: Are we Doing It Right?](https://hackmd.io/2brFqqXzS9GQ4Ei5xe0gLw) - see my own note [[Bandwidth-Delay Product for Block Exchange Protocol]]. diff --git a/10 Notes/Segmentation fault caused by NAT on logos-storage-nim.md b/10 Notes/Segmentation fault caused by NAT on logos-storage-nim.md new file mode 100644 index 0000000..0018726 --- /dev/null +++ b/10 Notes/Segmentation fault caused by NAT on logos-storage-nim.md @@ -0,0 +1,20 @@ +Regarding the segmentation fault, I had some iterations with gpt-5-codex and here is an edited summary: + +- The crash happens immediately after `Switch.start()` completes in `vendor/nim-codex/codex/codex.nim` (line `238`), before any of the block‑exchange or discovery logs appear. The next code that runs is `nattedAddress(...)`, so the blow‑up is occurring while we compute NAT mappings, not inside libp2p. +- `vendor/nim-codex/codex/nat.nim` keeps all runtime state in module‑level globals (`strategy`, `extIp`, `natClosed`, `activeMappings`, `natThreads`) plus a single `addQuitProc(stopNatThreads)` hook. That design only works when one node lives in the process. As soon as you create a second node, both instances mutate the same sequences and atomics: + - `redirectPorts` appends to the shared `activeMappings/natThreads` and spawns a renewal thread for every caller. Those renewal threads and any later redirectPorts invocations then race over the same global state. + - When the first node shuts down (or when the quit proc runs) `stopNatThreads()` sets the shared `natClosed` atomic to `true`, tears down all threads and deletes every mapping in `activeMappings`, regardless of which node created them. The other live node continues executing with stale NAT state and dangling C pointers, which is consistent with the `SIGSEGV` you’re observing when the second node starts up. + - Because the globals are never re‑initialised (`natClosed` never flips back to `false`, `activeMappings` is never cleared safely), the second node inherits half torn‑down structures. That’s why the bug only shows up once you create another node in the same process. +- The behaviour matches your platform reports: on Ubuntu (CI) we don’t hit the race because the NAT code exits early (CI runs in environments without UPnP/NAT‑PMP), whereas on your AMD desktops the NAT calls succeed, meaning we actually enter the broken multi‑instance path and crash. +- Also notice that the crash only happens once we actually go down the NAT path far enough to spin up per-process state and threads. Arnaud's Fedora does not suffer from the crash (regardless if he uses Nix or without Nix - I am **not** using Nix BTW), but that's can also be explained: if his Fedora is missing/blocked UPnP/NAT-PMP support, or the router refuses those protocols, `getExternalIP()` simply returns `none`. In that case `redirectPorts` and the renewal threads never run, so the global state never gets into a bad cross-node mix — the code just keeps the default `nat=any` without doing any mapping, and everything appears fine. On my AMD boxes the call likely succeeds (UPnP works), so the brittle shared state is exercised and I am hitting the segfault. + +To make multiple nodes safe, we need to turn NAT management into a per-node resource. + +The code on this branch is mostly authored by "gpt-5-codex" and so, it is just an entry point to actual work. The initial fix compiles and appears to work, but we had to temporarily disable the NAT port‑mapping renewal thread so we no longer spawn a background thread with `repeatPortMapping`. This cannot go to production like this as NAT will not be able to adjust to changing conditions, but, I think it is a great start. + +With this initial fix, I can at least start two nodes one after another with libcodex and even two of them at the same time, even with NAT set to `any`. Also apparently it fixed some logging issues that I have observed - for some combination of log levels for the codex nodes in one process, the node that stops second could in some circumstances hang on `stop` and `destroy` operations. With this initial fix, it seems not to be a problem any more. + +To experiments with libcodex, and to experience the problem yourself, you may like to check the following two repos: + +- https://github.com/codex-storage/codex-go-bindings +- https://github.com/codex-storage/go-codex-client (can be good for isolated experiments and test runs) \ No newline at end of file diff --git a/10 Notes/Sphinx Header Processing Example.md b/10 Notes/Sphinx Header Processing Example.md new file mode 100644 index 0000000..736fd09 --- /dev/null +++ b/10 Notes/Sphinx Header Processing Example.md @@ -0,0 +1,2231 @@ +This is another document from the [[Mix Implementation]] series. In the other two notes: + +- [[libp2p MIX Architecture and API]] +- [[Sphinx SURBs implementation in the libp2p MIX protocol]] + +you can find a high level overview I created interactively with OpenAI Codex. This note is fully hand-crafted though. + +We also have a detailed illustrated example in [[Sphinx Header Processing Infographic]] with the web version available at https://link.excalidraw.com/readonly/6y7DRQlUhkkBMZScEONS. + +In this note we are documenting how the [Sphinx](https://cypherpunks.ca/~iang/pubs/Sphinx_Oakland09.pdf) headers are created in our current [MIX Protocol Implementation](https://github.com/vacp2p/nim-libp2p/tree/master/libp2p/protocols/mix) and how they are processed by the mix nodes in the reply path. Where handy, comments about forward processing are also included. + +> We are actually focusing on the $\beta$ part of the header here, but I will keep use the word "header" where convenient. + +The objective is to have something that illustrates the complex mechanics of maintaining the constant size of the $\beta$ elements (part of the Sphinx header) using the so called _fillers_. It should help those who are working with Sphinx implementation and want to have a reference example to "quickly" visualize how the whole machinery works. As such it can be useful also for those who already know Sphinx very well. + +### Notation + +To create the examples that are visual and where you can "easily" see things happening, I introduced a couple of custom constructs. + +$\mathcal{S}_i$ - the AES-CTR keystream derived from the per-hop shared secret $s_i$. +$\mathcal{S}_i[x,y)$ - subrange of $\mathcal{S}_i$ starting at index $x$ and ending on index $y-1$ (`[x ..< y]` in Nim). +$\{0\}^a$ - a sequence of $0$s of length $a$. + +Now, to keep notation compact. Imagine we have a bit sequence of `0` of length $8$: `00000000` and a keystream $\mathcal{S}_i$. Now imagine _applying_ a subrange of $\mathcal{S}_i$ of the same length $8$ to that bit sequence, e.g. $\mathcal{S}_i[16,24)$: + +$$ +\begin{array}{|c|c|c|c|c|c|c|c|} +\hline +0&0&0&0&0&0&0&0 +\\ +\hline +\hspace{-2em}\oplus\hspace{1.4em} +\mathcal S_i[16] & +\mathcal S_i[17] & +\mathcal S_i[18] & +\mathcal S_i[19] & +\mathcal S_i[20] & +\mathcal S_i[21] & +\mathcal S_i[22] & +\mathcal S_i[23] +\\ +\hline +\hspace{-2em}=\hspace{1.2em} +\mathcal S_i[16] & +\mathcal S_i[17] & +\mathcal S_i[18] & +\mathcal S_i[19] & +\mathcal S_i[20] & +\mathcal S_i[21] & +\mathcal S_i[22] & +\mathcal S_i[23] +\\ +\hline +\end{array} +$$ + + +The result is a bit stream with the bit value $\mathcal{S}_i[16]$ in the first position and $\mathcal{S}_i[23]$ in the last position. We denote the result of applying a subrange $\mathcal{S}_i[x,y)$ to 0-bit sequence of the same length by $\mathcal{S}^0_i[x,y)$. Obviously $\mathcal{S}^0_i[x,y)\;\oplus\;\mathcal{S}^0_i[x,y) = \{0\}^{y-x}$. + +A sequence of XOR operations may be applied to a given bit sequence: + +$$ +\begin{array}{|c|c|c|c|c|c|c|c|} +\hline +0&1&0&1&1&0&1&0 +\\ +\hline +\hspace{-2em}\oplus\hspace{1.4em} +\begin{matrix} +\small\mathcal S_0[16] \\ +1 +\end{matrix} & +\begin{matrix} +\small\mathcal S_0[17] \\ +1 +\end{matrix} & +\begin{matrix} +\small\mathcal S_0[18] \\ +0 +\end{matrix} & +\begin{matrix} +\small\mathcal S_0[19] \\ +1 +\end{matrix} & +\begin{matrix} +\small\mathcal S_0[20] \\ +0 +\end{matrix} & +\begin{matrix} +\small\mathcal S_0[21] \\ +0 +\end{matrix} & +\begin{matrix} +\small\mathcal S_0[22] \\ +1 +\end{matrix} & +\begin{matrix} +\small\mathcal S_0[23] \\ +0 +\end{matrix} +\\ +\hline +\hspace{-2em}\oplus\hspace{1.4em} +\begin{matrix} +\small\mathcal S_1[24] \\ +0 +\end{matrix} & +\begin{matrix} +\small\mathcal S_1[25] \\ +1 +\end{matrix} & +\begin{matrix} +\small\mathcal S_1[26] \\ +0 +\end{matrix} & +\begin{matrix} +\small\mathcal S_1[27] \\ +1 +\end{matrix} & +\begin{matrix} +\small\mathcal S_1[28] \\ +1 +\end{matrix} & +\begin{matrix} +\small\mathcal S_1[29] \\ +0 +\end{matrix} & +\begin{matrix} +\small\mathcal S_1[30] \\ +1 +\end{matrix} & +\begin{matrix} +\small\mathcal S_1[31] \\ +0 +\end{matrix} +\\ +\hline +\hspace{-2em}\oplus\hspace{1.4em} +\begin{matrix} +\small\mathcal S_3[84] \\ +0 +\end{matrix} & +\begin{matrix} +\small\mathcal S_3[85] \\ +1 +\end{matrix} & +\begin{matrix} +\small\mathcal S_3[86] \\ +1 +\end{matrix} & +\begin{matrix} +\small\mathcal S_3[87] \\ +1 +\end{matrix} & +\begin{matrix} +\small\mathcal S_3[88] \\ +1 +\end{matrix} & +\begin{matrix} +\small\mathcal S_3[89] \\ +1 +\end{matrix} & +\begin{matrix} +\small\mathcal S_3[90] \\ +1 +\end{matrix} & +\begin{matrix} +\small\mathcal S_3[91] \\ +0 +\end{matrix} +\\ +\hline +\hspace{-2.8em}=\hspace{1.9em}1&0&1&0&1&1&0&0 +\\ +\hline +\end{array} +$$ + +We denote this operation as: +$$ +\begin{array}{l} +01011010 \\ +\,\left\vert +\begin{matrix} +\small\;\mathcal{S}_0[16,24) \\ +\small\;\mathcal{S}_1[24,32) \\ +\small\;\mathcal{S}_3[84,91) +\end{matrix} +\right. +\end{array} +$$ + +In particular, if $(A_3\,\Vert\,D_2\,\Vert\,\gamma_3)$ is concatenation of bit sequences $A_3$, $D_2$, and $\gamma_3$, and size of $(A_3\,\Vert\,D_2\,\Vert\,\gamma_3)$, denoted $\vert(A_3\,\Vert\,D_2\,\Vert\,\gamma_3)\vert$, is $l$, then applying a sequence of XOR operations to the sequence $(A_3\,\Vert\,D_2\,\Vert\,\gamma_3)$ will be written as: + +$$ +\begin{array}{l} +(A_3\,\Vert\,D_2\,\Vert\,\gamma_3) \\ +\,\left\vert +\begin{matrix} +\small\;\mathcal{S}_0[a,b) \\ +\small\;\mathcal{S}_1[c,d) \\ +\small\;\mathcal{S}_3[e,f) +\end{matrix} +\right. +\end{array} +$$ +where $b-a = d-c = f-e = l$. Notice that the result of the following two operations will be the same: + +$$ +\begin{array}{l} +(A_3\,\Vert\,D_2\,\Vert\,\gamma_3) \\ +\,\left\vert +\begin{matrix} +\small\;\mathcal{S}_0[a,b) \\ +\small\;\mathcal{S}_1[c,d) \\ +\small\;\mathcal{S}_3[e,f) \\ +\small\;\mathcal{S}_3[e,f) +\end{matrix} +\right. +\end{array} +\begin{matrix} +\quad = \quad \\ +\vphantom{a} \\ +\vphantom{a} \\ +\vphantom{a} \\ +\vphantom{a} +\end{matrix} +\begin{array}{l} +(A_3\,\Vert\,D_2\,\Vert\,\gamma_3) \\ +\begin{matrix} +\,\left\vert +\begin{matrix} +\small\;\mathcal{S}_0[a,b) \\ +\small\;\mathcal{S}_1[c,d) \\ +\end{matrix} +\right. +\vphantom{a} \\ +\vphantom{a} \\ +\vphantom{a} +\end{matrix} +\end{array} +$$ + +Because the two $\mathcal{S}_3[e,f)$ *cancel* each other, to make it more visible, we will write: + +$$ +\begin{array}{l} +(A_3\,\Vert\,D_2\,\Vert\,\gamma_3) \\ +\,\left\vert +\begin{matrix} +\small\;\mathcal{S}_0[a,b) \\ +\small\;\mathcal{S}_1[c,d) \\ +\small\;\enclose{horizontalstrike}{\mathcal{S}_3[e,f)} \\ +\small\;\enclose{horizontalstrike}{\mathcal{S}_3[e,f)} +\end{matrix} +\right. +\end{array} +$$ + +### Sphinx Header + +The Sphinx Header is defined as $\mathcal{H}=(\alpha,\beta,\gamma)$, where: + +- $\alpha$ is a (blinded) public key (group element; $\alpha\in\mathbb{G})$. +- $\beta$ is the (encrypted) routing information +- $\gamma$ is a MAC (message authentication code) + +Formal definition of $\alpha$ and $\gamma$ and how they are used in Sphinx can be found in note [Sphinx packet format](https://hackmd.io/kdqHnc2gRhuTS-6fDex2mw). In this document, I want to focus more on $\beta$, by giving an illustrative example of its construction and processing. Special attention will be given to the so called _filler_, which I personally found the most challenging to "see". This document should help in grasping the construction and processing of $\beta$ in a more visual manner. + +The intention of this document is, in the first place, to help understanding the [implementation of the current MIX protocol](https://github.com/vacp2p/nim-libp2p/tree/master/libp2p/protocols/mix). Thus, some things will be make bluntly concrete, e.g. sizes, and to find more details about them and about Mix protocol implementation in general, the reader should refer to [[libp2p MIX Architecture and API]] and [[Sphinx SURBs implementation in the libp2p MIX protocol]]. For brevity, in this document I will not repeat what is written there. + +The MIX implementation uses the following constants: + +```nim +const + k* = 16 + r* = 5 + t* = 6 + AlphaSize* = 32 + BetaSize* = ((r * (t + 1)) + 1) * k + GammaSize* = 16 + HeaderSize* = AlphaSize + BetaSize + GammaSize + DelaySize* = 2 + AddrSize* = (t * k) - DelaySize + PacketSize* = 4608 + MessageSize* = PacketSize - HeaderSize - k + PayloadSize* = MessageSize + k + SurbSize* = HeaderSize + AddrSize + k + SurbLenSize* = 1 + SurbIdLen* = k +``` + +Recall that `k` corresponds to the $\kappa=128$ bits of security from the [MIX Specification](https://lip.logos.co/ift-ts/raw/mix.html#82-cryptographic-primitives) and that `r` is the maximum number of hopes supported and `t*k` ($t\kappa$ in the spec) gives us the size of _combined address and delay width_. The size of $\beta$ - $\vert\beta\vert$ or `BetaSize` - is given by formula $(r(t+1)+1)\kappa$, which corresponds to `((r * (t + 1)) + 1) * k` in the code snippet above. To decipher this formula let's write it in a bit less compact form: + +$$ +(r(t+1)+1)\kappa = r(t+1)\kappa + \kappa +$$ +$r(t+1)\kappa$ corresponds to the space in bytes needed to hold $r$ combined address and delay blocks $t\kappa$ ($96$ bytes each) and $r$ $\gamma$ blocks ($16$ bytes each) resulting in $r\times112 = 5\times112 = 560$ bytes. Together with extra $\kappa$ bytes - perhaps reserved for future use, or just in case - we arrive at fixed size of $\beta$, $\vert\beta\vert = 576$ bytes. + +Knowing $\vert\beta\vert$, we get: + +$$ +\vert\mathcal{H}\vert = \vert\alpha\vert + \vert\beta\vert + \vert\gamma\vert = 32 + 576 + 16 = 624\;\text{bytes} +$$ + +But let's focus back at $\beta$. As we will see in a moment, its size - $r(t+1)\kappa=112$ bytes - is crucial. It contains the routing information for each single hop, and at each hop, one such block will be removed and to keep the size of $\beta$ fixed and still indistinguishable for a potential evil observer, we use a so called _filler_. +### Constructing the filler + +What may make construction of the filler hard to understand is that three things: construction of the filler, construction of the $\beta$, and then finally processing of $\beta$ in the forward and the reply path, all must be perfectly aligned. Moreover, because the header (and so also $\beta$) for the very first hop must contain the routing information for all the remaining hops, the header construction needs to happen in the backward direction (starting from the destination address). + +The `filler` is pre-computed before the construction of successive $\beta$-as is even started: + +```nim +proc computeFillerStrings(s: seq[seq[byte]]): Result[seq[byte], string] = + var filler: seq[byte] = @[] + + for i in 1 ..< s.len: + let + aes_key = deriveKeyMaterial("aes_key", s[i - 1]).kdf() + iv = deriveKeyMaterial("iv", s[i - 1]).kdf() + + let + fillerLength = (t + 1) * k + zeroPadding = newSeq[byte](fillerLength) + + filler = aes_ctr_start_index( + aes_key, + iv, + filler & zeroPadding, + (((t + 1) * (r - i)) + t + 2) * k, + ) + + return ok(filler) +``` + +Let's see how the filler will be created for a 4-hop Mix path. + +As we see from the routine above for a 4-hop Mix path we will have 3 iterations (`1 ..< s.len`). + +**i = 1**: $(((t+1)(r-i)) + t +2)k = ((6+1)(5-1)+6+2)\times16 = 576$ + +$$ +\begin{matrix} +\mathsf{filler} = \mathcal{S}^0_0[576,688) +\end{matrix} +$$ + +or to make it more explicit: + +$$ +\begin{matrix} +\mathsf{filler} \; = \ \\ +\vphantom{a} +\end{matrix} +\begin{array}{l} +\{0\}^{112} \\ +\,\left\vert +\begin{matrix} +\small\;\mathcal{S}_0[576,688) +\end{matrix} +\right. +\end{array} +$$ + +**i = 2**: $(((t+1)(r-i)) + t +2)k = ((6+1)(5-2)+6+2)\times16 = 464$ + +$$ +\begin{matrix} +\mathsf{filler} \; = \ \\ +\vphantom{a} \\ +\vphantom{a} +\end{matrix} +\begin{array}{l} +\{0\}^{112} \\ +\,\left\vert +\begin{matrix} +\small\;\mathcal{S}_0[576,688) \\ +\small\;\mathcal{S}_1[464,576) +\end{matrix} +\right. +\end{array} +\begin{matrix} +\quad\Large\Vert\quad \\ +\vphantom{a} \\ +\vphantom{a} +\end{matrix} +\begin{array}{l} +\{0\}^{112} \\ +\,\left\vert +\begin{matrix} +\small\vphantom{a} \\ +\small\;\mathcal{S}_1[576,688) +\end{matrix} +\right. +\end{array} +$$ + +**i = 3**: $(((t+1)(r-i)) + t +2)k = ((6+1)(5-3)+6+2)\times16 = 352$ + +$$ +\begin{matrix} +\mathsf{filler} \; = \ \\ +\vphantom{a} \\ +\vphantom{a} \\ +\vphantom{a} +\end{matrix} +\begin{array}{l} +\{0\}^{112} \\ +\,\left\vert +\begin{matrix} +\small\;\mathcal{S}_0[576,688) \\ +\small\;\mathcal{S}_1[464,576) \\ +\small\;\mathcal{S}_2[352,464) +\end{matrix} +\right. +\end{array} +\begin{matrix} +\quad\Large\Vert\quad \\ +\vphantom{a} \\ +\vphantom{a} \\ +\vphantom{a} +\end{matrix} +\begin{array}{l} +\{0\}^{112} \\ +\,\left\vert +\begin{matrix} +\small\vphantom{a} \\ +\small\;\mathcal{S}_1[576,688) \\ +\small\;\mathcal{S}_2[464,576) +\end{matrix} +\right. +\end{array} +\begin{matrix} +\quad\Large\Vert\quad \\ +\vphantom{a} \\ +\vphantom{a} \\ +\vphantom{a} +\end{matrix} +\begin{array}{l} +\{0\}^{112} \\ +\,\left\vert +\begin{matrix} +\small\vphantom{a} \\ +\small\vphantom{a} \\ +\small\;\mathcal{S}_2[576,688) +\end{matrix} +\right. +\end{array} +$$ + +### Constructing the header + +Now that we have the filler constructed, let's have an example of a step-by-step construction of the header. + +Recall, here we will be moving backwards, and the corresponding routine is as follows: + +```nim +proc computeBetaGamma( + s: seq[seq[byte]], + hops: openArray[Hop], + delay: openArray[seq[byte]], + destHop: Hop, + id: SURBIdentifier, +): Result[tuple[beta: seq[byte], gamma: seq[byte]], string] = + let sLen = s.len + var + beta: seq[byte] + gamma: seq[byte] + + let filler = computeFillerStrings(s).valueOr: + return err("Error in filler generation: " & error) + + for i in countdown(sLen - 1, 0): + let + beta_aes_key = deriveKeyMaterial("aes_key", s[i]).kdf() + mac_key = deriveKeyMaterial("mac_key", s[i]).kdf() + beta_iv = deriveKeyMaterial("iv", s[i]).kdf() + + if i == sLen - 1: + let destBytes = destHop.serialize() + let destPadding = destBytes & delay[i] & @id & newSeq[byte](PaddingLength) + let aes = aes_ctr(beta_aes_key, beta_iv, destPadding) + beta = aes & filler + else: + let betaPrefix = + beta[0 .. (((r * (t + 1)) - t) * k) - 1] + + let routingInfo = RoutingInfo.init( + hops[i + 1], + delay[i], + gamma, + betaPrefix, + ) + + let serializedRoutingInfo = routingInfo.serialize() + beta = aes_ctr(beta_aes_key, beta_iv, serializedRoutingInfo) + + gamma = hmac(mac_key, beta).toSeq() + + return ok((beta: beta, gamma: gamma)) +``` + +We see that the filler is indeed pre-computed before the $\beta$ construction loop even starts. + +Also recall, that the same routine is called for both forward and reply paths, the difference is in the routing information for the last hop. + +For forward path the `destHop` is the real destination address, encoded as a `Hop` and `id` is set to `default(SURBIdentifier)`, all zero bytes. The forward-path exit uses `destHop` to dial the destination protocol. + +For the reply path the `destHop` is an empty `Hop()`, which serializes as zero address bytes. This marks that the terminal return hop is not forwarding to another destination. 'id' for the reply path is set to random nonzero SURB identifier generated by `buildSurbs`. The original sender uses it to find `connCreds`. + +In what follows we use the reply path as an example (path length is $4$ as before). + +**i = 3**: + +As indicated above, instead of $(A_{i+1}\,\Vert\,D_i\,\Vert\,\gamma_{i+1})$ we will have $(\{0\}^{94}\,\Vert\,\{0\}^{2}\,\Vert\,\mathcal{id}_{\mathsf{SURB}})$, where space normally used for $\gamma_{i+1}$ is used to store SURB id $\mathcal{id}_{\mathsf{SURB}}$ where $\vert\mathcal{id}_{\mathsf{SURB}}\vert = \vert\gamma\vert = 16$ bytes. Just for reference, for the forward path, the final $\beta$ will be set to $(A_\mathsf{DST}\,\Vert\,\{0\}^{2}\,\Vert\,\{0\}^{16})$, where $A_\mathsf{DST}$ is the address of the destination node. + +Now, $\vert(\{0\}^{94}\,\Vert\,\{0\}^{2}\,\Vert\,\mathcal{id}_{\mathsf{SURB}})\vert = 112$ bytes. The final routing information is naturally shortest (there are no more hops after it), thus in order to keep size of $\beta$ constant ($576$ bytes), we add some extra padding (`PaddingLength`) and the full filler ($3\times 112 = 336$ bytes). The extra `PaddingLength` is the consequence of the fact, that the size of $\beta$ has been chosen to accommodate max $r=5$ hops, corresponding to $5\times112=560$ bytes plus extra $\kappa=16$ bytes for future use (or for some other reason), giving $576$ in total. Because for 4-hop path, the filler is $3\times 112 = 336$ bytes long `PaddingLength` is: + +$$ +\begin{aligned} +\mathsf{PaddingLength} +&= \vert\beta\vert - \vert(\{0\}^{94}\,\Vert\,\{0\}^{2}\,\Vert\,\mathcal{id}_{\mathsf{SURB}})\vert - \vert\mathsf{filler}\vert \\ +&= 576 - 112 - 336 = 128 +\end{aligned} +$$ + +or in a more generic form: + +$$ +\mathsf{PaddingLength} = (((t + 1)(r - \mathsf{PathLength})) + 1)k +$$ + +In our case `PathLength = 4`, thus, + +$$ +\begin{aligned} +\mathsf{PaddingLength} +&= (((6 + 1)(5 - 4)) + 1)\times16 \\ +&= (7 + 1) \times 16 \\ +&= 128 +\end{aligned} +$$ + +Before encryption thus, we have: + +$$ +\begin{matrix} +\widetilde\beta_3 \; = \ \\ +\small\vphantom{a} \\ +\small\vphantom{a} \\ +\small\vphantom{a} +\end{matrix} +\begin{matrix} +(\{0\}^{94}\,\Vert\,\{0\}^{2}\,\Vert\,\mathcal{id}_{\mathsf{SURB}}\,\Vert\,\{0\}^{128}) \\ +\small\vphantom{a} \\ +\small\vphantom{a} \\ +\small\vphantom{a} +\end{matrix} +\begin{matrix} +\quad\Large\Vert\quad \\ +\small\vphantom{a} \\ +\small\vphantom{a} \\ +\small\vphantom{a} +\end{matrix} +\begin{array}{l} +\{0\}^{112} \\ +\,\left\vert +\begin{matrix} +\small\;\mathcal{S}_0[576,688) \\ +\small\;\mathcal{S}_1[464,576) \\ +\small\;\mathcal{S}_2[352,464) +\end{matrix} +\right. +\end{array} +\begin{matrix} +\quad\Large\Vert\quad \\ +\small\vphantom{a} \\ +\small\vphantom{a} \\ +\small\vphantom{a} +\end{matrix} +\begin{array}{l} +\{0\}^{112} \\ +\,\left\vert +\begin{matrix} +\small\vphantom{a} \\ +\small\;\mathcal{S}_1[576,688) \\ +\small\;\mathcal{S}_2[464,576) +\end{matrix} +\right. +\end{array} +\begin{matrix} +\quad\Large\Vert\quad \\ +\small\vphantom{a} \\ +\small\vphantom{a} \\ +\small\vphantom{a} +\end{matrix} +\begin{array}{l} +\{0\}^{112} \\ +\,\left\vert +\begin{matrix} +\small\vphantom{a} \\ +\small\vphantom{a} \\ +\small\;\mathcal{S}_2[576,688) +\end{matrix} +\right. +\end{array} +$$ + +and after encryption $\widetilde\beta_3\;\oplus\;(\mathcal{S}_3[0,240)\;\Vert\;\{0\}^{3\times 112})$: + +$$ +\begin{matrix} +\beta_3 \; = \ \\ +\small\vphantom{a} \\ +\small\vphantom{a} \\ +\small\vphantom{a} +\end{matrix} +\begin{array}{l} +(\{0\}^{94}\,\Vert\,\{0\}^{2}\,\Vert\,\mathcal{id}_{\mathsf{SURB}}\,\Vert\,\{0\}^{128}) \\ +\,\left\vert +\begin{matrix} +\small\vphantom{a} \\ +\small\vphantom{a} \\ +\small\;\mathcal{S}_3[0,240) +\end{matrix} +\right. +\end{array} +\begin{matrix} +\quad\Large\Vert\quad \\ +\small\vphantom{a} \\ +\small\vphantom{a} \\ +\small\vphantom{a} +\end{matrix} +\begin{array}{l} +\{0\}^{112} \\ +\,\left\vert +\begin{matrix} +\small\;\mathcal{S}_0[576,688) \\ +\small\;\mathcal{S}_1[464,576) \\ +\small\;\mathcal{S}_2[352,464) +\end{matrix} +\right. +\end{array} +\begin{matrix} +\quad\Large\Vert\quad \\ +\small\vphantom{a} \\ +\small\vphantom{a} \\ +\small\vphantom{a} +\end{matrix} +\begin{array}{l} +\{0\}^{112} \\ +\,\left\vert +\begin{matrix} +\small\vphantom{a} \\ +\small\;\mathcal{S}_1[576,688) \\ +\small\;\mathcal{S}_2[464,576) +\end{matrix} +\right. +\end{array} +\begin{matrix} +\quad\Large\Vert\quad \\ +\small\vphantom{a} \\ +\small\vphantom{a} \\ +\small\vphantom{a} +\end{matrix} +\begin{array}{l} +\{0\}^{112} \\ +\,\left\vert +\begin{matrix} +\small\vphantom{a} \\ +\small\vphantom{a} \\ +\small\;\mathcal{S}_2[576,688) +\end{matrix} +\right. +\end{array} +$$ + +Notice that in this first iteration only $(\{0\}^{94}\,\Vert\,\{0\}^{2}\,\Vert\,\mathcal{id}_{\mathsf{SURB}}\,\Vert\,\{0\}^{128})$ is encrypted and the filler is used pre-computed. + +**i = 2**: + +From $\beta_3$, we drop the last filler segment ($112$ bytes) and prepend the routing info: + +$$ +\begin{matrix} +\widetilde\beta_2 \; = \ \\ +\small\vphantom{a} \\ +\small\vphantom{a} \\ +\small\vphantom{a} +\end{matrix} +\begin{matrix} +(A_3\,\Vert\,D_2\,\Vert\,\gamma_3) \\ +\small\vphantom{a} \\ +\small\vphantom{a} \\ +\small\vphantom{a} +\end{matrix} +\begin{matrix} +\quad\Large\Vert\quad \\ +\small\vphantom{a} \\ +\small\vphantom{a} \\ +\small\vphantom{a} +\end{matrix} +\begin{array}{l} +(\{0\}^{94}\,\Vert\,\{0\}^{2}\,\Vert\,\mathcal{id}_{\mathsf{SURB}}\,\Vert\,\{0\}^{128}) \\ +\,\left\vert +\begin{matrix} +\small\vphantom{a} \\ +\small\vphantom{a} \\ +\small\;\mathcal{S}_3[0,240) +\end{matrix} +\right. +\end{array} +\begin{matrix} +\quad\Large\Vert\quad \\ +\small\vphantom{a} \\ +\small\vphantom{a} \\ +\small\vphantom{a} +\end{matrix} +\begin{array}{l} +\{0\}^{112} \\ +\,\left\vert +\begin{matrix} +\small\;\mathcal{S}_0[576,688) \\ +\small\;\mathcal{S}_1[464,576) \\ +\small\;\mathcal{S}_2[352,464) +\end{matrix} +\right. +\end{array} +\begin{matrix} +\quad\Large\Vert\quad \\ +\small\vphantom{a} \\ +\small\vphantom{a} \\ +\small\vphantom{a} +\end{matrix} +\begin{array}{l} +\{0\}^{112} \\ +\,\left\vert +\begin{matrix} +\small\vphantom{a} \\ +\small\;\mathcal{S}_1[576,688) \\ +\small\;\mathcal{S}_2[464,576) +\end{matrix} +\right. +\end{array} +$$ + +and after encrypting $\widetilde\beta_2\;\oplus\mathcal{S}_2[0,576)$ w: + +$$ +\begin{matrix} +\beta_2 \; = \ \\ +\small\vphantom{a} \\ +\small\vphantom{a} \\ +\small\vphantom{a} \\ +\small\vphantom{a} +\end{matrix} +\begin{array}{l} +(A_3\,\Vert\,D_2\,\Vert\,\gamma_3) \\ +\,\left\vert +\begin{matrix} +\small\vphantom{a} \\ +\small\vphantom{a} \\ +\small\vphantom{a} \\ +\small\;\mathcal{S}_2[0,112) +\end{matrix} +\right. +\end{array} +\begin{matrix} +\quad\Large\Vert\quad \\ +\small\vphantom{a} \\ +\small\vphantom{a} \\ +\small\vphantom{a} \\ +\small\vphantom{a} +\end{matrix} +\begin{array}{l} +(\{0\}^{94}\,\Vert\,\{0\}^{2}\,\Vert\,\mathcal{id}_{\mathsf{SURB}}\,\Vert\,\{0\}^{128}) \\ +\,\left\vert +\begin{array}{l} +\small\vphantom{a} \\ +\small\vphantom{a} \\ +\small\;\mathcal{S}_3[0,240) \\ +\small\;\mathcal{S}_2[112,352) +\end{array} +\right. +\end{array} +\begin{matrix} +\quad\Large\Vert\quad \\ +\small\vphantom{a} \\ +\small\vphantom{a} \\ +\small\vphantom{a} \\ +\small\vphantom{a} +\end{matrix} +\begin{array}{l} +\{0\}^{112} \\ +\,\left\vert +\begin{matrix} +\small\;\mathcal{S}_0[576,688) \\ +\small\;\mathcal{S}_1[464,576) \\ +\small\;\enclose{horizontalstrike}{\mathcal{S}_2[352,464)} \\ +\small\;\enclose{horizontalstrike}{\mathcal{S}_2[352,464)} +\end{matrix} +\right. +\end{array} +\begin{matrix} +\quad\Large\Vert\quad \\ +\small\vphantom{a} \\ +\small\vphantom{a} \\ +\small\vphantom{a} \\ +\small\vphantom{a} +\end{matrix} +\begin{array}{l} +\{0\}^{112} \\ +\,\left\vert +\begin{matrix} +\small\vphantom{a} \\ +\small\;\mathcal{S}_1[576,688) \\ +\small\;\enclose{horizontalstrike}{\mathcal{S}_2[464,576)} \\ +\small\;\enclose{horizontalstrike}{\mathcal{S}_2[464,576)} +\end{matrix} +\right. +\end{array} +$$ + +which after canceling out the outer filler encryption becomes: + +$$ +\begin{matrix} +\beta_2 \; = \ \\ +\small\vphantom{a} \\ +\small\vphantom{a} +\end{matrix} +\begin{array}{l} +(A_3\,\Vert\,D_2\,\Vert\,\gamma_3) \\ +\,\left\vert +\begin{matrix} +\small\vphantom{a} \\ +\small\;\mathcal{S}_2[0,112) +\end{matrix} +\right. +\end{array} +\begin{matrix} +\quad\Large\Vert\quad \\ +\small\vphantom{a} \\ +\small\vphantom{a} +\end{matrix} +\begin{array}{l} +(\{0\}^{94}\,\Vert\,\{0\}^{2}\,\Vert\,\mathcal{id}_{\mathsf{SURB}}\,\Vert\,\{0\}^{128}) \\ +\,\left\vert +\begin{array}{l} +\small\;\mathcal{S}_3[0,240) \\ +\small\;\mathcal{S}_2[112,352) +\end{array} +\right. +\end{array} +\begin{matrix} +\quad\Large\Vert\quad \\ +\small\vphantom{a} \\ +\small\vphantom{a} +\end{matrix} +\begin{array}{l} +\{0\}^{112} \\ +\,\left\vert +\begin{matrix} +\small\;\mathcal{S}_0[576,688) \\ +\small\;\mathcal{S}_1[464,576) +\end{matrix} +\right. +\end{array} +\begin{matrix} +\quad\Large\Vert\quad \\ +\small\vphantom{a} \\ +\small\vphantom{a} +\end{matrix} +\begin{array}{l} +\{0\}^{112} \\ +\,\left\vert +\begin{matrix} +\small\vphantom{a} \\ +\small\;\mathcal{S}_1[576,688) +\end{matrix} +\right. +\end{array} +$$ + +**i = 1**: + +Here again, before next level of encryption, we drop the last filler segment ($112$ bytes) from and prepend the routing info to $\beta_2$: + +$$ +\begin{matrix} +\widetilde\beta_1 \; = \ \\ +\small\vphantom{a} \\ +\small\vphantom{a} +\end{matrix} +\begin{matrix} +(A_2\,\Vert\,D_1\,\Vert\,\gamma_2) \\ +\small\vphantom{a} \\ +\small\vphantom{a} +\end{matrix} +\begin{matrix} +\quad\Large\Vert\quad \\ +\small\vphantom{a} \\ +\small\vphantom{a} +\end{matrix} +\begin{array}{l} +(A_3\,\Vert\,D_2\,\Vert\,\gamma_3) \\ +\,\left\vert +\begin{matrix} +\small\vphantom{a} \\ +\small\;\mathcal{S}_2[0,112) +\end{matrix} +\right. +\end{array} +\begin{matrix} +\quad\Large\Vert\quad \\ +\small\vphantom{a} \\ +\small\vphantom{a} +\end{matrix} +\begin{array}{l} +(\{0\}^{94}\,\Vert\,\{0\}^{2}\,\Vert\,\mathcal{id}_{\mathsf{SURB}}\,\Vert\,\{0\}^{128}) \\ +\,\left\vert +\begin{array}{l} +\small\;\mathcal{S}_3[0,240) \\ +\small\;\mathcal{S}_2[112,352) +\end{array} +\right. +\end{array} +\begin{matrix} +\quad\Large\Vert\quad \\ +\small\vphantom{a} \\ +\small\vphantom{a} +\end{matrix} +\begin{array}{l} +\{0\}^{112} \\ +\,\left\vert +\begin{matrix} +\small\;\mathcal{S}_0[576,688) \\ +\small\;\mathcal{S}_1[464,576) +\end{matrix} +\right. +\end{array} +$$ + +and after encrypting $\widetilde\beta_1\;\oplus\mathcal{S}_1[0,576)$: + +$$ +\begin{matrix} +\beta_1 \; = \ \\ +\small\vphantom{a} \\ +\small\vphantom{a} \\ +\small\vphantom{a} +\end{matrix} +\begin{array}{l} +(A_2\,\Vert\,D_1\,\Vert\,\gamma_2) \\ +\,\left\vert +\begin{matrix} +\small\vphantom{a} \\ +\small\vphantom{a} \\ +\small\;\mathcal{S}_1[0,112) +\end{matrix} +\right. +\end{array} +\begin{matrix} +\quad\Large\Vert\quad \\ +\small\vphantom{a} \\ +\small\vphantom{a} \\ +\small\vphantom{a} +\end{matrix} +\begin{array}{l} +(A_3\,\Vert\,D_2\,\Vert\,\gamma_3) \\ +\,\left\vert +\begin{array}{l} +\small\vphantom{a} \\ +\small\;\mathcal{S}_2[0,112) \\ +\small\;\mathcal{S}_1[112,224) +\end{array} +\right. +\end{array} +\begin{matrix} +\quad\Large\Vert\quad \\ +\small\vphantom{a} \\ +\small\vphantom{a} \\ +\small\vphantom{a} +\end{matrix} +\begin{array}{l} +(\{0\}^{94}\,\Vert\,\{0\}^{2}\,\Vert\,\mathcal{id}_{\mathsf{SURB}}\,\Vert\,\{0\}^{128}) \\ +\,\left\vert +\begin{array}{l} +\small\;\mathcal{S}_3[0,240) \\ +\small\;\mathcal{S}_2[112,352) \\ +\small\;\mathcal{S}_1[224,464) +\end{array} +\right. +\end{array} +\begin{matrix} +\quad\Large\Vert\quad \\ +\small\vphantom{a} \\ +\small\vphantom{a} \\ +\small\vphantom{a} +\end{matrix} +\begin{array}{l} +\{0\}^{112} \\ +\,\left\vert +\begin{matrix} +\small\;\mathcal{S}_0[576,688) \\ +\small\;\enclose{horizontalstrike}{\mathcal{S}_1[464,576)} \\ +\small\;\enclose{horizontalstrike}{\mathcal{S}_1[464,576)} +\end{matrix} +\right. +\end{array} +$$ + +which leaves us with: + +$$ +\begin{matrix} +\beta_1 \; = \ \\ +\small\vphantom{a} \\ +\small\vphantom{a} \\ +\small\vphantom{a} +\end{matrix} +\begin{array}{l} +(A_2\,\Vert\,D_1\,\Vert\,\gamma_2) \\ +\,\left\vert +\begin{matrix} +\small\vphantom{a} \\ +\small\vphantom{a} \\ +\small\;\mathcal{S}_1[0,112) +\end{matrix} +\right. +\end{array} +\begin{matrix} +\quad\Large\Vert\quad \\ +\small\vphantom{a} \\ +\small\vphantom{a} \\ +\small\vphantom{a} +\end{matrix} +\begin{array}{l} +(A_3\,\Vert\,D_2\,\Vert\,\gamma_3) \\ +\,\left\vert +\begin{array}{l} +\small\vphantom{a} \\ +\small\;\mathcal{S}_2[0,112) \\ +\small\;\mathcal{S}_1[112,224) +\end{array} +\right. +\end{array} +\begin{matrix} +\quad\Large\Vert\quad \\ +\small\vphantom{a} \\ +\small\vphantom{a} \\ +\small\vphantom{a} +\end{matrix} +\begin{array}{l} +(\{0\}^{94}\,\Vert\,\{0\}^{2}\,\Vert\,\mathcal{id}_{\mathsf{SURB}}\,\Vert\,\{0\}^{128}) \\ +\,\left\vert +\begin{array}{l} +\small\;\mathcal{S}_3[0,240) \\ +\small\;\mathcal{S}_2[112,352) \\ +\small\;\mathcal{S}_1[224,464) +\end{array} +\right. +\end{array} +\begin{matrix} +\quad\Large\Vert\quad \\ +\small\vphantom{a} \\ +\small\vphantom{a} \\ +\small\vphantom{a} +\end{matrix} +\begin{array}{l} +\{0\}^{112} \\ +\,\left\vert +\begin{matrix} +\small\vphantom{a} \\ +\small\vphantom{a} \\ +\small\;\mathcal{S}_0[576,688) +\end{matrix} +\right. +\end{array} +$$ + +**i = 0**: final construction step. + +$$ +\begin{matrix} +\widetilde\beta_0 \; = \ \\ +\small\vphantom{a} \\ +\small\vphantom{a} \\ +\small\vphantom{a} +\end{matrix} +\begin{matrix} +(A_1\,\Vert\,D_0\,\Vert\,\gamma_1) \\ +\small\vphantom{a} \\ +\small\vphantom{a} \\ +\small\vphantom{a} +\end{matrix} +\begin{matrix} +\quad\Large\Vert\quad \\ +\small\vphantom{a} \\ +\small\vphantom{a} \\ +\small\vphantom{a} +\end{matrix} +\begin{array}{l} +(A_2\,\Vert\,D_1\,\Vert\,\gamma_2) \\ +\,\left\vert +\begin{matrix} +\small\vphantom{a} \\ +\small\vphantom{a} \\ +\small\;\mathcal{S}_1[0,112) +\end{matrix} +\right. +\end{array} +\begin{matrix} +\quad\Large\Vert\quad \\ +\small\vphantom{a} \\ +\small\vphantom{a} \\ +\small\vphantom{a} +\end{matrix} +\begin{array}{l} +(A_3\,\Vert\,D_2\,\Vert\,\gamma_3) \\ +\,\left\vert +\begin{array}{l} +\small\vphantom{a} \\ +\small\;\mathcal{S}_2[0,112) \\ +\small\;\mathcal{S}_1[112,224) +\end{array} +\right. +\end{array} +\begin{matrix} +\quad\Large\Vert\quad \\ +\small\vphantom{a} \\ +\small\vphantom{a} \\ +\small\vphantom{a} +\end{matrix} +\begin{array}{l} +(\{0\}^{94}\,\Vert\,\{0\}^{2}\,\Vert\,\mathcal{id}_{\mathsf{SURB}}\,\Vert\,\{0\}^{128}) \\ +\,\left\vert +\begin{array}{l} +\small\;\mathcal{S}_3[0,240) \\ +\small\;\mathcal{S}_2[112,352) \\ +\small\;\mathcal{S}_1[224,464) +\end{array} +\right. +\end{array} +$$ + +which after encryption $\widetilde\beta_0\;\oplus\mathcal{S}_0[0,576)$ gives us: + +$$ +\begin{matrix} +\beta_0 \; = \ \\ +\small\vphantom{a} \\ +\small\vphantom{a} \\ +\small\vphantom{a} \\ +\small\vphantom{a} +\end{matrix} +\begin{array}{l} +(A_1\,\Vert\,D_0\,\Vert\,\gamma_1) \\ +\,\left\vert +\begin{matrix} +\small\vphantom{a} \\ +\small\vphantom{a} \\ +\small\vphantom{a} \\ +\small\;\mathcal{S}_0[0,112) +\end{matrix} +\right. +\end{array} +\begin{matrix} +\quad\Large\Vert\quad \\ +\small\vphantom{a} \\ +\small\vphantom{a} \\ +\small\vphantom{a} \\ +\small\vphantom{a} +\end{matrix} +\begin{array}{l} +(A_2\,\Vert\,D_1\,\Vert\,\gamma_2) \\ +\,\left\vert +\begin{array}{l} +\small\vphantom{a} \\ +\small\vphantom{a} \\ +\small\;\mathcal{S}_1[0,112) \\ +\small\;\mathcal{S}_0[112,224) +\end{array} +\right. +\end{array} +\begin{matrix} +\quad\Large\Vert\quad \\ +\small\vphantom{a} \\ +\small\vphantom{a} \\ +\small\vphantom{a} \\ +\small\vphantom{a} +\end{matrix} +\begin{array}{l} +(A_3\,\Vert\,D_2\,\Vert\,\gamma_3) \\ +\,\left\vert +\begin{array}{l} +\small\vphantom{a} \\ +\small\;\mathcal{S}_2[0,112) \\ +\small\;\mathcal{S}_1[112,224) \\ +\small\;\mathcal{S}_0[224,336) +\end{array} +\right. +\end{array} +\begin{matrix} +\quad\Large\Vert\quad \\ +\small\vphantom{a} \\ +\small\vphantom{a} \\ +\small\vphantom{a} \\ +\small\vphantom{a} +\end{matrix} +\begin{array}{l} +(\{0\}^{94}\,\Vert\,\{0\}^{2}\,\Vert\,\mathcal{id}_{\mathsf{SURB}}\,\Vert\,\{0\}^{128}) \\ +\,\left\vert +\begin{array}{l} +\small\;\mathcal{S}_3[0,240) \\ +\small\;\mathcal{S}_2[112,352) \\ +\small\;\mathcal{S}_1[224,464) \\ +\small\;\mathcal{S}_0[336,576) +\end{array} +\right. +\end{array} +$$ + +No fillers are left at this last step, thus nothing cancels out. + +All those computations are happening in the entry layer of the node that wishes to use the MIX network for anonymous communication. The computed $\beta_0$, together with $\alpha_0$ and $\gamma_0$, will form the header $\mathcal{H}_0=(\alpha_0,\beta_0,\gamma_0)$. Each SURB header will be included in the corresponding SURB packet. All SURBs will be pre-pended to the message forming the actual payload $\delta$, which after onion encryption together with the forward path header will be sent to the first forward path hop. The exit node seeing that the reply is expected will retrieve the reply message from the destination node and send it back using all included SURB packets. + +## Processing the header + +When processing, at each hop $i$ the node removes its own routing information, i.e. the $(t+1)\kappa=112$ bytes, containing sequence $(A_{i+1}\,\Vert\,D_i\,\Vert\,\gamma_{i+1})$, where $A_{i+1}$ is the address of the next hop, $D_i$ is the delay for the current hop, and $\gamma_{i+1}$ is the MAC of the (encrypted) next $\beta$ (so, $\beta_{i+1}$). The tricky part is that the whole $\beta$ is encrypted and $\beta_{i+1}$ (further encrypted with $\mathcal{S}_{i+1}$) inside of it is missing the last $112$ bytes that were removed during header construction to accommodate the routing information of the **previous** hop (remember we are be going backward during header construction) while keeping the header size constant. We already know that the current node cannot just directly decrypt the whole $\beta_i$, and pad the last $112$ bytes with e.g. $\{0\}^{112}$, because this would leak the information about the message position in the mix path. Instead it makes sure that the last $112$ bytes are random. It achieves this by using its own decryption keystream (derived from its secret $s_i$) it uses to decrypt $\beta_i$. It does so, by appending $\{0\}^{112}$ **before** decrypting its own $\beta_i$. Thus, for all hops except the final one, the received $\beta_i$ is: + +$$ +\beta_i = ((A_{i+1}\,\Vert\,D_i\,\Vert\,\gamma_{i+1})\;\Vert\;\mathsf{trunc}_{[0,464)}(\beta_{i+1}))\oplus\mathcal{S}_i[0,576) +$$ + +Or using our special notation: + +$$ +\begin{matrix} +\beta_i \; = \ \\ +\vphantom{a} +\end{matrix} +\begin{array}{l} +(A_{i+1}\,\Vert\,D_i\,\Vert\,\gamma_{i+1}) \\ +\,\left\vert +\begin{matrix} +\small\;\mathcal{S}_i[0,112) +\end{matrix} +\right. +\end{array} +\begin{matrix} +\quad\Large\Vert\quad \\ +\vphantom{a} +\end{matrix} +\begin{array}{l} +\mathsf{trunc}(\beta_{i+1}) \\ +\,\left\vert +\begin{matrix} +\small\;\mathcal{S}_i[112,576) +\end{matrix} +\right. +\end{array} +$$ + +Before decrypting $\beta_i$ using $\mathcal{S}_i$, we first append $\{0\}^{112}$ to it. Then we perform XOR operation +using $\mathcal{S}_i[0,688)$: +$$ +\begin{matrix} +\mathcal{B}_i \; = \ \\ +\vphantom{a} \\ +\vphantom{a} +\end{matrix} +\begin{array}{l} +(A_{i+1}\,\Vert\,D_i\,\Vert\,\gamma_{i+1}) \\ +\,\left\vert +\begin{matrix} +\small\enclose{horizontalstrike}{\mathcal{S}_i[0,112)} \\ +\small\enclose{horizontalstrike}{\mathcal{S}_i[0,112)} +\end{matrix} +\right. +\end{array} +\begin{matrix} +\quad\Large\Vert\quad \\ +\vphantom{a} \\ +\vphantom{a} +\end{matrix} +\begin{array}{l} +\mathsf{trunc}(\beta_{i+1}) \\ +\,\left\vert +\begin{matrix} +\small\enclose{horizontalstrike}{\mathcal{S}_i[112,576)} \\ +\small\enclose{horizontalstrike}{\mathcal{S}_i[112,576)} +\end{matrix} +\right. +\end{array} +\begin{matrix} +\quad\Large\Vert\quad \\ +\vphantom{a} \\ +\vphantom{a} +\end{matrix} +\begin{array}{l} +\{0\}^{112} \\ +\,\left\vert +\begin{matrix} +\small\vphantom{a} \\ +\small\;\mathcal{S}_i[576,688) +\end{matrix} +\right. +\end{array}\color{blue} +$$ + +which is nothing more than $(\beta_i\;\Vert\;\{0\}^{112})\;\oplus\;\mathcal{S}_i[0,688)$: + +$$ +\begin{matrix} +\mathcal{B}_i \; = \ \\ +\small\vphantom{a} +\end{matrix} +\begin{matrix} +(A_{i+1}\,\Vert\,D_i\,\Vert\,\gamma_{i+1}) \\ +\small\vphantom{a} +\end{matrix} +\begin{matrix} +\;\Large\Vert\; \\ +\vphantom{a} +\end{matrix} +\begin{matrix} +\mathsf{trunc}(\beta_{i+1}) \\ +\small\vphantom{a} +\end{matrix} +\begin{matrix} +\;\Large\Vert\; \\ +\vphantom{a} +\end{matrix} +\begin{array}{l} +\{0\}^{112} \\ +\,\left\vert +\begin{matrix} +\small\;\mathcal{S}_i[576,688) +\end{matrix} +\right. +\end{array} +\begin{matrix} +\; = \; \\ +\small\vphantom{a} +\end{matrix} +\begin{matrix} +(A_{i+1}\,\Vert\,D_i\,\Vert\,\gamma_{i+1}) \\ +\small\vphantom{a} +\end{matrix} +\begin{matrix} +\;\Large\Vert\; \\ +\vphantom{a} +\end{matrix} +\begin{matrix} +\beta_{i+1} \\ +\small\vphantom{a} +\end{matrix} +$$ +$\beta_{i+1}$ above is the $\beta$ that the next hop will receive and its MAC will have to match $\gamma_{i+1}$. The $\{0\}^{112}\;\oplus\;\mathcal{S}_i[576,688)$ in the equation above, is part of the filler, and each hop will reveal another fragment of it. On arriving at the last hop, the whole filler will be reconstructed. For example, for a 4-hop reply path, the $\beta_3$ received by the last Mix node on the path will be: + +$$ +\beta_3 = ((\{0\}^{94}\,\Vert\,\{0\}^{2}\,\Vert\,\mathcal{id}_{\mathsf{SURB}}\,\Vert\,\{0\}^{128})\;\oplus\;\mathcal{S}_3[0,240))\;\Vert\;\mathsf{filler} +$$ + +Also, here, it will be extended and XORed using $\mathcal{S}_3[0,688)$ resulting in: + +$$ +(\{0\}^{94}\,\Vert\,\{0\}^{2}\,\Vert\,\mathcal{id}_{\mathsf{SURB}}\,\Vert\,\{0\}^{128})\;\Vert\;(\mathsf{filler}\;\oplus\;\mathcal{S}_3[240,688)) +$$ + +The filler part will be dropped leaving us with: + +$$ +(\{0\}^{94}\,\Vert\,\{0\}^{2}\,\Vert\,\mathcal{id}_{\mathsf{SURB}}\,\Vert\,\{0\}^{128}) +$$ + +For the forward path the processing will be analogical, the only difference is that instead of $(\{0\}^{94}\,\Vert\,\{0\}^{2}\,\Vert\,\mathcal{id}_{\mathsf{SURB}}\,\Vert\,\{0\}^{128})$ in $\beta_3$ we will have $(A_\mathsf{DST}\,\Vert\,\{0\}^{2}\,\Vert\,\{0\}^{16}\,\Vert\,\{0\}^{128})$. + + +Let's take a look at an example processing in the reply path. It is largely identical to the forward path, only the processing at the final destination, which in case of SURB packets is the original sender, will be different. + +The exit node sends the encrypted payload (with the key included in the given SURB), to the first hop on the return path. The address of the corresponding mix node is included in the SURB packet. Thus, our processing example starts at thevery fist hop - hop 0. + +**hop 0**: + +The node extracts $\alpha_0$, $\beta_0$, and $\gamma_0$ from the header. Using $\alpha_0$ and its own private key, it derives the shared secret $s_0$, from which other keys are subsequently derived. In this document we focus on the processing of the $\beta$ element, so the details of the key derivation are skipped. We assume that the node has $\mathcal{S}_0$ - the AES-CTR keystream derived from the per-hop shared secret $s_0$. + +Before decrypting $\beta_0$, the node appends $\{0\}^{112}$ to the end of it: + +$$ +\mathcal{B}_0 = (\beta_0\;\Vert\;\{0\}^{112})\;\oplus\;\mathcal{S}_0[0,688) +$$ + +With more details: + +$$ +\begin{matrix} +\mathcal{B}_0 \; = \ \\ +\small\vphantom{a} \\ +\small\vphantom{a} \\ +\small\vphantom{a} \\ +\small\vphantom{a} \\ +\small\vphantom{a} +\end{matrix} +\begin{array}{l} +(A_1\,\Vert\,D_0\,\Vert\,\gamma_1) \\ +\,\left\vert +\begin{matrix} +\small\vphantom{a} \\ +\small\vphantom{a} \\ +\small\vphantom{a} \\ +\small\;\enclose{horizontalstrike}{\mathcal{S}_0[0,112)} \\ +\small\;\enclose{horizontalstrike}{\mathcal{S}_0[0,112)} +\end{matrix} +\right. +\end{array} +\begin{matrix} +\quad\Large\Vert\quad \\ +\small\vphantom{a} \\ +\small\vphantom{a} \\ +\small\vphantom{a} \\ +\small\vphantom{a} \\ +\small\vphantom{a} +\end{matrix} +\begin{array}{l} +(A_2\,\Vert\,D_1\,\Vert\,\gamma_2) \\ +\,\left\vert +\begin{array}{l} +\small\vphantom{a} \\ +\small\vphantom{a} \\ +\small\;\mathcal{S}_1[0,112) \\ +\small\;\enclose{horizontalstrike}{\mathcal{S}_0[112,224)} \\ +\small\;\enclose{horizontalstrike}{\mathcal{S}_0[112,224)} +\end{array} +\right. +\end{array} +\begin{matrix} +\quad\Large\Vert\quad \\ +\small\vphantom{a} \\ +\small\vphantom{a} \\ +\small\vphantom{a} \\ +\small\vphantom{a} \\ +\small\vphantom{a} +\end{matrix} +\begin{array}{l} +(A_3\,\Vert\,D_2\,\Vert\,\gamma_3) \\ +\,\left\vert +\begin{array}{l} +\small\vphantom{a} \\ +\small\;\mathcal{S}_2[0,112) \\ +\small\;\mathcal{S}_1[112,224) \\ +\small\;\enclose{horizontalstrike}{\mathcal{S}_0[224,336)} \\ +\small\;\enclose{horizontalstrike}{\mathcal{S}_0[224,336)} +\end{array} +\right. +\end{array} +\begin{matrix} +\quad\Large\Vert\quad \\ +\small\vphantom{a} \\ +\small\vphantom{a} \\ +\small\vphantom{a} \\ +\small\vphantom{a} \\ +\small\vphantom{a} +\end{matrix} +\begin{array}{l} +(\{0\}^{94}\,\Vert\,\{0\}^{2}\,\Vert\,\mathcal{id}_{\mathsf{SURB}}\,\Vert\,\{0\}^{128}) \\ +\,\left\vert +\begin{array}{l} +\small\;\mathcal{S}_3[0,240) \\ +\small\;\mathcal{S}_2[112,352) \\ +\small\;\mathcal{S}_1[224,464) \\ +\small\;\enclose{horizontalstrike}{\mathcal{S}_0[336,576)} \\ +\small\;\enclose{horizontalstrike}{\mathcal{S}_0[336,576)} +\end{array} +\right. +\end{array} +\begin{matrix} +\quad\Large\Vert\quad \\ +\small\vphantom{a} \\ +\small\vphantom{a} \\ +\small\vphantom{a} \\ +\small\vphantom{a} \\ +\small\vphantom{a} +\end{matrix} +\begin{array}{l} +\{0\}^{112} \\ +\,\left\vert +\begin{matrix} +\small\vphantom{a} \\ +\small\vphantom{a} \\ +\small\vphantom{a} \\ +\small\vphantom{a} \\ +\small\;\mathcal{S}_0[576,688) +\end{matrix} +\right. +\end{array} +$$ + +which reduces to: + +$$ +\begin{matrix} +\mathcal{B}_0 \; = \ \\ +\small\vphantom{a} \\ +\small\vphantom{a} \\ +\small\vphantom{a} +\end{matrix} +\begin{matrix} +(A_1\,\Vert\,D_0\,\Vert\,\gamma_1) \\ +\small\vphantom{a} \\ +\small\vphantom{a} \\ +\small\vphantom{a} +\end{matrix} +\begin{matrix} +\quad\Large\Vert\quad \\ +\small\vphantom{a} \\ +\small\vphantom{a} \\ +\small\vphantom{a} +\end{matrix} +\begin{array}{l} +(A_2\,\Vert\,D_1\,\Vert\,\gamma_2) \\ +\,\left\vert +\begin{matrix} +\small\vphantom{a} \\ +\small\vphantom{a} \\ +\small\;\mathcal{S}_1[0,112) +\end{matrix} +\right. +\end{array} +\begin{matrix} +\quad\Large\Vert\quad \\ +\small\vphantom{a} \\ +\small\vphantom{a} \\ +\small\vphantom{a} +\end{matrix} +\begin{array}{l} +(A_3\,\Vert\,D_2\,\Vert\,\gamma_3) \\ +\,\left\vert +\begin{array}{l} +\small\vphantom{a} \\ +\small\;\mathcal{S}_2[0,112) \\ +\small\;\mathcal{S}_1[112,224) +\end{array} +\right. +\end{array} +\begin{matrix} +\quad\Large\Vert\quad \\ +\small\vphantom{a} \\ +\small\vphantom{a} \\ +\small\vphantom{a} +\end{matrix} +\begin{array}{l} +(\{0\}^{94}\,\Vert\,\{0\}^{2}\,\Vert\,\mathcal{id}_{\mathsf{SURB}}\,\Vert\,\{0\}^{128}) \\ +\,\left\vert +\begin{array}{l} +\small\;\mathcal{S}_3[0,240) \\ +\small\;\mathcal{S}_2[112,352) \\ +\small\;\mathcal{S}_1[224,464) +\end{array} +\right. +\end{array} +\begin{matrix} +\quad\Large\Vert\quad \\ +\small\vphantom{a} \\ +\small\vphantom{a} \\ +\small\vphantom{a} +\end{matrix} +\begin{array}{l} +\{0\}^{112} \\ +\,\left\vert +\begin{matrix} +\small\vphantom{a} \\ +\small\vphantom{a} \\ +\small\;\mathcal{S}_0[576,688) +\end{matrix} +\right. +\end{array} +$$ + +We see that $(A_1\,\Vert\,D_0\,\Vert\,\gamma_1)$ is successfully decrypted. It is then removed and the remaining part is shifted to the left by the size of $(A_1\,\Vert\,D_0\,\Vert\,\gamma_1)$ - $112$ bytes: + +$$ +\begin{matrix} +\beta_1 \; = \ \\ +\small\vphantom{a} \\ +\small\vphantom{a} \\ +\small\vphantom{a} +\end{matrix} +\begin{array}{l} +(A_2\,\Vert\,D_1\,\Vert\,\gamma_2) \\ +\,\left\vert +\begin{matrix} +\small\vphantom{a} \\ +\small\vphantom{a} \\ +\small\;\mathcal{S}_1[0,112) +\end{matrix} +\right. +\end{array} +\begin{matrix} +\quad\Large\Vert\quad \\ +\small\vphantom{a} \\ +\small\vphantom{a} \\ +\small\vphantom{a} +\end{matrix} +\begin{array}{l} +(A_3\,\Vert\,D_2\,\Vert\,\gamma_3) \\ +\,\left\vert +\begin{array}{l} +\small\vphantom{a} \\ +\small\;\mathcal{S}_2[0,112) \\ +\small\;\mathcal{S}_1[112,224) +\end{array} +\right. +\end{array} +\begin{matrix} +\quad\Large\Vert\quad \\ +\small\vphantom{a} \\ +\small\vphantom{a} \\ +\small\vphantom{a} +\end{matrix} +\begin{array}{l} +(\{0\}^{94}\,\Vert\,\{0\}^{2}\,\Vert\,\mathcal{id}_{\mathsf{SURB}}\,\Vert\,\{0\}^{128}) \\ +\,\left\vert +\begin{array}{l} +\small\;\mathcal{S}_3[0,240) \\ +\small\;\mathcal{S}_2[112,352) \\ +\small\;\mathcal{S}_1[224,464) +\end{array} +\right. +\end{array} +\begin{matrix} +\quad\Large\Vert\quad \\ +\small\vphantom{a} \\ +\small\vphantom{a} \\ +\small\vphantom{a} +\end{matrix} +\begin{array}{l} +\{0\}^{112} \\ +\,\left\vert +\begin{matrix} +\small\vphantom{a} \\ +\small\vphantom{a} \\ +\small\;\mathcal{S}_0[576,688) +\end{matrix} +\right. +\end{array} +$$ + +Yes, this is exactly the same $\beta_1$ we constructed in construction phase we shown in the previous section. Notice the appended part of the filler. If there would be any different or misalignement in the reconstructed $\beta_1$, the next node would detect it using the received MAC $\gamma_1$. The node at hop 0 is not able to fake that $\gamma_1$, as it is keyed with $\mathcal{S}_1$, which the node at hop 0 does not have. + +Now we should start seeing how it all works. + +**hop 1**: + +$$ +\mathcal{B}_1 = (\beta_1\;\Vert\;\{0\}^{112})\;\oplus\;\mathcal{S}_1[0,688) +$$ + +$$ +\begin{matrix} +\mathcal{B}_1 \; = \ \\ +\small\vphantom{a} \\ +\small\vphantom{a} \\ +\small\vphantom{a} \\ +\small\vphantom{a} +\end{matrix} +\begin{array}{l} +(A_2\,\Vert\,D_1\,\Vert\,\gamma_2) \\ +\,\left\vert +\begin{matrix} +\small\vphantom{a} \\ +\small\vphantom{a} \\ +\small\;\enclose{horizontalstrike}{\mathcal{S}_1[0,112)} \\ +\small\;\enclose{horizontalstrike}{\mathcal{S}_1[0,112)} +\end{matrix} +\right. +\end{array} +\begin{matrix} +\quad\Large\Vert\quad \\ +\small\vphantom{a} \\ +\small\vphantom{a} \\ +\small\vphantom{a} \\ +\small\vphantom{a} +\end{matrix} +\begin{array}{l} +(A_3\,\Vert\,D_2\,\Vert\,\gamma_3) \\ +\,\left\vert +\begin{array}{l} +\small\vphantom{a} \\ +\small\;\mathcal{S}_2[0,112) \\ +\small\;\enclose{horizontalstrike}{\mathcal{S}_1[112,224)} \\ +\small\;\enclose{horizontalstrike}{\mathcal{S}_1[112,224)} +\end{array} +\right. +\end{array} +\begin{matrix} +\quad\Large\Vert\quad \\ +\small\vphantom{a} \\ +\small\vphantom{a} \\ +\small\vphantom{a} \\ +\small\vphantom{a} +\end{matrix} +\begin{array}{l} +(\{0\}^{94}\,\Vert\,\{0\}^{2}\,\Vert\,\mathcal{id}_{\mathsf{SURB}}\,\Vert\,\{0\}^{128}) \\ +\,\left\vert +\begin{array}{l} +\small\;\mathcal{S}_3[0,240) \\ +\small\;\mathcal{S}_2[112,352) \\ +\small\;\enclose{horizontalstrike}{\mathcal{S}_1[224,464)} \\ +\small\;\enclose{horizontalstrike}{\mathcal{S}_1[224,464)} +\end{array} +\right. +\end{array} +\begin{matrix} +\quad\Large\Vert\quad \\ +\small\vphantom{a} \\ +\small\vphantom{a} \\ +\small\vphantom{a} \\ +\small\vphantom{a} +\end{matrix} +\begin{array}{l} +\{0\}^{112} \\ +\,\left\vert +\begin{matrix} +\small\vphantom{a} \\ +\small\vphantom{a} \\ +\small\;\mathcal{S}_0[576,688) \\ +\small\;\mathcal{S}_1[464,576) +\end{matrix} +\right. +\end{array} +\begin{matrix} +\quad\Large\Vert\quad \\ +\small\vphantom{a} \\ +\small\vphantom{a} \\ +\small\vphantom{a} \\ +\small\vphantom{a} +\end{matrix} +\begin{array}{l} +\{0\}^{112} \\ +\,\left\vert +\begin{matrix} +\small\vphantom{a} \\ +\small\vphantom{a} \\ +\small\vphantom{a} \\ +\small\;\mathcal{S}_1[576,688) +\end{matrix} +\right. +\end{array} +$$ + +This reduces to: + +$$ +\begin{matrix} +\mathcal{B}_1 \; = \ \\ +\small\vphantom{a} \\ +\small\vphantom{a} +\end{matrix} +\begin{matrix} +(A_2\,\Vert\,D_1\,\Vert\,\gamma_2) \\ +\small\vphantom{a} \\ +\small\vphantom{a} +\end{matrix} +\begin{matrix} +\quad\Large\Vert\quad \\ +\small\vphantom{a} \\ +\small\vphantom{a} +\end{matrix} +\begin{array}{l} +(A_3\,\Vert\,D_2\,\Vert\,\gamma_3) \\ +\,\left\vert +\begin{array}{l} +\small\vphantom{a} \\ +\small\;\mathcal{S}_2[0,112) +\end{array} +\right. +\end{array} +\begin{matrix} +\quad\Large\Vert\quad \\ +\small\vphantom{a} \\ +\small\vphantom{a} +\end{matrix} +\begin{array}{l} +(\{0\}^{94}\,\Vert\,\{0\}^{2}\,\Vert\,\mathcal{id}_{\mathsf{SURB}}\,\Vert\,\{0\}^{128}) \\ +\,\left\vert +\begin{array}{l} +\small\;\mathcal{S}_3[0,240) \\ +\small\;\mathcal{S}_2[112,352) +\end{array} +\right. +\end{array} +\begin{matrix} +\quad\Large\Vert\quad \\ +\small\vphantom{a} \\ +\small\vphantom{a} +\end{matrix} +\begin{array}{l} +\{0\}^{112} \\ +\,\left\vert +\begin{matrix} +\small\;\mathcal{S}_0[576,688) \\ +\small\;\mathcal{S}_1[464,576) +\end{matrix} +\right. +\end{array} +\begin{matrix} +\quad\Large\Vert\quad \\ +\small\vphantom{a} \\ +\small\vphantom{a} +\end{matrix} +\begin{array}{l} +\{0\}^{112} \\ +\,\left\vert +\begin{matrix} +\small\vphantom{a} \\ +\small\;\mathcal{S}_1[576,688) +\end{matrix} +\right. +\end{array} +$$ + +After removing $(A_2\,\Vert\,D_1\,\Vert\,\gamma_2)$ and shifting to the left, we get the original constructed $\beta_2$: + +$$ +\begin{matrix} +\beta_2 \; = \ \\ +\small\vphantom{a} \\ +\small\vphantom{a} +\end{matrix} +\begin{array}{l} +(A_3\,\Vert\,D_2\,\Vert\,\gamma_3) \\ +\,\left\vert +\begin{matrix} +\small\vphantom{a} \\ +\small\;\mathcal{S}_2[0,112) +\end{matrix} +\right. +\end{array} +\begin{matrix} +\quad\Large\Vert\quad \\ +\small\vphantom{a} \\ +\small\vphantom{a} +\end{matrix} +\begin{array}{l} +(\{0\}^{94}\,\Vert\,\{0\}^{2}\,\Vert\,\mathcal{id}_{\mathsf{SURB}}\,\Vert\,\{0\}^{128}) \\ +\,\left\vert +\begin{array}{l} +\small\;\mathcal{S}_3[0,240) \\ +\small\;\mathcal{S}_2[112,352) +\end{array} +\right. +\end{array} +\begin{matrix} +\quad\Large\Vert\quad \\ +\small\vphantom{a} \\ +\small\vphantom{a} +\end{matrix} +\begin{array}{l} +\{0\}^{112} \\ +\,\left\vert +\begin{matrix} +\small\;\mathcal{S}_0[576,688) \\ +\small\;\mathcal{S}_1[464,576) +\end{matrix} +\right. +\end{array} +\begin{matrix} +\quad\Large\Vert\quad \\ +\small\vphantom{a} \\ +\small\vphantom{a} +\end{matrix} +\begin{array}{l} +\{0\}^{112} \\ +\,\left\vert +\begin{matrix} +\small\vphantom{a} \\ +\small\;\mathcal{S}_1[576,688) +\end{matrix} +\right. +\end{array} +$$ + +**hop 2**: + +$$ +\mathcal{B}_2 = (\beta_2\;\Vert\;\{0\}^{112})\;\oplus\;\mathcal{S}_2[0,688) +$$ + +$$ +\begin{matrix} +\mathcal{B}_2 \; = \ \\ +\small\vphantom{a} \\ +\small\vphantom{a} \\ +\small\vphantom{a} +\end{matrix} +\begin{array}{l} +(A_3\,\Vert\,D_2\,\Vert\,\gamma_3) \\ +\,\left\vert +\begin{array}{l} +\small\vphantom{a} \\ +\small\;\enclose{horizontalstrike}{\mathcal{S}_2[0,112)} \\ +\small\;\enclose{horizontalstrike}{\mathcal{S}_2[0,112)} +\end{array} +\right. +\end{array} +\begin{matrix} +\quad\Large\Vert\quad \\ +\small\vphantom{a} \\ +\small\vphantom{a} \\ +\small\vphantom{a} +\end{matrix} +\begin{array}{l} +(\{0\}^{94}\,\Vert\,\{0\}^{2}\,\Vert\,\mathcal{id}_{\mathsf{SURB}}\,\Vert\,\{0\}^{128}) \\ +\,\left\vert +\begin{array}{l} +\small\;\mathcal{S}_3[0,240) \\ +\small\;\enclose{horizontalstrike}{\mathcal{S}_2[112,352)} \\ +\small\;\enclose{horizontalstrike}{\mathcal{S}_2[112,352)} +\end{array} +\right. +\end{array} +\begin{matrix} +\quad\Large\Vert\quad \\ +\small\vphantom{a} \\ +\small\vphantom{a} \\ +\small\vphantom{a} +\end{matrix} +\begin{array}{l} +\{0\}^{112} \\ +\,\left\vert +\begin{matrix} +\small\;\mathcal{S}_0[576,688) \\ +\small\;\mathcal{S}_1[464,576) \\ +\small\;\mathcal{S}_2[352,464) +\end{matrix} +\right. +\end{array} +\begin{matrix} +\quad\Large\Vert\quad \\ +\small\vphantom{a} \\ +\small\vphantom{a} \\ +\small\vphantom{a} +\end{matrix} +\begin{array}{l} +\{0\}^{112} \\ +\,\left\vert +\begin{matrix} +\small\vphantom{a} \\ +\small\;\mathcal{S}_1[576,688) \\ +\small\;\mathcal{S}_2[464,576) +\end{matrix} +\right. +\end{array} +\begin{matrix} +\quad\Large\Vert\quad \\ +\small\vphantom{a} \\ +\small\vphantom{a} \\ +\small\vphantom{a} +\end{matrix} +\begin{array}{l} +\{0\}^{112} \\ +\,\left\vert +\begin{matrix} +\small\vphantom{a} \\ +\small\vphantom{a} \\ +\small\;\mathcal{S}_2[576,688) +\end{matrix} +\right. +\end{array} +$$ + +which is: + +$$ +\begin{matrix} +\mathcal{B}_2 \; = \ \\ +\small\vphantom{a} \\ +\small\vphantom{a} \\ +\small\vphantom{a} +\end{matrix} +\begin{matrix} +(A_3\,\Vert\,D_2\,\Vert\,\gamma_3) \\ +\small\vphantom{a} \\ +\small\vphantom{a} \\ +\small\vphantom{a} +\end{matrix} +\begin{matrix} +\quad\Large\Vert\quad \\ +\small\vphantom{a} \\ +\small\vphantom{a} \\ +\small\vphantom{a} +\end{matrix} +\begin{array}{l} +(\{0\}^{94}\,\Vert\,\{0\}^{2}\,\Vert\,\mathcal{id}_{\mathsf{SURB}}\,\Vert\,\{0\}^{128}) \\ +\,\left\vert +\begin{array}{l} +\small\vphantom{a} \\ +\small\vphantom{a} \\ +\small\;\mathcal{S}_3[0,240) +\end{array} +\right. +\end{array} +\begin{matrix} +\quad\Large\Vert\quad \\ +\small\vphantom{a} \\ +\small\vphantom{a} \\ +\small\vphantom{a} +\end{matrix} +\begin{array}{l} +\{0\}^{112} \\ +\,\left\vert +\begin{matrix} +\small\;\mathcal{S}_0[576,688) \\ +\small\;\mathcal{S}_1[464,576) \\ +\small\;\mathcal{S}_2[352,464) +\end{matrix} +\right. +\end{array} +\begin{matrix} +\quad\Large\Vert\quad \\ +\small\vphantom{a} \\ +\small\vphantom{a} \\ +\small\vphantom{a} +\end{matrix} +\begin{array}{l} +\{0\}^{112} \\ +\,\left\vert +\begin{matrix} +\small\vphantom{a} \\ +\small\;\mathcal{S}_1[576,688) \\ +\small\;\mathcal{S}_2[464,576) +\end{matrix} +\right. +\end{array} +\begin{matrix} +\quad\Large\Vert\quad \\ +\small\vphantom{a} \\ +\small\vphantom{a} \\ +\small\vphantom{a} +\end{matrix} +\begin{array}{l} +\{0\}^{112} \\ +\,\left\vert +\begin{matrix} +\small\vphantom{a} \\ +\small\vphantom{a} \\ +\small\;\mathcal{S}_2[576,688) +\end{matrix} +\right. +\end{array} +$$ + +which, after removing $(A_3\,\Vert\,D_2\,\Vert\,\gamma_3)$ and shifting, gives us: + +$$ +\begin{matrix} +\beta_3 \; = \ \\ +\small\vphantom{a} \\ +\small\vphantom{a} \\ +\small\vphantom{a} +\end{matrix} +\begin{array}{l} +(\{0\}^{94}\,\Vert\,\{0\}^{2}\,\Vert\,\mathcal{id}_{\mathsf{SURB}}\,\Vert\,\{0\}^{128}) \\ +\,\left\vert +\begin{matrix} +\small\vphantom{a} \\ +\small\vphantom{a} \\ +\small\;\mathcal{S}_3[0,240) +\end{matrix} +\right. +\end{array} +\begin{matrix} +\quad\Large\Vert\quad \\ +\small\vphantom{a} \\ +\small\vphantom{a} \\ +\small\vphantom{a} +\end{matrix} +\begin{array}{l} +\{0\}^{112} \\ +\,\left\vert +\begin{matrix} +\small\;\mathcal{S}_0[576,688) \\ +\small\;\mathcal{S}_1[464,576) \\ +\small\;\mathcal{S}_2[352,464) +\end{matrix} +\right. +\end{array} +\begin{matrix} +\quad\Large\Vert\quad \\ +\small\vphantom{a} \\ +\small\vphantom{a} \\ +\small\vphantom{a} +\end{matrix} +\begin{array}{l} +\{0\}^{112} \\ +\,\left\vert +\begin{matrix} +\small\vphantom{a} \\ +\small\;\mathcal{S}_1[576,688) \\ +\small\;\mathcal{S}_2[464,576) +\end{matrix} +\right. +\end{array} +\begin{matrix} +\quad\Large\Vert\quad \\ +\small\vphantom{a} \\ +\small\vphantom{a} \\ +\small\vphantom{a} +\end{matrix} +\begin{array}{l} +\{0\}^{112} \\ +\,\left\vert +\begin{matrix} +\small\vphantom{a} \\ +\small\vphantom{a} \\ +\small\;\mathcal{S}_2[576,688) +\end{matrix} +\right. +\end{array} +$$ + +It matches $\beta_3$ from the construction phase, and we also now see fully reconstructed filler. + +**hop 3**: + +$$ +\mathcal{B}_3 = (\beta_3\;\Vert\;\{0\}^{112})\;\oplus\;\mathcal{S}_3[0,688) +$$ + +$$ +\begin{matrix} +\mathcal{B}_3 \; = \ \\ +\small\vphantom{a} \\ +\small\vphantom{a} \\ +\small\vphantom{a} \\ +\small\vphantom{a} +\end{matrix} +\begin{array}{l} +(\{0\}^{94}\,\Vert\,\{0\}^{2}\,\Vert\,\mathcal{id}_{\mathsf{SURB}}\,\Vert\,\{0\}^{128}) \\ +\,\left\vert +\begin{matrix} +\small\vphantom{a} \\ +\small\vphantom{a} \\ +\small\;\enclose{horizontalstrike}{\mathcal{S}_3[0,240)} \\ +\small\;\enclose{horizontalstrike}{\mathcal{S}_3[0,240)} +\end{matrix} +\right. +\end{array} +\begin{matrix} +\quad\Large\Vert\quad \\ +\small\vphantom{a} \\ +\small\vphantom{a} \\ +\small\vphantom{a} \\ +\small\vphantom{a} +\end{matrix} +\begin{array}{l} +\{0\}^{112} \\ +\,\left\vert +\begin{matrix} +\small\;\mathcal{S}_0[576,688) \\ +\small\;\mathcal{S}_1[464,576) \\ +\small\;\mathcal{S}_2[352,464) \\ +\small\;\mathcal{S}_3[240,352) +\end{matrix} +\right. +\end{array} +\begin{matrix} +\quad\Large\Vert\quad \\ +\small\vphantom{a} \\ +\small\vphantom{a} \\ +\small\vphantom{a} \\ +\small\vphantom{a} +\end{matrix} +\begin{array}{l} +\{0\}^{112} \\ +\,\left\vert +\begin{matrix} +\small\vphantom{a} \\ +\small\;\mathcal{S}_1[576,688) \\ +\small\;\mathcal{S}_2[464,576) \\ +\small\;\mathcal{S}_3[352,464) +\end{matrix} +\right. +\end{array} +\begin{matrix} +\quad\Large\Vert\quad \\ +\small\vphantom{a} \\ +\small\vphantom{a} \\ +\small\vphantom{a} \\ +\small\vphantom{a} +\end{matrix} +\begin{array}{l} +\{0\}^{112} \\ +\,\left\vert +\begin{matrix} +\small\vphantom{a} \\ +\small\vphantom{a} \\ +\small\;\mathcal{S}_2[576,688) \\ +\small\;\mathcal{S}_3[464,576) +\end{matrix} +\right. +\end{array} +\begin{matrix} +\quad\Large\Vert\quad \\ +\small\vphantom{a} \\ +\small\vphantom{a} \\ +\small\vphantom{a} \\ +\small\vphantom{a} +\end{matrix} +\begin{array}{l} +\{0\}^{112} \\ +\,\left\vert +\begin{matrix} +\small\vphantom{a} \\ +\small\vphantom{a} \\ +\small\vphantom{a} \\ +\small\;\mathcal{S}_3[576,688) +\end{matrix} +\right. +\end{array} +$$ + +There is no $\beta_4$, and of course, the filler after this last step does not make any sense anymore, but we are only interested in the first $240$ bytes: + +$$ +(\{0\}^{94}\,\Vert\,\{0\}^{2}\,\Vert\,\mathcal{id}_{\mathsf{SURB}}\,\Vert\,\{0\}^{128}) +$$ + +This is the end of the processing phase for the $\beta$ element, and the end of this document. \ No newline at end of file diff --git a/10 Notes/Sphinx Header Processing Infographic.md b/10 Notes/Sphinx Header Processing Infographic.md new file mode 100644 index 0000000..e3d94c9 --- /dev/null +++ b/10 Notes/Sphinx Header Processing Infographic.md @@ -0,0 +1,8 @@ +Related to: [[Sphinx Header Processing Example]]. + +Here is the Excalidraw drawing demonstrating the creation of the filler, the header, and the subsequent header processing. + +This is editable version (requires Exalidraw plugin for Obsidian). For a non editable shared version +that you can use in a browser, please visit: https://link.excalidraw.com/readonly/6y7DRQlUhkkBMZScEONS. + +![[Sphinx Header Processing Infographic 2026-05-11 02.50.17.excalidraw]] \ No newline at end of file diff --git a/10 Notes/Sphinx SURBs implementation in the libp2p MIX protocol.md b/10 Notes/Sphinx SURBs implementation in the libp2p MIX protocol.md new file mode 100644 index 0000000..97e35f0 --- /dev/null +++ b/10 Notes/Sphinx SURBs implementation in the libp2p MIX protocol.md @@ -0,0 +1,1745 @@ +The copy of this document can be found in [https://github.com/logos-storage/libp2p-storage-mix-transport/blob/master/docs/surb.md](https://github.com/logos-storage/libp2p-storage-mix-transport/blob/master/docs/surb.md). The content of this document should contain the most recent version. + +> This document belong to the series of [[Mix Implementation]] notes. + +This document is a deeper treatment of Single-Use Reply Blocks (SURBs) in the +vendored libp2p MIX implementation at +`nimbledeps/pkgs2/libp2p-*/libp2p/protocols/mix`. + +It maps the implementation to the MIX spec, with special attention to the newer +SURB section in pull request 307: + +- Published MIX LIP: https://lip.logos.co/ift-ts/raw/mix.html +- Pull request 307: https://github.com/logos-co/logos-lips/pull/307 +- Pull request snapshot, Section 8.7: https://github.com/logos-co/logos-lips/blob/bfd845f11c5ee4edc1d425c7c4a2b941285fd9a3/docs/ift-ts/raw/mix.md#87-single-use-reply-blocks + +The published LIP still contains older wording saying reply support is not +implemented yet. The pull request snapshot adds Section 8.7, which describes +SURB creation, use, reply processing, and reply recovery. This document compares +that newer SURB section with the current Nim implementation. + +## High-Level Model + +A SURB lets the destination side send a reply without learning the sender's +identity or return path. The sender precomputes a return-path Sphinx header, +embeds it in the forward message, and keeps the corresponding decryption +material locally. The exit node later uses the embedded SURB to package the +destination response as a MIX reply. + +The current implementation uses SURBs for request/response flows such as Ping: + +```text +sender + builds forward Sphinx packet + embeds N SURBs in the encrypted forward payload + stores SURB id -> reply credentials + incoming queue + | + v +mix path to exit + | + v +exit node + extracts SURBs + forwards request to destination protocol + reads destination response + sends the same response through each supplied SURB + | + v +return mix path(s) + | + v +sender + accepts first valid SURB reply + deletes credentials for all SURBs from that request + writes one recovered response into MixEntryConnection's incoming queue +``` + +The important operational point is that `numSurbs > 1` does not mean the +application receives multiple responses. In this implementation it means the +same response is sent over multiple independent return paths, and the first valid +reply wins. + +## Relevant Types and Constants + +The wire structures live mostly in `serialization.nim`. + +```nim +const + k* = 16 + r* = 5 + t* = 6 + AlphaSize* = 32 + BetaSize* = ((r * (t + 1)) + 1) * k + GammaSize* = 16 + HeaderSize* = AlphaSize + BetaSize + GammaSize + DelaySize* = 2 + AddrSize* = (t * k) - DelaySize + PacketSize* = 4608 + MessageSize* = PacketSize - HeaderSize - k + PayloadSize* = MessageSize + k + SurbSize* = HeaderSize + AddrSize + k + SurbLenSize* = 1 + SurbIdLen* = k +``` + +With the current parameters: + +- `HeaderSize = 624` +- `DelaySize = 2` +- `AddrSize = 94` +- `SurbSize = 734` +- `MessageSize = 3968` +- `PayloadSize = 3984` + +`t * k` is the combined per-hop routing block space for address plus delay: +`6 * 16 = 96` bytes. The implementation reserves `DelaySize = 2` bytes for the +encoded per-hop delay, leaving `AddrSize = 94` bytes for the serialized hop +address. + +That matches the pull request 307 Section 8.7.1 structure: + +```text +SURB = hop_0 || header || reply_key + = 94 || 624 || 16 + = 734 bytes +``` + +The implementation type is: + +```nim +type Hop* = object + MultiAddress: seq[byte] + +type + Secret* = seq[seq[byte]] + Key* = seq[byte] + SURBIdentifier* = array[SurbIdLen, byte] + + SURB* = object + hop*: Hop + header*: Header + key*: Key + secret*: Opt[Secret] +``` + +`Hop` is the fixed-size routing address container used both for normal next-hop +routing and for `hop_0` in a SURB. Its serialized form is always `AddrSize` +bytes: + +```nim +proc serialize*(hop: Hop): seq[byte] = + if hop.MultiAddress.len == 0: + return newSeq[byte](AddrSize) + + doAssert len(hop.MultiAddress) == AddrSize + return hop.MultiAddress +``` + +An empty `Hop()` serializes as 94 zero bytes. The implementation uses that in +SURB construction for the final return-path routing block: zero address plus +zero delay means "this is not a normal forward destination"; the nonzero SURB +identifier placed after that block marks it as a reply. + +Field mapping: + +- `hop`: the spec term `hop_0`, the first hop on the return path. +- `header`: the spec tuple `(alpha_0, beta_0, gamma_0)`, the precomputed + Sphinx header. +- `key`: the spec term `k_tilde`, the reply key. +- `secret`: local-only per-hop shared secrets `s_0 ... s_{L-1}`. This should + not be distributed with the SURB. + +The serialized SURB embedded into the forward message deliberately omits +`secret`: + +```nim +let surbBytes = + surbs.mapIt(it.hop.serialize() & it.header.serialize() & it.key).concat() +``` + +## Where the Reply Queue Fits + +The reply queue is not part of the Sphinx/SURB spec. It is an implementation +adapter that lets a `MixEntryConnection` look like a normal libp2p `Connection` +to client-side protocol code. + +`MixEntryConnection` has: + +```nim +type MixEntryConnection* = ref object of Connection + incoming: AsyncQueue[seq[byte]] + incomingFut: Future[void] + replyReceivedFut: Future[void] + cached: seq[byte] +``` + +When `expectReply = true`, construction creates the queue and starts one +background future: + +```nim +instance.incoming = newAsyncQueue[seq[byte]]() +instance.replyReceivedFut = newFuture[void]() + +let checkForIncoming = proc(): Future[void] {.async.} = + instance.cached = await instance.incoming.get() + instance.replyReceivedFut.complete() + +instance.incomingFut = checkForIncoming() +``` + +When client code later reads from the connection, `readOnce` waits for +`replyReceivedFut` and then serves bytes from `cached`: + +```nim +if s.cached.len == 0: + await s.replyReceivedFut + +let toRead = min(nbytes, s.cached.len) +copyMem(pbytes, addr s.cached[0], toRead) +s.cached = s.cached[toRead ..^ 1] +``` + +The queue is populated by the sender-side `Reply` branch in +`handleMixMessages`, after the returned SURB packet has been recovered: + +```nim +await connCred.incoming.put(deserialized.message) +``` + +So the reply queue is the bridge between: + +- MIX/SURB packet processing, which eventually recovers `seq[byte]`; and +- libp2p protocol code, which expects to read those bytes from a `Connection`. + +Current limitation: this is shaped for a single request/response. One +`replyReceivedFut` is completed once, and the first successful reply fills +`cached`. It is not a general multi-response stream abstraction. + +## Sender-Side SURB Creation + +SURB creation begins during a normal MIX send. `MixEntryConnection.write` calls: + +```nim +let sendRes = await srcMix.anonymizeLocalProtocolSend( + instance.incoming, msg, codec, dest, numSurbs +) +``` + +Inside `anonymizeLocalProtocolSend`, after the forward path has selected an exit +node, the message is augmented with SURBs: + +```nim +let msgWithSurbs = mixProto.prepareMsgWithSurbs( + incoming, msg, numSurbs, destination.peerId, exitPeerId +) +``` + +`prepareMsgWithSurbs` calls `buildSurbs`, then serializes them before the +application message: + +```nim +proc prepareMsgWithSurbs( + mixProto: MixProtocol, + incoming: AsyncQueue[seq[byte]], + msg: seq[byte], + numSurbs: uint8 = 0, + destPeerId: PeerId, + exitPeerId: PeerId, +): Result[seq[byte], string] = + let surbs = + mixProto.buildSurbs(incoming, numSurbs, destPeerId, exitPeerId).valueOr: + return err(error) + + serializeMessageWithSURBs(msg, surbs) +``` + +### `buildSurbs`: Outer Loop and Local State + +`buildSurbs` is the outer loop. It creates `numSurbs` independent SURBs for this +one outgoing request. It is also where `buildSurb` is called: + +```nim +proc buildSurbs( + mixProto: MixProtocol, + incoming: AsyncQueue[seq[byte]], + numSurbs: uint8, + destPeerId: PeerId, + exitPeerId: PeerId, +): Result[seq[SURB], string] = + var response: seq[SURB] + var igroup = SURBIdentifierGroup(members: initHashSet[SURBIdentifier]()) + + for _ in 0.uint8 ..< numSurbs: + var id: SURBIdentifier + hmacDrbgGenerate(mixProto.rng[], id) + + let surb = ?mixProto.buildSurb(id, destPeerId, exitPeerId) + + igroup.members.incl(id) + mixProto.connCreds[id] = ConnCreds( + igroup: igroup, + surbSecret: surb.secret.get(), + surbKey: surb.key, + incoming: incoming, + ) + + response.add(surb) + + return ok(response) +``` + +In that loop: + +- `id` is the random SURB identifier later embedded in the return-path header. +- `buildSurb(id, destPeerId, exitPeerId)` builds one complete return-path SURB. +- `connCreds[id]` stores the local-only recovery material for that SURB. +- `igroup` groups all SURB identifiers created for this request, so the first + valid reply can consume the whole group. +- `response` is the list of distributable SURBs that will be serialized into the + forward request payload. + +The serialized layout is: + +```text +num_surbs: 1 byte +SURB[0]: hop || header || key +SURB[1]: hop || header || key +... +application_message +``` + +This means even messages with no replies still carry a one-byte SURB count: + +```text +0x00 || application_message +``` + +### Identifier and Reply Key + +For each SURB, `buildSurbs` samples a distinct identifier before calling +`buildSurb`: + +```nim +var id: SURBIdentifier +hmacDrbgGenerate(mixProto.rng[], id) +let surb = ?mixProto.buildSurb(id, destPeerId, exitPeerId) +``` + +That `id` is embedded into the terminal routing block of the SURB return path. +When a reply returns, the original sender extracts this identifier and uses it +to look up the stored recovery credentials in `connCreds`. + +`createSURB`, which is called from inside `buildSurb`, samples the reply key: + +```nim +var key = newSeqUninit[byte](k) +rng[].generate(key) +``` + +This maps to pull request 307 Section 8.7.2 Step 2: sample a unique SURB +identifier `id` and a reply key `k_tilde`. + +There is no explicit collision check against existing `connCreds`; uniqueness is +probabilistic from the 16-byte random identifier. + +### `buildSurb`: Return Path Selection + +`buildSurb` constructs one return path per SURB and returns the distributable +SURB object: + +```nim +method buildSurb*( + mixProto: MixProtocol, + id: SURBIdentifier, + destPeerId: PeerId, + exitPeerId: PeerId +): Result[SURB, string] +``` + +Inside `buildSurb`, the implementation accumulates three aligned arrays: + +```nim +var + publicKeys: seq[FieldElement] = @[] + hops: seq[Hop] = @[] + delay: seq[seq[byte]] = @[] +``` + +Those arrays are then passed to `createSURB(publicKeys, delay, hops, id)`, which +constructs the Sphinx return-path header and reply key. + +It excludes the forward-path exit and destination from the random part of the +return path: + +```nim +var pubNodeInfoKeys = + mixProto.nodePool.peerIds().filterIt(it != exitPeerId and it != destPeerId) +``` + +Then it selects `PathLength` hops. The loop index `i` is the return-path hop +index. With the current `PathLength = 3`, `i = 0` and `i = 1` are random +intermediate return hops, while `i = 2` is the final hop. For all but the last +hop, it picks random public mix nodes from the filtered pool. This branch does +not run for the final hop: + +```nim +if i < PathLength - 1: + let randomIndexPosition = cryptoRandomInt(mixProto.rng, availableIndices.len).valueOr: + return err("failed to generate random num: " & error) + let selectedIndex = availableIndices[randomIndexPosition] + let randPeerId = pubNodeInfoKeys[selectedIndex] + availableIndices.del(randomIndexPosition) + + let mixPubInfo = mixProto.nodePool.get(randPeerId) + ( + mixPubInfo.peerId, + mixPubInfo.multiAddr, + mixPubInfo.mixPubKey, + mixProto.delayStrategy.generateForEntry(), + ) +``` + +There are two index layers here. `pubNodeInfoKeys` stores the candidate peer IDs. +`availableIndices` stores the indices in `pubNodeInfoKeys` that have not yet +been selected for this return path. `cryptoRandomInt` chooses a random position +inside `availableIndices`; the value at that position is then used as the index +into `pubNodeInfoKeys`. + +For example: + +```text +pubNodeInfoKeys = [peerA, peerB, peerC, peerD] +availableIndices = [0, 1, 2, 3] + +randomIndexPosition = 2 +selectedIndex = availableIndices[2] = 2 +randPeerId = pubNodeInfoKeys[2] = peerC +``` + +After selecting `peerC`, the code removes that entry from `availableIndices`: + +```nim +availableIndices.del(randomIndexPosition) +``` + +That prevents the same mix node from being selected twice in one SURB return +path. The tuple returned for a selected hop contains the libp2p peer ID, +dialable multiaddress, MIX public key used for Sphinx header construction, and +the encoded delay value for that hop. + +The last hop is the original sender's own mix node: + +```nim +else: + ( + mixProto.mixNodeInfo.peerId, + mixProto.mixNodeInfo.multiAddr, + mixProto.mixNodeInfo.mixPubKey, + 0.uint16, + ) +``` + +This `else` branch is reached only when `i == PathLength - 1`. With +`PathLength = 3`, that means `i == 2`. So the last return-path hop is not random: +it is forcibly set to `mixProto.mixNodeInfo`, the local mix node that originally +created the SURB. In this example: + +```text +i = 0 random mix node +i = 1 random mix node +i = 2 original sender's own mix node +``` + +The phrase "original sender" here means the node that created the SURB and sent +the original forward request. It is also the final recipient of the SURB reply, +because only that node has the stored `surbKey` and `surbSecret` needed to +recover the reply payload. + +This maps to pull request 307 Section 8.7.2 Step 1: the initiating node selects +a return path with itself as the final hop and computes ephemeral secrets for +that path. + +### Header Construction + +The cryptographic construction is in `sphinx.nim`. The inputs collected during +return-path selection are: + +- `publicKeys`: the MIX public keys for the selected return-path hops, in path + order. These are not libp2p identity keys. They are Curve25519/Sphinx keys + used to derive one shared secret per hop. +- `hops`: the serialized routing addresses for the same return-path hops. +- `delay`: the encoded delay value for each hop. +- `id`: the SURB identifier that the sender will later use to find the stored + reply recovery keys. + +`buildSurb` fills `publicKeys`, `hops`, and `delay` together while iterating +over the selected return-path nodes. The relevant section is: + +```nim +for i in 0 ..< PathLength: + let (peerId, multiAddr, mixPubKey, delayMillisec) = + if i < PathLength - 1: + let randomIndexPosition = cryptoRandomInt(mixProto.rng, availableIndices.len).valueOr: + return err("failed to generate random num: " & error) + let selectedIndex = availableIndices[randomIndexPosition] + let randPeerId = pubNodeInfoKeys[selectedIndex] + availableIndices.del(randomIndexPosition) + let mixPubInfo = mixProto.nodePool.get(randPeerId).valueOr: + return err("could not get mix pub info for peer: " & $randPeerId) + ( + mixPubInfo.peerId, + mixPubInfo.multiAddr, + mixPubInfo.mixPubKey, + mixProto.delayStrategy.generateForEntry(), + ) + else: + ( + mixProto.mixNodeInfo.peerId, + mixProto.mixNodeInfo.multiAddr, + mixProto.mixNodeInfo.mixPubKey, + 0.uint16, + ) + + publicKeys.add(mixPubKey) + + let multiAddrBytes = multiAddrToBytes(peerId, multiAddr).valueOr: + return err("failed to convert multiaddress to bytes: " & error) + + hops.add(Hop.init(multiAddrBytes)) + delay.add(@(delayMillisec.uint16.toBytesBE())) +``` + +Each line feeds a different part of Sphinx construction: + +- `publicKeys.add(mixPubKey)` stores the hop's MIX public key. Later, + `computeAlpha(publicKeys)` uses these public keys to derive one shared secret + per return-path hop. +- `multiAddrToBytes(peerId, multiAddr)` converts the hop's libp2p identity and + dialable address into the fixed 94-byte `Hop` address format. Later, + `computeBetaGamma` encrypts these hop addresses into the routing header. +- `delay.add(@(delayMillisec.uint16.toBytesBE()))` stores the hop delay as two + big-endian bytes, matching `DelaySize = 2`. Later, each return-path hop + decrypts its own delay value from Beta and applies it before forwarding. + +The ordering matters. `publicKeys[i]`, `hops[i]`, and `delay[i]` must describe +the same return-path hop at index `i`; otherwise the encrypted routing header +would pair the wrong key, address, or delay with a hop. + +At the end of `buildSurb`, those aligned arrays are handed to `createSURB`: + +```nim +return createSURB(publicKeys, delay, hops, id) +``` + +`createSURB` computes the return-path `alpha_0`, per-hop secrets, `beta_0`, and +`gamma_0`, samples the reply key, and returns the final SURB object. The relevant +part is: + +```nim +proc createSURB*( + publicKeys: openArray[FieldElement], + delay: openArray[seq[byte]], + hops: openArray[Hop], + id: SURBIdentifier, + rng: ref HmacDrbgContext = newRng(), +): Result[SURB, string] = + if id == default(SURBIdentifier): + return err("id should be initialized") + + let (alpha_0, s) = computeAlpha(publicKeys).valueOr: + return err("Error in alpha generation: " & error) + + let (beta_0, gamma_0) = computeBetaGamma(s, hops, delay, Hop(), id).valueOr: + return err("Error in beta and gamma generation: " & error) + + var key = newSeqUninit[byte](k) + rng[].generate(key) + + return ok( + SURB( + hop: hops[0], + header: Header.init(alpha_0, beta_0, gamma_0), + secret: Opt.some(s), + key: key, + ) + ) +``` + +This is where the distributable SURB fields are assembled: + +- `hop: hops[0]` is `hop_0`, the first return-path hop the exit should send to. +- `header: Header.init(alpha_0, beta_0, gamma_0)` is the precomputed Sphinx + header for the return path. +- `key` is the reply key `k_tilde`, distributed with the SURB so the exit can + encrypt the reply payload. +- `secret: Opt.some(s)` is local recovery material. It is stored in + `connCreds` by `buildSurbs`, but is not serialized into the SURB sent to the + exit. + +#### Alpha and Per-Hop Secrets + +`computeAlpha(publicKeys)` creates the initial Sphinx ephemeral public value and +the shared secret for each return-path hop: + +```nim +var + s: seq[seq[byte]] = newSeq[seq[byte]](publicKeys.len) + alpha_0: seq[byte] + alpha: FieldElement + secret: FieldElement + blinders: seq[FieldElement] = @[] + +let x = generateRandomFieldElement() +blinders.add(x) + +for i in 0 ..< publicKeys.len: + if i == 0: + alpha = multiplyBasePointWithScalars([blinders[i]]) + alpha_0 = fieldElementToBytes(alpha) + else: + alpha = multiplyPointWithScalars(alpha, [blinders[i]]) + + secret = multiplyPointWithScalars(publicKeys[i], blinders) + + let blinder = bytesToFieldElement( + sha256_hash(fieldElementToBytes(alpha) & fieldElementToBytes(secret)) + ) + + blinders.add(blinder) + s[i] = fieldElementToBytes(secret) +``` + +Conceptually: + +- The sender samples an ephemeral scalar `x`. +- `blinders` is the blinding chain. It starts with `x`; after each hop, the code + derives a new blinder from that hop's current `alpha` and shared secret. +- `alpha_0 = x * G` is the initial public value placed in the SURB header. + `multiplyBasePointWithScalars([x])` computes this by multiplying the + Curve25519 base point `G` by the scalar `x`. In the helper implementation, + this is done by calling `public(x)`, because a Curve25519 public key is the + base point multiplied by the private scalar. +- For every return-path hop, the sender derives a shared secret from that hop's + MIX public key and the current blinding chain. +- The next `alpha` value is produced by multiplying the previous `alpha` by the + next blinder. This lets every hop see a fresh-looking `alpha` while still + allowing the sender to precompute all per-hop secrets. +- Each hop will later derive the same secret from its private key and the `alpha` + value it receives while processing the Sphinx packet. +- The secrets `s[0] ... s[L-1]` are kept locally in `surb.secret` so the sender + can recover the reply when the return packet reaches it. + +#### Beta and Gamma + +The SURB section of the spec indexes the return path in the direction the reply +will travel: + +```text +i = 0 first return-path hop, the node the exit sends to +i = sLen - 1 terminal return-path hop, the original sender +``` + +This matches pull request 307 Section 8.7.2, where `hop_0` is the first hop on +the return path and the initiating node is the final hop. + +The implementation uses the same index convention in its arrays: + +```text +hops[0], publicKeys[0], delay[0], s[0] -> hop_0 +hops[1], publicKeys[1], delay[1], s[1] -> hop_1 +hops[sLen - 1], publicKeys[sLen - 1], delay[sLen - 1] -> hop_{L-1} +``` + +So `sLen - 1` does not mean `hop_0`; it means `hop_{L-1}`. In the SURB return +path constructed above, `hop_{L-1}` is the original sender's own mix node, +because `buildSurb` explicitly put `mixProto.mixNodeInfo` in the final hop slot. + +Equivalently, for `PathLength = 3`: + +```text +s[0] -> hop_0, first return hop +s[1] -> hop_1, second return hop +s[2] -> hop_2, terminal return hop/original sender +``` + +The countdown loop below changes construction order only. It does not change +which hop each `s[i]` belongs to. + +There is only one `computeBetaGamma` routine. This is its full signature: + +```nim +proc computeBetaGamma( + s: seq[seq[byte]], + hops: openArray[Hop], + delay: openArray[seq[byte]], + destHop: Hop, + id: SURBIdentifier, +): Result[tuple[beta: seq[byte], gamma: seq[byte]], string] = +``` + +The forward path and the SURB return path both call this same function. The +difference is only in the argument values passed to `hops`, `destHop`, and `id`. + +The implementation then iterates over the path indices from high to low: + +```nim +proc computeBetaGamma( + s: seq[seq[byte]], + hops: openArray[Hop], + delay: openArray[seq[byte]], + destHop: Hop, + id: SURBIdentifier, +): Result[tuple[beta: seq[byte], gamma: seq[byte]], string] = + let sLen = s.len + var + beta: seq[byte] + gamma: seq[byte] + + let filler = computeFillerStrings(s).valueOr: + return err("Error in filler generation: " & error) + + for i in countdown(sLen - 1, 0): + let + beta_aes_key = deriveKeyMaterial("aes_key", s[i]).kdf() + mac_key = deriveKeyMaterial("mac_key", s[i]).kdf() + beta_iv = deriveKeyMaterial("iv", s[i]).kdf() + + if i == sLen - 1: + let destBytes = destHop.serialize() + let destPadding = destBytes & delay[i] & @id & newSeq[byte](PaddingLength) + let aes = aes_ctr(beta_aes_key, beta_iv, destPadding) + beta = aes & filler + else: + let betaPrefix = + beta[0 .. (((r * (t + 1)) - t) * k) - 1] + + let routingInfo = RoutingInfo.init( + hops[i + 1], + delay[i], + gamma, + betaPrefix, + ) + + let serializedRoutingInfo = routingInfo.serialize() + beta = aes_ctr(beta_aes_key, beta_iv, serializedRoutingInfo) + + gamma = hmac(mac_key, beta).toSeq() + + return ok((beta: beta, gamma: gamma)) +``` + +The same `computeBetaGamma` routine is used for both normal forward packets and +SURB return-path headers. The difference is entirely in the arguments. + +For a normal forward message, `wrapInSphinxPacket` calls: + +```nim +let (beta_0, gamma_0) = computeBetaGamma( + s, + hop, + delay, + destHop, + default(SURBIdentifier), +) +``` + +For a SURB, `createSURB` calls: + +```nim +let (beta_0, gamma_0) = computeBetaGamma( + s, + hops, + delay, + Hop(), + id, +) +``` + +The argument differences are: + +| Argument | Forward message | SURB return path | +| --------- | ------------------------------------------------------------------------------------------------------------- | ---------------------------------------------------------------------------------------------------------------------------------------- | +| `hops` | Forward mix path: first mix hop, intermediate hops, final exit hop. | Return mix path: first return hop, intermediate return hops, original sender as final hop. | +| `destHop` | Real destination address, encoded as a `Hop`. The forward-path exit uses it to dial the destination protocol. | Empty `Hop()`, which serializes as zero address bytes. This marks that the terminal return hop is not forwarding to another destination. | +| `id` | `default(SURBIdentifier)`, all zero bytes. | Random nonzero SURB identifier generated by `buildSurbs`. The original sender uses it to find `connCreds`. | + +For `PathLength = 3`, the final routing block produced by the same +`if i == sLen - 1` branch therefore differs like this: + +```text +Forward message final block: + destHop = destination address + delay = 0 + id = 0^16 + meaning = normal exit; forward plaintext to destination + +SURB return final block: + destHop = zero Hop() + delay = 0 + id = random SURB id + meaning = reply arrived at original sender; recover using connCreds[id] +``` + +So there is no separate "forward Beta" and "SURB Beta" algorithm. There is one +Beta/Gamma algorithm with two terminal-block encodings. + +`beta` and `gamma` are mutable byte sequences. During the countdown loop, they +always hold the header state for the hop that was just constructed. For a +3-hop path, after the first iteration they hold `beta_2/gamma_2`; after the +second iteration they hold `beta_1/gamma_1`; after the final iteration they hold +`beta_0/gamma_0`, which is what goes into the SURB header. + +#### Filler + +`filler` is precomputed before the Beta/Gamma countdown loop: + +```nim +proc computeFillerStrings(s: seq[seq[byte]]): Result[seq[byte], string] = + var filler: seq[byte] = @[] + + for i in 1 ..< s.len: + let + aes_key = deriveKeyMaterial("aes_key", s[i - 1]).kdf() + iv = deriveKeyMaterial("iv", s[i - 1]).kdf() + + let + fillerLength = (t + 1) * k + zeroPadding = newSeq[byte](fillerLength) + + filler = aes_ctr_start_index( + aes_key, + iv, + filler & zeroPadding, + (((t + 1) * (r - i)) + t + 2) * k, + ) + + return ok(filler) +``` + +The hard part is why this exists. Each hop decrypts and shifts the routing +header state as the packet moves forward. Without filler, the end of Beta would +gradually become distinguishable padding, and a hop could infer information +about its position in the path or the remaining path length. Filler precomputes +the bytes that must be appended at the tail so that, after each hop's Sphinx +transformation, the Beta field still has the right fixed-size shape and does not +reveal where the packet is in the path. + +The call to `aes_ctr_start_index` is what makes the filler line up with the tail +of the conceptual full Beta stream: + +```nim +filler = aes_ctr_start_index( + aes_key, + iv, + filler & zeroPadding, + (((t + 1) * (r - i)) + t + 2) * k, +) +``` + +`filler & zeroPadding` extends the previous filler by one routing block: + +```text +(t + 1) * k = (6 + 1) * 16 = 112 bytes +``` + +`aes_ctr_start_index` encrypts that data as if it started at byte offset +`startIndex` in a larger AES-CTR stream. This matters because filler bytes live +at the tail of Beta, not at byte offset 0. AES-CTR keystream bytes depend on +position, so filler must be encrypted with the keystream positions where those +bytes will sit inside the full Beta field. + +For the current constants, the filler loop runs twice for `PathLength = 3`: + +```text +i = 1: + startIndex = (((7) * (5 - 1)) + 8) * 16 + = 576 + input length = 112 bytes + +i = 2: + startIndex = (((7) * (5 - 2)) + 8) * 16 + = 464 + input length = 224 bytes +``` + +So the final filler is 224 bytes. Conceptually, it is pre-encrypted tail data +that will remain well-formed after earlier hops append zero padding and decrypt +their Beta layers. + +In this implementation, filler is only appended when constructing the terminal +routing block: + +```nim +if i == sLen - 1: + ... + beta = aes & filler +``` + +That may look surprising, but remember the countdown loop builds nested header +state. The terminal block is built first and becomes the innermost state carried +forward into `beta_{L-2}`, `beta_{L-3}`, and eventually `beta_0`. Appending +filler there prepares the tail bytes that will be needed after later hops peel +their layers. + +The loop in `computeFillerStrings` starts at `i = 1` because no filler is needed +before the first hop has processed anything. The expression `s[i - 1]` therefore +starts with `s[0]`, which is the secret for `hop_0`, the first return hop. It +does not start with the original sender. The filler code uses each earlier +travel-order hop's `aes_key`/`iv` to predict how zero padding at the tail will +transform as those earlier layers are processed. + +That is the end of the filler-specific part. The next paragraphs return to the +general Beta/Gamma construction flow. + +This countdown is construction order, not path-travel order. It is needed +because each earlier hop's routing block contains encrypted information for the +next hop. For a 3-hop return path: + +```text +hop 0 -> hop 1 -> hop 2/original sender +``` + +the header has to be prepared in this dependency order: + +```text +1. build beta_2/gamma_2 for the original sender +2. build beta_1/gamma_1, embedding gamma_2 and part of beta_2 +3. build beta_0/gamma_0, embedding gamma_1 and part of beta_1 +``` + +The exit receives only `beta_0/gamma_0` in the SURB header. Hop 0 decrypts its +routing block and learns how to forward to hop 1, including the `beta_1/gamma_1` +state that hop 1 will verify next. Hop 1 does the same for hop 2. That is the +reason the construction loop counts down from the original sender back to the +first return hop. + +#### Digression: Why Build `beta_2` Before `beta_0`? + +For both normal forward messages and SURB return messages, the path is indexed +in travel order: + +```text +hop_0 -> hop_1 -> hop_2 +``` + +For a normal forward message: + +```text +sender -> hop_0 -> hop_1 -> hop_2/exit -> destination +``` + +For a SURB reply: + +```text +exit -> hop_0 -> hop_1 -> hop_2/original sender +``` + +In both cases, the packet is processed in travel order: + +```text +hop_0 processes beta_0/gamma_0 +hop_1 processes beta_1/gamma_1 +hop_2 processes beta_2/gamma_2 +``` + +But the header must be constructed in the opposite order because each earlier +hop's routing block embeds the next hop's header state: + +```text +beta_0 contains next-hop info for hop_1 plus beta_1/gamma_1 +beta_1 contains next-hop info for hop_2 plus beta_2/gamma_2 +beta_2 contains the final instruction +``` + +So `beta_0` cannot be built until `beta_1/gamma_1` exists, and `beta_1` cannot +be built until `beta_2/gamma_2` exists. The construction dependency is: + +```text +1. build beta_2/gamma_2 +2. use those to build beta_1/gamma_1 +3. use those to build beta_0/gamma_0 +``` + +The packet/SURB then carries `beta_0/gamma_0` as the starting header state. At +runtime, each hop decrypts its own layer and reveals the next header state: + +```text +construction: beta_2 -> beta_1 -> beta_0 +processing: beta_0 -> beta_1 -> beta_2 +``` + +For SURBs, the final instruction in `beta_2` is special: it contains zero +address/delay plus the SURB identifier. For normal forward messages, the final +instruction contains the destination address. + +Returning to the SURB header construction code, each iteration of +`computeBetaGamma` derives the keys needed to encrypt and authenticate one hop's +routing block. + +For each hop secret `s[i]`, the code derives: + +- `beta_aes_key`: encrypts the routing block for that hop. +- `beta_iv`: IV for that routing-block encryption. +- `mac_key`: authenticates the resulting `beta`. + +For hops where `i < sLen - 1`, meaning every return-path hop before the original +sender, the routing block contains the next hop's address, this hop's delay, the +next hop's `gamma`, and the next encrypted `beta` prefix: + +```nim +let betaPrefix = + beta[0 .. (((r * (t + 1)) - t) * k) - 1] + +let routingInfo = RoutingInfo.init( + hops[i + 1], + delay[i], + gamma, + betaPrefix, +) + +let serializedRoutingInfo = routingInfo.serialize() +beta = aes_ctr(beta_aes_key, beta_iv, serializedRoutingInfo) +``` + +That is the onion-routing part of the header: when hop `i` processes the packet, +it can decrypt only its own routing block and learn only the next hop, delay, +next MAC, and next encrypted header state. + +The `betaPrefix` slice is the part of the already-built next-hop `beta` that +fits into a `RoutingInfo` block. The formula is: + +```text +(((r * (t + 1)) - t) * k) +``` + +With the current constants: + +```text +r = 5 +t = 6 +k = 16 + +((5 * (6 + 1)) - 6) * 16 += ((5 * 7) - 6) * 16 += (35 - 6) * 16 += 29 * 16 += 464 bytes +``` + +That matches the `RoutingInfo.serialize()` layout: + +```text +Addr = 94 bytes +Delay = 2 bytes +Gamma = 16 bytes +Beta = 464 bytes +Total = 576 bytes +``` + +`RoutingInfo.serialize()` must produce exactly 576 bytes because the Sphinx +header format has a fixed-size Beta field. Each non-terminal hop encrypts one +serialized `RoutingInfo` block to produce the next `beta` value. Since address, +delay, and gamma consume 112 bytes, only 464 bytes are available for carrying +forward the next encrypted Beta state. The slice: + +```nim +beta[0 .. 463] +``` + +keeps exactly that prefix. + +There is an important distinction here: + +```text +BetaSize = ((r * (t + 1)) + 1) * k = 576 bytes +betaPrefix size = ((r * (t + 1)) - t) * k = 464 bytes +``` + +So `(((r * (t + 1)) - t) * k)` is not the full Beta size in this +implementation. The full `beta` value is 576 bytes. The 464-byte slice is the +amount of the already-built next-hop Beta that can be embedded inside the +previous hop's `RoutingInfo`, because `RoutingInfo` must also include 112 bytes +of fresh routing data: + +```text +next hop address 94 bytes +delay 2 bytes +next gamma 16 bytes +--------------------------- +fresh routing 112 bytes + +576-byte RoutingInfo - 112 fresh bytes = 464 bytes for betaPrefix +``` + +During packet processing, the receiving hop appends `(t + 1) * k = 112` zero +bytes before decrypting Beta: + +```nim +let zeroPadding = newSeq[byte]((t + 1) * k) +let B = aes_ctr(beta_aes_key, beta_iv, beta & zeroPadding) +``` + +That is how the hop recovers a full routing block containing 112 bytes of fresh +routing data plus a restored 576-byte next-hop Beta state. The construction side +stores only a 464-byte prefix because the processing side later supplies the +extra 112 zero bytes before decryption. + +For `i == sLen - 1`, meaning the terminal return-path hop and original sender, +the routing block is special: + +The call passes `Hop()` as `destHop` and a non-default `id`. In +`computeBetaGamma`, the final routing block is built as: + +```nim +let destBytes = destHop.serialize() +let destPadding = destBytes & delay[i] & @id & newSeq[byte](PaddingLength) +let aes = aes_ctr(beta_aes_key, beta_iv, destPadding) +beta = aes & filler +``` + +For a SURB, `destHop.serialize()` is all zeros and the final delay is zero. +That produces the pull request 307 Section 8.7.2 Step 3 shape: + +```text +zero address/delay || SURB id || zero padding +``` + +This is how the original sender, when it becomes the final return-path hop, can +distinguish a SURB reply from a normal forward exit message. + +After each final or non-final `beta` calculation, `gamma` is computed over that +`beta`: + +```nim +gamma = hmac(mac_key, beta).toSeq() +``` + +The first values produced by the backwards loop, `beta_0` and `gamma_0`, are the +values placed in the distributed SURB header. Later return-path hops derive and +verify the next `gamma` values as they process the packet. + +#### Hop-by-Hop Beta Example + +For a concrete 3-hop SURB return path, the countdown loop behaves like this: + +```text +return travel path: hop_0 -> hop_1 -> hop_2/original sender +construction loop: i = 2, then i = 1, then i = 0 +``` + +At `i = 2`, the code builds the terminal block for the original sender: + +```text +destPadding = + zero Hop() address 94 bytes + zero delay 2 bytes + SURB id 16 bytes + zero padding 240 bytes # PaddingLength + +AES-CTR(key_2, iv_2, destPadding) = 352 bytes +filler = 224 bytes +beta_2 = 576 bytes +gamma_2 = HMAC(mac_key_2, beta_2) +``` + +Here `PaddingLength` is: + +```text +(((t + 1) * (r - PathLength)) + 1) * k += (((6 + 1) * (5 - 3)) + 1) * 16 += 240 bytes +``` + +At this point, the mutable `beta`/`gamma` variables hold `beta_2/gamma_2`. + +At `i = 1`, the code builds routing instructions for `hop_1`. When `hop_1` +later processes the packet, it needs to learn how to forward to `hop_2` and what +header state `hop_2` should verify. So `RoutingInfo.init` is effectively: + +```nim +let routingInfo = RoutingInfo.init( + hops[2], # address of hop_2/original sender + delay[1], # delay hop_1 should apply before forwarding + gamma_2, # MAC that hop_2 should verify + beta_2[0 .. 463], +) +``` + +`RoutingInfo.init` is just a structured container: + +```nim +RoutingInfo( + Addr: hops[2], + Delay: delay[1], + Gamma: gamma_2, + Beta: beta_2[0 .. 463], +) +``` + +Then serialization lays those fields out in a fixed 576-byte block: + +```text +hops[2] 94 bytes +delay[1] 2 bytes +gamma_2 16 bytes +beta_2 prefix 464 bytes +------------------------- +serialized 576 bytes +``` + +That block is encrypted to become `beta_1`, and then `gamma_1` is computed: + +```text +beta_1 = AES-CTR(key_1, iv_1, serialized RoutingInfo for hop_1) +gamma_1 = HMAC(mac_key_1, beta_1) +``` + +At `i = 0`, the same pattern repeats for `hop_0`: + +```nim +let routingInfo = RoutingInfo.init( + hops[1], # address of hop_1 + delay[0], # delay hop_0 should apply before forwarding + gamma_1, # MAC that hop_1 should verify + beta_1[0 .. 463], +) +``` + +After encryption: + +```text +beta_0 = AES-CTR(key_0, iv_0, serialized RoutingInfo for hop_0) +gamma_0 = HMAC(mac_key_0, beta_0) +``` + +The SURB distributed to the exit contains `hop_0` plus `alpha_0/beta_0/gamma_0`. +It does not contain `beta_1` or `beta_2` as separate fields. Those later header +states are nested inside `beta_0` through the encrypted `RoutingInfo` blocks. + +#### Hop-by-Hop Processing Example + +The processing side reverses the construction dependency. A return packet starts +at `hop_0` with: + +```text +Header(alpha_0, beta_0, gamma_0) +Payload(delta_0) +``` + +At every non-terminal hop, `processSphinxPacket` verifies the current Gamma, +decrypts Beta with 112 bytes of appended zero padding, transforms Delta, and +creates the header for the next hop: + +```nim +if hmac(mac_key, beta).toSeq() != gamma: + return InvalidMAC + +let delta_prime = aes_ctr(delta_aes_key, delta_iv, payload) + +let zeroPadding = newSeq[byte]((t + 1) * k) +let B = aes_ctr(beta_aes_key, beta_iv, beta & zeroPadding) + +let routingInfo = RoutingInfo.deserialize(B) +let (address, delay, gamma_prime, beta_prime) = + routingInfo.getRoutingInfo() + +let alpha_prime = multiplyPointWithScalars(alphaFE, [blinder]) + +let sphinxPkt = SphinxPacket.init( + Header.init(fieldElementToBytes(alpha_prime), beta_prime, gamma_prime), + delta_prime, +) +``` + +For the same 3-hop return path, `hop_0` receives `beta_0/gamma_0`: + +```text +input at hop_0: + beta_0 576 bytes + gamma_0 16 bytes + +processing: + B_0 = AES-CTR(key_0, iv_0, beta_0 || 112 zero bytes) +``` + +`B_0` decrypts to the routing block that was built for `hop_0`: + +```text +B_0 = + hops[1] 94 bytes # next hop address + delay[0] 2 bytes # delay for hop_0 + gamma_1 16 bytes # MAC for hop_1 to verify + beta_1 576 bytes # restored next-hop Beta +``` + +`RoutingInfo.deserialize(B_0)` returns: + +```text +address = hops[1] +delay = delay[0] +gamma_prime = gamma_1 +beta_prime = beta_1 +``` + +Then `hop_0` forwards: + +```text +Header(alpha_1, beta_1, gamma_1) +Payload(delta_1) +``` + +`hop_1` repeats the same process: + +```text +B_1 = AES-CTR(key_1, iv_1, beta_1 || 112 zero bytes) + +B_1 = + hops[2] 94 bytes + delay[1] 2 bytes + gamma_2 16 bytes + beta_2 576 bytes +``` + +Then `hop_1` forwards: + +```text +Header(alpha_2, beta_2, gamma_2) +Payload(delta_2) +``` + +At `hop_2`, the original sender, the decrypted routing block is not parsed as a +normal `RoutingInfo`. Instead, the zero address/delay plus nonzero SURB +identifier tells the code this is a reply packet: + +```text +B_2 = + zero address/delay 96 bytes + SURB id 16 bytes + zero padding ... +``` + +The sender extracts the SURB identifier and hands `delta_prime` to reply +recovery. That final payload is not application plaintext yet; it still needs +`processReply(surbKey, surbSecret, delta_prime)`. + +### Local Credential Storage + +`buildSurbs` stores local recovery state in `mixProto.connCreds`: + +```nim +mixProto.connCreds[id] = ConnCreds( + igroup: igroup, + surbSecret: surb.secret.get(), + surbKey: surb.key, + incoming: incoming, +) +``` + +`ConnCreds` contains: + +```nim +type + SURBIdentifierGroup = ref object + members: HashSet[SURBIdentifier] + + ConnCreds = object + igroup: SURBIdentifierGroup + incoming: AsyncQueue[seq[byte]] + surbSecret: serialization.Secret + surbKey: serialization.Key +``` + +Mapping to pull request 307 Section 8.7.2 Step 4: + +- `surbKey` is `k_tilde`. +- `surbSecret` is `s_0 ... s_{L-1}`. +- `connCreds[id]` is the local table indexed by SURB identifier. +- `incoming` is implementation-specific glue for waking the `Connection` reader. + +The `SURBIdentifierGroup` is not described in the pull request spec. It is an +implementation policy for multiple SURBs attached to one request. All SURB IDs +created for that request share the same group object. + +## Distribution to the Exit + +Once SURBs are serialized into the forward payload, the whole message is encoded +as a normal `MixMessage`, padded, and wrapped in the forward Sphinx packet: + +```nim +let message = buildMessage(msgWithSurbs, codec, mixProto.mixNodeInfo.peerId) +let sphinxPacket = wrapInSphinxPacket(message, publicKeys, delay, hop, destHop) +``` + +The exit node eventually decrypts the forward packet and extracts SURBs: + +```nim +let deserialized = MixMessage.deserialize(unpaddedMsg) +let (surbs, message) = extractSURBs(deserialized.message) + +await mixProto.exitLayer.onMessage( + deserialized.codec, message, processedSP.destination, surbs +) +``` + +`extractSURBs` reconstructs only the distributed part: + +```nim +surbs[i].hop = ?Hop.deserialize(hopBytes) +surbs[i].header = ?Header.deserialize(headerBytes) +surbs[i].key = ?readBytes(offset, Opt.some(k)) +``` + +The exit receives no `secret` field. That is correct: only the original sender +should know the per-hop return-path secrets needed for final reply recovery. + +## Exit-Side Use of SURBs + +The exit layer first forwards the request to the real destination protocol: + +```nim +let destConn = await self.switch.dial(destPeerId, @[destAddr], codec) +await destConn.write(message) +``` + +If SURBs were attached, it reads a destination response using the registered +`DestReadBehavior`: + +```nim +let rawResponse = await behavior.callback(destConn) +``` + +Then it calls: + +```nim +await self.reply(surbs, response) +``` + +The current implementation sends the same response over every supplied SURB: + +```nim +let respFuts = surbs.mapIt(self.onReplyDialer(it, msg)) +await allFutures(respFuts) +``` + +This is an important behavioral choice. Pull request 307 Section 8.7.3 describes +how to use a SURB; it does not require using every SURB for the same response. +The Nim implementation currently treats multiple SURBs as redundant return paths +for one response. + +Each individual SURB is used in `mix_protocol.reply`: + +```nim +let (peerId, multiAddr) = surb.hop.get().bytesToMultiAddr() +let message = buildMessage(msg, "", peerId) +let sphinxPacket = useSURB(surb, message) +await mixProto.sendPacket(peerId, multiAddr, sphinxPacket, SendPacketLogConfig(logType: Reply)) +``` + +`buildMessage(msg, "", peerId)` pads the reply as a normal `MessageChunk` +wrapped in a `MixMessage` with an empty codec. The empty codec is acceptable +because the reply is matched by SURB identifier rather than by application +protocol negotiation. + +`useSURB` encrypts the reply payload once with the SURB reply key: + +```nim +let delta_aes_key = deriveKeyMaterial("delta_aes_key", surb.key).kdf() +let delta_iv = deriveKeyMaterial("delta_iv", surb.key).kdf() +let serializedMsg = msg.serialize() +let delta = aes_ctr(delta_aes_key, delta_iv, serializedMsg) + +SphinxPacket.init(surb.header, delta) +``` + +This maps to pull request 307 Section 8.7.3: + +- prepare/pad the reply message; +- encrypt the payload with `k_tilde`; +- assemble a Sphinx packet with the SURB header; +- transmit it to `hop_0` over `/mix/1.0.0`. + +## Return Path Processing + +Return packets use the same `/mix/1.0.0` handler as forward packets. +Intermediate return-path nodes do not know they are forwarding a reply. They +perform ordinary Sphinx processing: + +```nim +let processedSP = processSphinxPacket(...) + +case processedSP.status +of Intermediate: + await mixProto.writeLp(nextPeerId, @[nextAddr], @[MixProtocolID], outgoingPacket) +``` + +Every intermediate hop decrypts one payload layer and forwards the transformed +packet. This is why pull request 307 Section 8.7.3 says the reply is initially encrypted +with `k_tilde`, and each return-path hop adds the corresponding Sphinx payload +transformation. The sender must later remove `L + 1` layers: one for `k_tilde` +and one for each return-path secret. + +## Sender-Side Reply Detection + +The original sender is the final hop of the return path. In +`processSphinxPacket`, after decrypting the final routing block `B`, the code +distinguishes normal forward exit from SURB reply: + +```nim +if B.isZeros((t + 1) * k, ((t + 1) * k) + PaddingLength - 1): + let hop = Hop.deserialize(B[0 .. AddrSize - 1]) + + if B.isZeros(AddrSize, ((t + 1) * k) - 1): + # normal forward exit + elif B.isZeros(0, (t * k) - 1): + return ok( + ProcessedSphinxPacket( + status: Reply, + id: B.extractSurbId(), + delta_prime: delta_prime, + ) + ) +``` + +The SURB identifier is extracted at `t * k`, matching pull request 307 Section 8.7.4: + +```nim +template extractSurbId(data: seq[byte]): SURBIdentifier = + const startIndex = t * k + const endIndex = startIndex + SurbIdLen - 1 + var id: SURBIdentifier + copyMem(addr id[0], addr data[startIndex], SurbIdLen) + id +``` + +## Reply Recovery + +The `Reply` branch in `handleMixMessages` performs implementation-level reply +recovery. + +First it looks up the SURB identifier: + +```nim +if not mixProto.connCreds.hasKey(processedSP.id): + mix_messages_error.inc(labelValues = ["Sender/Reply", "NO_CONN_FOUND"]) + return + +connCred = mixProto.connCreds[processedSP.id] +``` + +This maps to pull request 307 Section 8.7.5 Step 1: retrieve `k_tilde` and +`s_0 ... s_{L-1}` by `id`; if not found, discard. + +Then it removes all payload encryption layers: + +```nim +let reply = processReply( + connCred.surbKey, connCred.surbSecret, processedSP.delta_prime +) +``` + +`processReply` starts with `k_tilde`, then iterates over each stored return-path +secret: + +```nim +var delta = delta_prime[0 ..^ 1] +var key_prime = key + +for i in 0 .. s.len: + if i != 0: + key_prime = s[i - 1] + + let delta_aes_key = deriveKeyMaterial("delta_aes_key", key_prime).kdf() + let delta_iv = deriveKeyMaterial("delta_iv", key_prime).kdf() + + delta = aes_ctr(delta_aes_key, delta_iv, delta) + +let deserializeMsg = Message.deserialize(delta) +``` + +This maps directly to pull request 307 Section 8.7.5 Step 2: decrypt with `k_tilde`, then +with `s_0 ... s_{L-1}`, then check/strip the leading `k` zero bytes through +`Message.deserialize`. + +After that, the implementation deletes all credentials in the identifier group: + +```nim +for id in connCred.igroup.members: + mixProto.connCreds.del(id) +``` + +This is the "first valid reply wins" policy. If a request had `numSurbs > 1`, +all those SURB IDs are in the same group. The first reply that can be recovered +causes all sibling SURB credentials to be removed. + +Late replies for the same request are dropped because their identifiers no +longer exist: + +```nim +if not mixProto.connCreds.hasKey(processedSP.id): + mix_messages_error.inc(labelValues = ["Sender/Reply", "NO_CONN_FOUND"]) + return +``` + +Finally, the recovered reply is decoded and pushed to the queue used by +`MixEntryConnection.readOnce`: + +```nim +let msgChunk = MessageChunk.deserialize(reply) +let unpaddedMsg = msgChunk.removePadding() +let deserialized = MixMessage.deserialize(unpaddedMsg) + +await connCred.incoming.put(deserialized.message) +``` + +Only this first successfully recovered reply becomes visible to the application. + +## `numSurbs > 1` + +In the current implementation, multiple SURBs attached to one request behave as +redundant return paths: + +1. The sender creates `numSurbs` distinct SURB identifiers. +2. Each SURB has its own return path, header, reply key, and stored recovery + credentials. +3. All identifiers are inserted into one `SURBIdentifierGroup`. +4. The exit sends the same destination response through all supplied SURBs. +5. The sender accepts the first valid reply to arrive. +6. The sender deletes credentials for every SURB in the group. +7. Late duplicate replies are discarded with `NO_CONN_FOUND`. +8. One response byte sequence is written to the reply queue. + +This gives redundancy against return-path loss or delay, but it does not provide +multi-response semantics. If a future rewrite wants multiple distinct responses, +the grouping and `MixEntryConnection` read model need to change. + +## Spec Mapping Summary + +| Pull Request 307 Section | Spec Concept | Nim Implementation | +| --- | --- | --- | +| 8.7.1 | SURB is `hop_0`, header, reply key | `SURB(hop, header, key)` in `serialization.nim`; serialized as `hop || header || key` | +| 8.7.2 Step 1 | Select return path ending at sender | `MixProtocol.buildSurb`; last hop is `mixProto.mixNodeInfo` | +| 8.7.2 Step 2 | Sample `id` and `k_tilde` | `buildSurbs` samples `id`; `createSURB` samples `key` | +| 8.7.2 Step 3 | Header has zero address/delay plus `id` | `computeBetaGamma(..., Hop(), id)` | +| 8.7.2 Step 4 | Store recovery tuple by `id` | `mixProto.connCreds[id] = ConnCreds(...)` | +| 8.7.3 | Recipient uses SURB to reply | `ExitLayer.reply` -> `MixProtocol.reply` -> `useSURB` | +| 8.7.4 | Final return hop extracts `id` | `processSphinxPacket` returns `ProcessedSphinxPacket(status: Reply, id, delta_prime)` | +| 8.7.5 | Recover reply with stored keys | `processReply(surbKey, surbSecret, delta_prime)` | + +## Rewrite-Relevant Observations + +- The current model is single-request/single-visible-reply, even when multiple + SURBs are attached. +- Multiple SURBs are grouped and treated as redundant alternatives. First valid + reply consumes the whole group. +- The exit currently sends the same response through every SURB. That is a + policy choice in `ExitLayer.reply`, not an inherent requirement of the SURB + format. +- The reply queue is local connection glue, not part of the cryptographic spec. +- `MixEntryConnection` creates one future waiting for one incoming queue item. + It is not currently a robust stream abstraction for repeated request/reply + cycles over the same connection object. +- `connCreds` has a TODO in `MixProtocol`: credentials may need cleanup when a + response never arrives or the connection is closed. +- The spec says a SURB must be used at most once. The implementation enforces + sender-side single acceptance by deleting credentials, but the exit can still + attempt to use all SURBs it was given. The sender drops late duplicates. +- The implementation does not explicitly check SURB identifier collisions before + inserting into `connCreds`; it relies on 16 bytes of randomness. +- The implementation's application payload budget is smaller than raw + `MessageSize` because `MessageChunk` reserves two bytes for padding length and + four bytes for sequence number. Use `getMaxMessageSizeForCodec(codec, + numberOfSurbs)` when calculating usable application bytes. + +## Appendix: Filler as Suffix Consistency + +Another useful way to understand filler is as a suffix consistency mechanism. +This view focuses on what happens to the tail of Beta when a processing node +appends zero bytes before decrypting. + +Let: + +```text +q = (t + 1) * k = 112 bytes +BetaSize = 576 bytes +betaPrefix size = 464 bytes +``` + +When hop `i` processes a packet, it decrypts: + +```text +beta_i || 0^112 +``` + +The appended 112 zero bytes are not transmitted, but after AES-CTR they become +position-specific keystream bytes. For hop 0: + +```text +tail_0 = KS_0[576..687] +``` + +For hop 0 to reconstruct a full `beta_1`, the missing suffix of `beta_1` must +equal that tail: + +```text +beta_1[464..575] = tail_0 +``` + +The first filler iteration computes exactly this: + +```text +F1 = AES-CTR_0(start = 576, 0^112) + = KS_0[576..687] +``` + +For hop 1, the same problem appears one layer deeper. We need: + +```text +beta_2[464..575] = KS_1[576..687] +``` + +But `beta_1[464..575]` is produced by encrypting `beta_2[352..463]` under hop +1's Beta key at positions `464..575`. To make hop 0's reconstructed +`beta_1[464..575]` equal `F1`, construction must choose: + +```text +beta_2[352..463] XOR KS_1[464..575] = F1 +``` + +So: + +```text +beta_2[352..463] = F1 XOR KS_1[464..575] +``` + +The second filler iteration computes both required pieces at once: + +```text +F2 = AES-CTR_1(start = 464, F1 || 0^112) + +F2 = + (F1 XOR KS_1[464..575]) + || + (0^112 XOR KS_1[576..687]) +``` + +That final `F2` is appended to the terminal Beta block: + +```text +beta_2 = AES-CTR_2(destPadding) || F2 +``` + +So filler is not just "padding." It is precomputed tail material that makes the +suffix bytes created from appended zeros at one hop match the suffix bytes the +next Beta state needs. + +Compactly: + +```text +Construction: + precompute encrypted tail bytes as filler + +Processing at each hop: + decrypt beta || 112 zero bytes + consume the first 112 bytes as routing info + carry the remaining 576 bytes forward as next beta +``` diff --git a/10 Notes/Understanding NAT.md b/10 Notes/Understanding NAT.md new file mode 100644 index 0000000..75f4af5 --- /dev/null +++ b/10 Notes/Understanding NAT.md @@ -0,0 +1,2 @@ +Some learning resources about [[NAT]]: +- https://tailscale.com/blog/how-nat-traversal-works \ No newline at end of file diff --git a/10 Notes/libp2p MIX Architecture and API.md b/10 Notes/libp2p MIX Architecture and API.md new file mode 100644 index 0000000..8e8ff8d --- /dev/null +++ b/10 Notes/libp2p MIX Architecture and API.md @@ -0,0 +1,552 @@ +The copy of this document can be found in [https://github.com/logos-storage/libp2p-storage-mix-transport/blob/master/docs/mix.md](https://github.com/logos-storage/libp2p-storage-mix-transport/blob/master/docs/mix.md). The content of this document should contain the most recent version. + +> This document belong to the series of [[Mix Implementation]] notes. + +This document describes the MIX implementation vendored with this [project] under +`nimbledeps/pkgs2/libp2p-*/libp2p/protocols/mix`. It focuses on how the code is +structured, what API surface is intended for callers, and what constraints matter +when using MIX as a transport-like wrapper for other libp2p protocols. + +## Overview + +MIX adds an anonymous message routing layer on top of libp2p streams. A sender +wraps an application protocol message in a fixed-size Sphinx packet, sends it to +a randomly selected mix path, and lets each hop peel one routing layer before +forwarding the packet. The final mix hop acts as an exit node and forwards the +inner message to the real destination protocol. Replies are optional and are +returned through Single Use Reply Blocks (SURBs), so the destination can respond +without learning the sender. + +The libp2p protocol ID is: + +```nim +const MixProtocolID* = "/mix/1.0.0" +``` + +At a high level: + +```text +sender protocol + | + | writes to MixEntryConnection + v +entry MixProtocol + | + | Sphinx packet over /mix/1.0.0 + v +mix hop 1 -> mix hop 2 -> ... -> exit mix hop + | + | original codec + v + destination protocol + | + | optional response via SURBs + v +sender MixEntryConnection +``` + +## Main Modules + +The public import is `libp2p/protocols/mix`. It re-exports the main types and +helpers from the implementation modules: + +- `mix_protocol.nim`: main `MixProtocol` implementation, path selection, + Sphinx packet handling, SURB creation, forwarding, and reply processing. +- `mix_node.nim`: private/public mix node identity records. +- `pool.nim`: `MixNodePool`, backed by the libp2p `PeerStore`. +- `entry_connection.nim`: `MixEntryConnection`, a `Connection` facade used by + local protocols to write through MIX and optionally read replies. +- `exit_layer.nim`: destination forwarding and reply dispatch from the exit + node. +- `reply_connection.nim`: `MixReplyConnection`, a write-only connection facade + used by the exit layer to send replies over SURBs. +- `serialization.nim`, `sphinx.nim`, `fragmentation.nim`, `mix_message.nim`: + fixed packet formats, Sphinx processing, padding, and application message + encoding. +- `multiaddr.nim`: compact encoding for next-hop and destination addresses. +- `delay_strategy.nim`: pluggable per-hop delay strategy. +- `spam_protection.nim`: optional per-hop proof interface. +- `tag_manager.nim`: replay detection state for Sphinx tags. + +## Core Types + +### `MixProtocol` + +`MixProtocol` is an `LPProtocol` mounted on a libp2p `Switch`. Each running mix +node owns one instance. + +Important fields and collaborators: + +- `mixNodeInfo`: this node's libp2p identity and Curve25519 MIX keypair. +- `switch`: the underlying libp2p switch used for dialing peers and destinations. +- `nodePool`: public information for candidate mix nodes. +- `tagManager`: replay detection for processed Sphinx packets. +- `exitLayer`: forwards exit messages to destination protocols and sends replies. +- `connCreds`: temporary SURB credentials for expected replies. +- `destReadBehavior`: per-codec callbacks that tell the exit node how to read a + destination response. +- `spamProtection`: optional proof generator/verifier. +- `delayStrategy`: pluggable encoded/actual delay policy. + +Create and mount it with: + +```nim +let proto = MixProtocol.new(nodeInfo, switch) +await proto.start() +proto.nodePool.add(otherMixNodes) +switch.mount(proto) +``` + +`MixProtocol.new` defaults to `NoSamplingDelayStrategy` and no spam protection. + +### `MixNodeInfo` and `MixPubInfo` + +`MixNodeInfo` contains private node data and is used by the local mix node: + +```nim +type MixNodeInfo* = object + peerId*: PeerId + multiAddr*: MultiAddress + mixPubKey*: FieldElement + mixPrivKey*: FieldElement + libp2pPubKey*: SkPublicKey + libp2pPrivKey*: SkPrivateKey +``` + +`MixPubInfo` is the shareable subset stored in `MixNodePool`: + +```nim +type MixPubInfo* = object + peerId*: PeerId + multiAddr*: MultiAddress + mixPubKey*: FieldElement + libp2pPubKey*: SkPublicKey +``` + +Convenience helpers: + +- `MixNodeInfo.generateRandom(port)` +- `MixNodeInfo.generateRandomMany(count, basePort = 4242)` +- `initMixNodeInfo(...)` +- `toMixPubInfo(info)` +- `includeAllExcept(allNodes, exceptNode)` + +In local examples, switches are started first so wildcard listen addresses are +resolved, then `initMixNodeInfo` rebuilds each node record with a dialable +address from `switch.peerInfo.addrs`. + +### `MixNodePool` + +`MixNodePool` manages public mix node information through the switch peer store. +It writes to the peer store's mix public key book, address book, and key book. + +Public operations: + +```nim +let pool = MixNodePool.new(switch.peerStore) +pool.add(info) +pool.add(infos) +discard pool.remove(peerId) +let infoOpt = pool.get(peerId) +let ids = pool.peerIds() +let n = pool.len +``` + +Supported addresses are IPv4 TCP and IPv4 QUIC-v1, including supported +circuit-relay addresses over those base transports. IPv6, DNS, WebSocket, and +related address forms are not supported by the compact address encoder in this +implementation. + +The implementation requires Secp256k1 libp2p peer IDs when serializing hop +addresses. + +### `MixDestination` + +`MixDestination` identifies the final target of a mixed message. + +Normal usage forwards from the exit node to a destination address: + +```nim +let destination = MixDestination.init(destPeerId, destAddr) +``` + +This is equivalent to `MixDestination.forwardToAddr(destPeerId, destAddr)`. + +There is also compile-time experimental support for `exit == destination` behind +`-d:libp2p_mix_experimental_exit_is_dest`. Without that define, the destination +must be a separate forwarded address. + +### `MixParameters` + +`MixParameters` controls entry connection behavior: + +```nim +type MixParameters* = object + expectReply*: Opt[bool] + numSurbs*: Opt[uint8] +``` + +If `expectReply` is true, `toConnection` creates an incoming queue and the +sender embeds SURBs in the outgoing payload. If `numSurbs` is omitted while a +reply is expected, `MixEntryConnection` uses a default of 4 SURBs. If no reply is +expected, the number of SURBs is forced to 0. + +### `DestReadBehavior` + +When a request expects a reply, the exit node needs to know how to read a +response from the destination protocol connection. Register that per application +codec on every mix node that may be selected as an exit: + +```nim +proto.registerDestReadBehavior(PingCodec, readExactly(32)) +``` + +The public helpers are: + +```nim +readExactly(nBytes: int): DestReadBehavior +readLp(maxSize: int): DestReadBehavior +``` + +Use `readExactly` for fixed-size response protocols. Use `readLp` when the +destination protocol returns length-prefixed messages using libp2p's varint LP +framing. For `readLp`, the exit layer restores the length prefix before sending +the reply through MIX, allowing the original caller to call `readLp()` on the +returned `MixEntryConnection`. + +## Sending Through MIX + +### What "writes to `MixEntryConnection`" means + +In libp2p Nim, application protocols usually talk to a generic +`Connection`. For example, the Ping client does not know whether the connection +is a direct TCP stream, QUIC stream, relay stream, or MIX-backed connection: + +```nim +proc ping*(p: Ping, conn: Connection): Future[Duration] = + await conn.write(randomBytes) + await conn.readExactly(addr resultBuf[0], 32) +``` + +`MixEntryConnection` is a custom `Connection` implementation. It has the same +`write` and `readOnce`/`readExactly` behavior that application protocols expect, +but its `write` method does not write directly to the destination. Instead, it +calls into `MixProtocol.anonymizeLocalProtocolSend`, which wraps that write in a +Sphinx packet and sends it through the mixnet. + +So "writes to `MixEntryConnection`" normally happens indirectly: + +1. Application code calls an existing protocol helper, such as + `pingProto.ping(conn)`. +2. That helper calls `conn.write(...)`. +3. Because `conn` is actually a `MixEntryConnection`, the write becomes a MIX + send. +4. If the helper later calls `conn.readExactly(...)`, `MixEntryConnection` waits + for a SURB reply and serves the reply bytes from its local incoming queue. + +This is why `mix_ping_tcp.nim` can reuse the normal Ping client logic: + +```nim +let pingProto = Ping.new() +destNode.mount(pingProto) + +let conn = mixProtos[senderIndex] + .toConnection( + MixDestination.init(destNode.peerInfo.peerId, destNode.peerInfo.addrs[0]), + PingCodec, + MixParameters(expectReply: Opt.some(true), numSurbs: Opt.some(byte(1))), + ) + .expect("could not build connection") + +let response = await pingProto.ping(conn) +``` + +There are two different uses of the same `Ping` instance here: + +- Mounted on `destNode`, `Ping` acts as the destination server handler. It reads + 32 bytes and writes the same 32 bytes back. +- Called as `pingProto.ping(conn)`, `Ping` acts as client-side helper code. It + only needs a `Connection`, so it can use the MIX-backed connection returned by + `toConnection`. + +### Preferred API: `toConnection` + +The ergonomic API is `toConnection`, which returns a libp2p `Connection` +implementation. Use this when you want an existing libp2p protocol helper to run +over MIX: + +```nim +let conn = mixProto + .toConnection( + MixDestination.init(destNode.peerInfo.peerId, destNode.peerInfo.addrs[0]), + PingCodec, + MixParameters(expectReply: Opt.some(true), numSurbs: Opt.some(byte(1))), + ) + .expect("could not build connection") + +let response = await pingProto.ping(conn) +await conn.close() +``` + +`MixEntryConnection.write` sends each write as one independent MIX message by +calling `MixProtocol.anonymizeLocalProtocolSend`. `readOnce` waits for one reply +if the connection was created with `expectReply = true`. + +If `expectReply = true` and no destination read behavior has been registered on +the sender's local `MixProtocol`, `toConnection` returns an error. The actual +response read happens on the selected exit node, so practical deployments should +register the same behavior on all candidate exit nodes. If no reply is expected, +missing read behavior only logs a warning. + +### Lower-level API: `anonymizeLocalProtocolSend` + +`MixProtocol.anonymizeLocalProtocolSend` is also exported from +`mix_protocol.nim` itself. It sends one byte message through MIX without first +constructing a `Connection` facade: + +```nim +let incoming = newAsyncQueue[seq[byte]]() +let sendRes = await mixProto.anonymizeLocalProtocolSend( + incoming, + msg, + codec, + destination, + numSurbs, +) +``` + +This is useful if you are building a custom adapter and want direct control over +the incoming reply queue. It is less convenient for normal libp2p protocols +because those protocols usually expect to read and write through a `Connection`. + +In this implementation, the practical outbound interaction models are: + +- Use `toConnection` and pass the returned connection to an existing protocol + client helper. This is the normal path. +- Use `toConnection` directly and call `conn.write`, `conn.readExactly`, + `conn.readLp`, etc. yourself. +- Call `anonymizeLocalProtocolSend` from `mix_protocol.nim` for a lower-level + one-message send. + +Inbound mixnet traffic is not handled by application code directly. Mix nodes +receive `/mix/1.0.0` streams through the mounted `MixProtocol`; the exit layer +then dials the destination using the original application codec. + +## Internal Message Flow + +### Entry + +`anonymizeLocalProtocolSend` performs the sender-side work: + +1. Check that the node pool has at least `PathLength` available public mix nodes. +2. Randomly select a path from `nodePool`, excluding the final destination if it + is also present in the pool. +3. Use the last selected mix node as the exit node. +4. Encode each hop as compact bytes containing IPv4 address, transport, port, + optional relay peer ID, and peer ID. +5. Generate per-hop delay values using `delayStrategy.generateForEntry`. +6. Optionally create SURBs for replies and prepend them to the application + message. +7. Encode the application message as `MixMessage(message, codec)`. +8. Pad it into one fixed-size `MessageChunk`. +9. Wrap it into a Sphinx packet using the selected public keys, delays, hops, + and final destination. +10. Optionally append a spam protection proof. +11. Send the packet to the first hop over `/mix/1.0.0`. + +### Intermediate Hop + +Each mix node handles inbound `/mix/1.0.0` streams in +`handleMixNodeConnection`. For every length-prefixed packet read from the stream, +it spawns `handleMixMessages`. + +For intermediate packets: + +1. Extract the optional spam proof. +2. Deserialize the Sphinx packet. +3. Check replay tags with the node's MIX private key and `TagManager`. +4. Verify spam protection after the replay check. +5. Process the Sphinx packet to reveal the next hop and transformed packet. +6. Compute the actual delay using `delayStrategy.generateForIntermediate`. +7. Generate a fresh per-hop spam proof for the outgoing packet if enabled. +8. Sleep for the computed delay. +9. Forward to the next hop over `/mix/1.0.0`. + +Connections to next hops are cached by peer ID in `connPool`. If a cached stream +is closed or reset, the implementation dials a fresh stream and retries the +write. + +### Exit + +When Sphinx processing returns `Exit`, the node: + +1. Deserializes and unpads the `MessageChunk`. +2. Deserializes the `MixMessage` to recover `codec` and `message`. +3. Extracts any embedded SURBs. +4. Passes the request to `ExitLayer.onMessage`. + +For normal forwarded destinations, `ExitLayer` dials the destination peer using +the recovered codec, writes the raw inner message, and optionally reads a +response using the registered `DestReadBehavior`. + +If SURBs were provided, the exit layer sends the response back through every SURB +using a `MixReplyConnection`. + +### Reply + +Replies do not contain an application codec; they are associated with a SURB +identifier generated by the original sender. + +The original sender stores each generated SURB identifier in `connCreds` with +the SURB key, secret, identifier group, and incoming queue. When a `Reply` packet +arrives: + +1. The sender looks up the SURB identifier. +2. It processes the reply using the stored SURB key and secret. +3. It deletes all credentials in the same identifier group. +4. It deserializes, unpads, and decodes the reply message. +5. It places the reply bytes on the entry connection's incoming queue. + +Because the credentials are single-use, one response consumes the associated SURB +group. + +## Packet and Payload Limits + +Important constants from `serialization.nim` and `fragmentation.nim`: + +```nim +PacketSize = 4608 +MessageSize = PacketSize - HeaderSize - k +DataSize = MessageSize - PaddingLengthSize - SeqNoSize +PathLength = 3 +``` + +Current code builds a single padded `MessageChunk` for each `write`; it does not +automatically split large application messages in `anonymizeLocalProtocolSend`. +`MixEntryConnection.write` rejects messages larger than `DataSize`, and +`buildMessage` rejects serialized `MixMessage` values larger than `DataSize`. + +Because MIX adds codec and SURB overhead inside the fixed payload, callers should +use: + +```nim +let maxPayload = getMaxMessageSizeForCodec(codec, numberOfSurbs) +``` + +This returns the maximum application message size available for the given codec +and number of embedded SURBs. + +## Delay Strategies + +Delay behavior is pluggable through `DelayStrategy`. + +Built-in strategies: + +- `NoSamplingDelayStrategy`: default. The entry node encodes a random delay in + the range 0-2 ms, and intermediate nodes use that value directly. +- `ExponentialDelayStrategy`: the entry node encodes a mean delay, and + intermediate nodes sample from an exponential distribution with that mean. + The default mean is `DefaultMeanDelayMs = 100`. + +Example: + +```nim +let rng = newRng() +let delay = ExponentialDelayStrategy.new(meanDelayMs = 100, rng = rng) +let proto = MixProtocol.new(nodeInfo, switch, rng = rng, delayStrategy = Opt.some(delay)) +``` + +When spam protection is enabled, proof generation runs in parallel with the +intermediate delay. If proof generation takes longer than the configured delay, +the effective delay becomes the proof generation time. + +## Spam Protection + +Spam protection is optional and is represented by an abstract `SpamProtection` +object: + +```nim +type SpamProtection* = ref object of RootObj + proofSize*: int + +method generateProof(self: SpamProtection, bindingData: seq[byte]): Result[seq[byte], string] +method verifyProof(self: SpamProtection, encodedProofData: seq[byte], bindingData: seq[byte]): Result[bool, string] +``` + +If provided to `MixProtocol.new`, the wire packet becomes: + +```text +[Sphinx packet: 4608 bytes][proof: proofSize bytes] +``` + +Each hop extracts and verifies the incoming proof, processes the Sphinx packet, +then generates a fresh proof for the next hop. If no spam protection instance is +provided, packets are just the fixed-size Sphinx packet. + +## Address Constraints + +Hop and destination addresses are encoded into a fixed `AddrSize` field. The +implementation currently supports: + +- `/ip4/.../tcp/...` +- `/ip4/.../udp/.../quic-v1` +- circuit-relay variants over those base transports + +Current limitations: + +- No IPv6 support. +- No DNS or DNS4 support. +- No WebSocket, WebSocket Secure, or SNI support. +- Peer IDs must serialize to the expected Secp256k1 multihash length. + +Invalid or unsupported mix node addresses are removed from consideration during +path construction. + +## Minimal Setup Pattern + +The local TCP and QUIC examples follow this shape: + +```nim +let mixNodeInfos = MixNodeInfo.generateRandomMany(NumMixNodes) + +for nodeInfo in mixNodeInfos: + let switch = createSwitch(nodeInfo.multiAddr, Opt.some(nodeInfo.libp2pPrivKey)) + await switch.start() + switches.add(switch) + +let resolvedInfos = collect: + for i, nodeInfo in mixNodeInfos: + initMixNodeInfo( + nodeInfo.peerId, + switches[i].peerInfo.addrs[0], + nodeInfo.mixPubKey, + nodeInfo.mixPrivKey, + nodeInfo.libp2pPubKey, + nodeInfo.libp2pPrivKey, + ) + +for i, nodeInfo in resolvedInfos: + let proto = MixProtocol.new(nodeInfo, switches[i]) + await proto.start() + proto.nodePool.add(resolvedInfos.includeAllExcept(nodeInfo)) + proto.registerDestReadBehavior(PingCodec, readExactly(32)) + switches[i].mount(proto) +``` + +For QUIC, build switches with `TransportType.QUIC` and use +`/ip4/0.0.0.0/udp/0/quic-v1` listen addresses. + +## Operational Notes + +- Every mix participant must mount `MixProtocol` on its switch. +- The sender's node pool must contain enough usable mix nodes for `PathLength`. +- Destination protocols do not need to know about MIX when using normal + exit-forwarding mode; the exit node dials them by their original codec. +- Replies require a registered `DestReadBehavior` for the application codec. + Register it on all candidate exit nodes; the sender also checks for a local + registration before creating a reply-capable connection. +- MIX messages are independent and stateless at the routing layer, apart from + replay protection tags, cached outbound streams, and temporary SURB credentials. +- `MixProtocol.stop` marks the protocol stopped and stops the tag manager, but + it does not perform broad connection-pool or credential cleanup. +- Benchmark-only metadata framing is compiled in with `-d:enable_mix_benchmarks`. diff --git a/90 Extras/92 Assets/MixNets - Sphinx YouTube video_0.png b/90 Extras/92 Assets/MixNets - Sphinx YouTube video_0.png new file mode 100644 index 0000000..ebdd1a3 Binary files /dev/null and b/90 Extras/92 Assets/MixNets - Sphinx YouTube video_0.png differ diff --git a/90 Extras/92 Assets/MixNets - Sphinx YouTube video_1.png b/90 Extras/92 Assets/MixNets - Sphinx YouTube video_1.png new file mode 100644 index 0000000..6545a4d Binary files /dev/null and b/90 Extras/92 Assets/MixNets - Sphinx YouTube video_1.png differ diff --git a/90 Extras/92 Assets/MixNets - Sphinx YouTube video_2.png b/90 Extras/92 Assets/MixNets - Sphinx YouTube video_2.png new file mode 100644 index 0000000..9217a57 Binary files /dev/null and b/90 Extras/92 Assets/MixNets - Sphinx YouTube video_2.png differ diff --git a/90 Extras/92 Assets/MixNets - Sphinx YouTube video_3.png b/90 Extras/92 Assets/MixNets - Sphinx YouTube video_3.png new file mode 100644 index 0000000..e141d4a Binary files /dev/null and b/90 Extras/92 Assets/MixNets - Sphinx YouTube video_3.png differ diff --git a/90 Extras/92 Assets/MixNets - Sphinx YouTube video_4.png b/90 Extras/92 Assets/MixNets - Sphinx YouTube video_4.png new file mode 100644 index 0000000..a67e5ab Binary files /dev/null and b/90 Extras/92 Assets/MixNets - Sphinx YouTube video_4.png differ diff --git a/90 Extras/92 Assets/MixNets - Sphinx YouTube video_5.png b/90 Extras/92 Assets/MixNets - Sphinx YouTube video_5.png new file mode 100644 index 0000000..8317d01 Binary files /dev/null and b/90 Extras/92 Assets/MixNets - Sphinx YouTube video_5.png differ diff --git a/90 Extras/92 Assets/Pasted image 20250513024925.png b/90 Extras/92 Assets/Pasted image 20250513024925.png deleted file mode 100644 index 2176fb6..0000000 Binary files a/90 Extras/92 Assets/Pasted image 20250513024925.png and /dev/null differ diff --git a/90 Extras/92 Assets/Pasted image 20250724142014.png b/90 Extras/92 Assets/Pasted image 20250724142014.png deleted file mode 100644 index 8eacd76..0000000 Binary files a/90 Extras/92 Assets/Pasted image 20250724142014.png and /dev/null differ diff --git a/90 Extras/92 Assets/Pasted image 20250911204521.png b/90 Extras/92 Assets/Pasted image 20250911204521.png deleted file mode 100644 index fc063b6..0000000 Binary files a/90 Extras/92 Assets/Pasted image 20250911204521.png and /dev/null differ diff --git a/90 Extras/92 Assets/Sphinx Header Processing Infographic 2026-05-11 02.50.17.excalidraw.md b/90 Extras/92 Assets/Sphinx Header Processing Infographic 2026-05-11 02.50.17.excalidraw.md new file mode 100644 index 0000000..c29622c --- /dev/null +++ b/90 Extras/92 Assets/Sphinx Header Processing Infographic 2026-05-11 02.50.17.excalidraw.md @@ -0,0 +1,3030 @@ +--- + +excalidraw-plugin: parsed +tags: [excalidraw] + +--- +==⚠ Switch to EXCALIDRAW VIEW in the MORE OPTIONS menu of this document. ⚠== You can decompress Drawing data with the command palette: 'Decompress current Excalidraw file'. For more info check in plugin settings under 'Saving' + + +# Excalidraw Data + +## Text Elements + +proc computeFillerStrings(s: seq[seq[byte]]): Result[seq[byte], string] = + var filler: seq[byte] = @[] + + for i in 1 ..< s.len: + let + aes_key = deriveKeyMaterial("aes_key", s[i - 1]).kdf() + iv = deriveKeyMaterial("iv", s[i - 1]).kdf() + + let + fillerLength = (t + 1) * k + zeroPadding = newSeq[byte](fillerLength) + + filler = aes_ctr_start_index( + aes_key, + iv, + filler & zeroPadding, + (((t + 1) * (r - i)) + t + 2) * k, + ) + + return ok(filler) ^JZsrbKFI + +i = 1 ^sCUTbIs5 + +i = 2 ^N3TLV4Hs + +i = 3 ^C0Uw6jGX + + +proc computeBetaGamma( + s: seq[seq[byte]], + hops: openArray[Hop], + delay: openArray[seq[byte]], + destHop: Hop, + id: SURBIdentifier, +): Result[tuple[beta: seq[byte], gamma: seq[byte]], string] = + let sLen = s.len + var + beta: seq[byte] + gamma: seq[byte] + + let filler = computeFillerStrings(s).valueOr: + return err("Error in filler generation: " & error) + + for i in countdown(sLen - 1, 0): + let + beta_aes_key = deriveKeyMaterial("aes_key", s[i]).kdf() + mac_key = deriveKeyMaterial("mac_key", s[i]).kdf() + beta_iv = deriveKeyMaterial("iv", s[i]).kdf() + + if i == sLen - 1: + let destBytes = destHop.serialize() + let destPadding = destBytes & delay[i] & @id & newSeq[byte](PaddingLength) + let aes = aes_ctr(beta_aes_key, beta_iv, destPadding) + beta = aes & filler + else: + let betaPrefix = + beta[0 .. (((r * (t + 1)) - t) * k) - 1] + + let routingInfo = RoutingInfo.init( + hops[i + 1], + delay[i], + gamma, + betaPrefix, + ) + + let serializedRoutingInfo = routingInfo.serialize() + beta = aes_ctr(beta_aes_key, beta_iv, serializedRoutingInfo) + + gamma = hmac(mac_key, beta).toSeq() + + return ok((beta: beta, gamma: gamma)) ^hbb85k1n + +i = 3 ^cDn7qQ33 + +filler ^8sx5srIe + +i = 2 ^T9mizIXz + +i = 1 ^ohEzxPL5 + +i = 0 ^xev2b5J7 + +hop 0 ^6utiEESr + +hop 1 ^I0SU7PAs + +hop 2 ^qdYaK063 + +filler ^iueU5Qmb + +hop 3 ^1Np7nLmR + +filler ^T87RrIOV + +Yes, we are just +following the routine. +It will create garbage +at the filler position, +but the first 240 bytes +will remain correct. ^uQAISp7N + +## Embedded Files +bb5b547701d54147800f0504a7243cead0c05a74: $$\mathrm{Header\ Construction}$$ + +df5f68569d79b203a5777e4fc25fb08bc54727a8: $$\mathrm{Filler}$$ + +a35f8920ed51dcebc6adc6d7d77e74f3f6126ab6: $$\mathcal{H}=(\alpha,\beta,\gamma)$$ + +6cca88282dac996aae74a0c86266244ec4351c0b: $$\mathsf{Start\ index\ in\ the\ keystream\ aes\_key\ }(\mathcal{S}_i).$$ + +c694375a39b5a6909a3dd95c479a60dce5336b21: $$(((t+1)(r-i)) + t +2)k = 576$$ + +8b21d359930e1473b5d5ad2952a2ba784675b50a: $$\begin{matrix} +\mathsf{filler} \; = \ \\ +\vphantom{a} +\end{matrix} +\begin{array}{l} +\{0\}^{112} \\ +\,\left\vert +\begin{matrix} +\small\;\mathcal{S}_0[576,688) +\end{matrix} +\right. +\end{array}$$ + +a48dab53b299b7d0ef5ada587c84cebc485dbb17: $$(((t+1)(r-i)) + t +2)k = 464$$ + +7a389a4e0e00b05c6ddb9187299198d6f60b719c: $$\begin{matrix} +\mathsf{filler} \; = \ \\ +\vphantom{a} \\ +\vphantom{a} +\end{matrix} +\begin{array}{l} +\{0\}^{112} \\ +\,\left\vert +\begin{matrix} +\small\;\mathcal{S}_0[576,688) \\ +\small\;\mathcal{S}_1[464,576) +\end{matrix} +\right. +\end{array} +\begin{matrix} +\quad\Large\Vert\quad \\ +\vphantom{a} \\ +\vphantom{a} +\end{matrix} +\begin{array}{l} +\{0\}^{112} \\ +\,\left\vert +\begin{matrix} +\small\vphantom{a} \\ +\small\;\mathcal{S}_1[576,688) +\end{matrix} +\right. +\end{array}$$ + +c1fc20faa1b1254b2c010158b369d6d152819035: $$(((t+1)(r-i)) + t +2)k = 352$$ + +d1ed8333586b8a13f41804a581bebb65f4f0d4f6: $$\begin{matrix} +\mathsf{filler} \; = \ \\ +\vphantom{a} \\ +\vphantom{a} \\ +\vphantom{a} +\end{matrix} +\begin{array}{l} +\{0\}^{112} \\ +\,\left\vert +\begin{matrix} +\small\;\mathcal{S}_0[576,688) \\ +\small\;\mathcal{S}_1[464,576) \\ +\small\;\mathcal{S}_2[352,464) +\end{matrix} +\right. +\end{array} +\begin{matrix} +\quad\Large\Vert\quad \\ +\vphantom{a} \\ +\vphantom{a} \\ +\vphantom{a} +\end{matrix} +\begin{array}{l} +\{0\}^{112} \\ +\,\left\vert +\begin{matrix} +\small\vphantom{a} \\ +\small\;\mathcal{S}_1[576,688) \\ +\small\;\mathcal{S}_2[464,576) +\end{matrix} +\right. +\end{array} +\begin{matrix} +\quad\Large\Vert\quad \\ +\vphantom{a} \\ +\vphantom{a} \\ +\vphantom{a} +\end{matrix} +\begin{array}{l} +\{0\}^{112} \\ +\,\left\vert +\begin{matrix} +\small\vphantom{a} \\ +\small\vphantom{a} \\ +\small\;\mathcal{S}_2[576,688) +\end{matrix} +\right. +\end{array}$$ + +9cd565d59f425759e7d4571cb0515aba568461d0: $$\begin{matrix} +(\{0\}^{94}\,\Vert\,\{0\}^{2}\,\Vert\,\mathcal{id}_{\mathsf{SURB}}\,\Vert\,\{0\}^{128}) \\ +\small\vphantom{a} \\ +\small\vphantom{a} \\ +\small\vphantom{a} +\end{matrix} +\begin{matrix} +\quad\Large\Vert\quad \\ +\small\vphantom{a} \\ +\small\vphantom{a} \\ +\small\vphantom{a} +\end{matrix} +\begin{array}{l} +\{0\}^{112} \\ +\,\left\vert +\begin{matrix} +\small\;\mathcal{S}_0[576,688) \\ +\small\;\mathcal{S}_1[464,576) \\ +\small\;\mathcal{S}_2[352,464) +\end{matrix} +\right. +\end{array} +\begin{matrix} +\quad\Large\Vert\quad \\ +\small\vphantom{a} \\ +\small\vphantom{a} \\ +\small\vphantom{a} +\end{matrix} +\begin{array}{l} +\{0\}^{112} \\ +\,\left\vert +\begin{matrix} +\small\vphantom{a} \\ +\small\;\mathcal{S}_1[576,688) \\ +\small\;\mathcal{S}_2[464,576) +\end{matrix} +\right. +\end{array} +\begin{matrix} +\quad\Large\Vert\quad \\ +\small\vphantom{a} \\ +\small\vphantom{a} \\ +\small\vphantom{a} +\end{matrix} +\begin{array}{l} +\{0\}^{112} \\ +\,\left\vert +\begin{matrix} +\small\vphantom{a} \\ +\small\vphantom{a} \\ +\small\;\mathcal{S}_2[576,688) +\end{matrix} +\right. +\end{array}$$ + +0b3697062776e5871a082ded7dd0cc47a54506cd: $$\begin{array}{l} +(\{0\}^{94}\,\Vert\,\{0\}^{2}\,\Vert\,\mathcal{id}_{\mathsf{SURB}}\,\Vert\,\{0\}^{128}) \\ +\,\left\vert +\begin{matrix} +\small\vphantom{a} \\ +\small\vphantom{a} \\ +\small\;\mathcal{S}_3[0,240) +\end{matrix} +\right. +\end{array} +\begin{matrix} +\quad\Large\Vert\quad \\ +\small\vphantom{a} \\ +\small\vphantom{a} \\ +\small\vphantom{a} +\end{matrix} +\begin{array}{l} +\{0\}^{112} \\ +\,\left\vert +\begin{matrix} +\small\;\mathcal{S}_0[576,688) \\ +\small\;\mathcal{S}_1[464,576) \\ +\small\;\mathcal{S}_2[352,464) +\end{matrix} +\right. +\end{array} +\begin{matrix} +\quad\Large\Vert\quad \\ +\small\vphantom{a} \\ +\small\vphantom{a} \\ +\small\vphantom{a} +\end{matrix} +\begin{array}{l} +\{0\}^{112} \\ +\,\left\vert +\begin{matrix} +\small\vphantom{a} \\ +\small\;\mathcal{S}_1[576,688) \\ +\small\;\mathcal{S}_2[464,576) +\end{matrix} +\right. +\end{array} +\begin{matrix} +\quad\Large\Vert\quad \\ +\small\vphantom{a} \\ +\small\vphantom{a} \\ +\small\vphantom{a} +\end{matrix} +\begin{array}{l} +\{0\}^{112} \\ +\,\left\vert +\begin{matrix} +\small\vphantom{a} \\ +\small\vphantom{a} \\ +\small\;\mathcal{S}_2[576,688) +\end{matrix} +\right. +\end{array}$$ + +c1f9204a7e884a102a70456a2862f541a0396615: $$\mathcal{S}_3[0,240)$$ + +d0c949e1a1ce277db33d3c38a5648f42eb72b69e: $$\widetilde\beta_3$$ + +c4dff163ffc907e293e29c011204d671ab20a0ce: $$\beta_3$$ + +0c4012ecd594add31357d5308dddd626736a7005: $$\begin{array}{l} +(\{0\}^{94}\,\Vert\,\{0\}^{2}\,\Vert\,\mathcal{id}_{\mathsf{SURB}}\,\Vert\,\{0\}^{128}) \\ +\,\left\vert +\begin{matrix} +\small\vphantom{a} \\ +\small\vphantom{a} \\ +\small\;\mathcal{S}_3[0,240) +\end{matrix} +\right. +\end{array} +\begin{matrix} +\quad\Large\Vert\quad \\ +\small\vphantom{a} \\ +\small\vphantom{a} \\ +\small\vphantom{a} +\end{matrix} +\begin{array}{l} +\{0\}^{112} \\ +\,\left\vert +\begin{matrix} +\small\;\mathcal{S}_0[576,688) \\ +\small\;\mathcal{S}_1[464,576) \\ +\small\;\mathcal{S}_2[352,464) +\end{matrix} +\right. +\end{array} +\begin{matrix} +\quad\Large\Vert\quad \\ +\small\vphantom{a} \\ +\small\vphantom{a} \\ +\small\vphantom{a} +\end{matrix} +\begin{array}{l} +\{0\}^{112} \\ +\,\left\vert +\begin{matrix} +\small\vphantom{a} \\ +\small\;\mathcal{S}_1[576,688) \\ +\small\;\mathcal{S}_2[464,576) +\end{matrix} +\right. +\end{array} +\begin{matrix} +\quad\Large\Vert\quad \\ +\small\vphantom{a} \\ +\small\vphantom{a} \\ +\small\vphantom{a} +\end{matrix} +\begin{array}{l} +\{0\}^{112} \\ +\,\left\vert +\begin{matrix} +\small\vphantom{a} \\ +\small\vphantom{a} \\ +\small\;\mathcal{S}_2[576,688) +\end{matrix} +\right. +\end{array}$$ + +b6a48b517a716c9efa2f39d5e12a237374af22ac: $$\mathcal{S}_2[0,576)$$ + +d57aa6ebb82c4323d1a7446e310a84c8d3f4d92e: $$\begin{matrix} +(A_3\,\Vert\,D_2\,\Vert\,\gamma_3) \\ +\small\vphantom{a} \\ +\small\vphantom{a} \\ +\small\vphantom{a} +\end{matrix} +\begin{matrix} +\quad\Large\Vert\quad \\ +\small\vphantom{a} \\ +\small\vphantom{a} \\ +\small\vphantom{a} +\end{matrix} +\begin{array}{l} +(\{0\}^{94}\,\Vert\,\{0\}^{2}\,\Vert\,\mathcal{id}_{\mathsf{SURB}}\,\Vert\,\{0\}^{128}) \\ +\,\left\vert +\begin{matrix} +\small\vphantom{a} \\ +\small\vphantom{a} \\ +\small\;\mathcal{S}_3[0,240) +\end{matrix} +\right. +\end{array} +\begin{matrix} +\quad\Large\Vert\quad \\ +\small\vphantom{a} \\ +\small\vphantom{a} \\ +\small\vphantom{a} +\end{matrix} +\begin{array}{l} +\{0\}^{112} \\ +\,\left\vert +\begin{matrix} +\small\;\mathcal{S}_0[576,688) \\ +\small\;\mathcal{S}_1[464,576) \\ +\small\;\mathcal{S}_2[352,464) +\end{matrix} +\right. +\end{array} +\begin{matrix} +\quad\Large\Vert\quad \\ +\small\vphantom{a} \\ +\small\vphantom{a} \\ +\small\vphantom{a} +\end{matrix} +\begin{array}{l} +\{0\}^{112} \\ +\,\left\vert +\begin{matrix} +\small\vphantom{a} \\ +\small\;\mathcal{S}_1[576,688) \\ +\small\;\mathcal{S}_2[464,576) +\end{matrix} +\right. +\end{array}$$ + +19c1c6bc23651316344767f1a5d4ddf59ac6df34: $$\widetilde\beta_2$$ + +5e0876714bfa1b5a534e9d7b20a5c455772684fa: $$(A_3\,\Vert\,D_2\,\Vert\,\gamma_3)$$ + +02bcb5607aa1b2f7b26c009e079f35c971a96125: $$\begin{array}{l} +(A_3\,\Vert\,D_2\,\Vert\,\gamma_3) \\ +\,\left\vert +\begin{matrix} +\small\vphantom{a} \\ +\small\vphantom{a} \\ +\small\vphantom{a} \\ +\small\;\mathcal{S}_2[0,112) +\end{matrix} +\right. +\end{array} +\begin{matrix} +\quad\Large\Vert\quad \\ +\small\vphantom{a} \\ +\small\vphantom{a} \\ +\small\vphantom{a} \\ +\small\vphantom{a} +\end{matrix} +\begin{array}{l} +(\{0\}^{94}\,\Vert\,\{0\}^{2}\,\Vert\,\mathcal{id}_{\mathsf{SURB}}\,\Vert\,\{0\}^{128}) \\ +\,\left\vert +\begin{array}{l} +\small\vphantom{a} \\ +\small\vphantom{a} \\ +\small\;\mathcal{S}_3[0,240) \\ +\small\;\mathcal{S}_2[112,352) +\end{array} +\right. +\end{array} +\begin{matrix} +\quad\Large\Vert\quad \\ +\small\vphantom{a} \\ +\small\vphantom{a} \\ +\small\vphantom{a} \\ +\small\vphantom{a} +\end{matrix} +\begin{array}{l} +\{0\}^{112} \\ +\,\left\vert +\begin{matrix} +\small\;\mathcal{S}_0[576,688) \\ +\small\;\mathcal{S}_1[464,576) \\ +\small\;\enclose{horizontalstrike}{\mathcal{S}_2[352,464)} \\ +\small\;\enclose{horizontalstrike}{\mathcal{S}_2[352,464)} +\end{matrix} +\right. +\end{array} +\begin{matrix} +\quad\Large\Vert\quad \\ +\small\vphantom{a} \\ +\small\vphantom{a} \\ +\small\vphantom{a} \\ +\small\vphantom{a} +\end{matrix} +\begin{array}{l} +\{0\}^{112} \\ +\,\left\vert +\begin{matrix} +\small\vphantom{a} \\ +\small\;\mathcal{S}_1[576,688) \\ +\small\;\enclose{horizontalstrike}{\mathcal{S}_2[464,576)} \\ +\small\;\enclose{horizontalstrike}{\mathcal{S}_2[464,576)} +\end{matrix} +\right. +\end{array}$$ + +3922fb02900c6a34d2adab82c56611dfe15668e1: $$\beta_2$$ + +a468860c4880806742acf3981cd5888d46a9ab3f: $$\begin{array}{l} +(A_3\,\Vert\,D_2\,\Vert\,\gamma_3) \\ +\,\left\vert +\begin{matrix} +\small\vphantom{a} \\ +\small\;\mathcal{S}_2[0,112) +\end{matrix} +\right. +\end{array} +\begin{matrix} +\quad\Large\Vert\quad \\ +\small\vphantom{a} \\ +\small\vphantom{a} +\end{matrix} +\begin{array}{l} +(\{0\}^{94}\,\Vert\,\{0\}^{2}\,\Vert\,\mathcal{id}_{\mathsf{SURB}}\,\Vert\,\{0\}^{128}) \\ +\,\left\vert +\begin{array}{l} +\small\;\mathcal{S}_3[0,240) \\ +\small\;\mathcal{S}_2[112,352) +\end{array} +\right. +\end{array} +\begin{matrix} +\quad\Large\Vert\quad \\ +\small\vphantom{a} \\ +\small\vphantom{a} +\end{matrix} +\begin{array}{l} +\{0\}^{112} \\ +\,\left\vert +\begin{matrix} +\small\;\mathcal{S}_0[576,688) \\ +\small\;\mathcal{S}_1[464,576) +\end{matrix} +\right. +\end{array} +\begin{matrix} +\quad\Large\Vert\quad \\ +\small\vphantom{a} \\ +\small\vphantom{a} +\end{matrix} +\begin{array}{l} +\{0\}^{112} \\ +\,\left\vert +\begin{matrix} +\small\vphantom{a} \\ +\small\;\mathcal{S}_1[576,688) +\end{matrix} +\right. +\end{array}$$ + +98a7235f6736abdc9743dde93fd7bcf8abc986de: $$\beta_2$$ + +8d52fa299952b6bb4716f434afe457d66e2ac1a6: $$(A_2\,\Vert\,D_1\,\Vert\,\gamma_2)$$ + +4ea1ff84f86dc9737ca7573716fc40abdbd4b60f: $$\begin{array}{l} +(A_3\,\Vert\,D_2\,\Vert\,\gamma_3) \\ +\,\left\vert +\begin{matrix} +\small\vphantom{a} \\ +\small\;\mathcal{S}_2[0,112) +\end{matrix} +\right. +\end{array} +\begin{matrix} +\quad\Large\Vert\quad \\ +\small\vphantom{a} \\ +\small\vphantom{a} +\end{matrix} +\begin{array}{l} +(\{0\}^{94}\,\Vert\,\{0\}^{2}\,\Vert\,\mathcal{id}_{\mathsf{SURB}}\,\Vert\,\{0\}^{128}) \\ +\,\left\vert +\begin{array}{l} +\small\;\mathcal{S}_3[0,240) \\ +\small\;\mathcal{S}_2[112,352) +\end{array} +\right. +\end{array} +\begin{matrix} +\quad\Large\Vert\quad \\ +\small\vphantom{a} \\ +\small\vphantom{a} +\end{matrix} +\begin{array}{l} +\{0\}^{112} \\ +\,\left\vert +\begin{matrix} +\small\;\mathcal{S}_0[576,688) \\ +\small\;\mathcal{S}_1[464,576) +\end{matrix} +\right. +\end{array} +\begin{matrix} +\quad\Large\Vert\quad \\ +\small\vphantom{a} \\ +\small\vphantom{a} +\end{matrix} +\begin{array}{l} +\{0\}^{112} \\ +\,\left\vert +\begin{matrix} +\small\vphantom{a} \\ +\small\;\mathcal{S}_1[576,688) +\end{matrix} +\right. +\end{array}$$ + +4a0e8e41b209e15e853d5f3e33f5fdf0d2976917: $$\mathcal{S}_1[0,576)$$ + +f4b28faa47fcd33870166aa1739ed6a17061967e: $$\begin{array}{l} +(A_2\,\Vert\,D_1\,\Vert\,\gamma_2) \\ +\,\left\vert +\begin{matrix} +\small\vphantom{a} \\ +\small\vphantom{a} \\ +\small\;\mathcal{S}_1[0,112) +\end{matrix} +\right. +\end{array} +\begin{matrix} +\quad\Large\Vert\quad \\ +\small\vphantom{a} \\ +\small\vphantom{a} \\ +\small\vphantom{a} +\end{matrix} +\begin{array}{l} +(A_3\,\Vert\,D_2\,\Vert\,\gamma_3) \\ +\,\left\vert +\begin{array}{l} +\small\vphantom{a} \\ +\small\;\mathcal{S}_2[0,112) \\ +\small\;\mathcal{S}_1[112,224) +\end{array} +\right. +\end{array} +\begin{matrix} +\quad\Large\Vert\quad \\ +\small\vphantom{a} \\ +\small\vphantom{a} \\ +\small\vphantom{a} +\end{matrix} +\begin{array}{l} +(\{0\}^{94}\,\Vert\,\{0\}^{2}\,\Vert\,\mathcal{id}_{\mathsf{SURB}}\,\Vert\,\{0\}^{128}) \\ +\,\left\vert +\begin{array}{l} +\small\;\mathcal{S}_3[0,240) \\ +\small\;\mathcal{S}_2[112,352) \\ +\small\;\mathcal{S}_1[224,464) +\end{array} +\right. +\end{array} +\begin{matrix} +\quad\Large\Vert\quad \\ +\small\vphantom{a} \\ +\small\vphantom{a} \\ +\small\vphantom{a} +\end{matrix} +\begin{array}{l} +\{0\}^{112} \\ +\,\left\vert +\begin{matrix} +\small\vphantom{a} \\ +\small\vphantom{a} \\ +\small\;\mathcal{S}_0[576,688) +\end{matrix} +\right. +\end{array}$$ + +10feeaadb6a21acd49f8c4f088e48cf8b3ffd748: $$\beta_1$$ + +1259ffe0859608dc49db6247534cbf2d3efc8d8c: $$\begin{array}{l} +(A_2\,\Vert\,D_1\,\Vert\,\gamma_2) \\ +\,\left\vert +\begin{matrix} +\small\vphantom{a} \\ +\small\vphantom{a} \\ +\small\;\mathcal{S}_1[0,112) +\end{matrix} +\right. +\end{array} +\begin{matrix} +\quad\Large\Vert\quad \\ +\small\vphantom{a} \\ +\small\vphantom{a} \\ +\small\vphantom{a} +\end{matrix} +\begin{array}{l} +(A_3\,\Vert\,D_2\,\Vert\,\gamma_3) \\ +\,\left\vert +\begin{array}{l} +\small\vphantom{a} \\ +\small\;\mathcal{S}_2[0,112) \\ +\small\;\mathcal{S}_1[112,224) +\end{array} +\right. +\end{array} +\begin{matrix} +\quad\Large\Vert\quad \\ +\small\vphantom{a} \\ +\small\vphantom{a} \\ +\small\vphantom{a} +\end{matrix} +\begin{array}{l} +(\{0\}^{94}\,\Vert\,\{0\}^{2}\,\Vert\,\mathcal{id}_{\mathsf{SURB}}\,\Vert\,\{0\}^{128}) \\ +\,\left\vert +\begin{array}{l} +\small\;\mathcal{S}_3[0,240) \\ +\small\;\mathcal{S}_2[112,352) \\ +\small\;\mathcal{S}_1[224,464) +\end{array} +\right. +\end{array} +\begin{matrix} +\quad\Large\Vert\quad \\ +\small\vphantom{a} \\ +\small\vphantom{a} \\ +\small\vphantom{a} +\end{matrix} +\begin{array}{l} +\{0\}^{112} \\ +\,\left\vert +\begin{matrix} +\small\;\mathcal{S}_0[576,688) \\ +\small\;\enclose{horizontalstrike}{\mathcal{S}_1[464,576)} \\ +\small\;\enclose{horizontalstrike}{\mathcal{S}_1[464,576)} +\end{matrix} +\right. +\end{array}$$ + +b7e9296b5dc39dcd62ece2ceef997c51197dfd76: $$\beta_1$$ + +cb06071980dc33931024f5026be56c8339fa46d1: $$\begin{matrix} +(A_2\,\Vert\,D_1\,\Vert\,\gamma_2) \\ +\small\vphantom{a} \\ +\small\vphantom{a} +\end{matrix} +\begin{matrix} +\quad\Large\Vert\quad \\ +\small\vphantom{a} \\ +\small\vphantom{a} +\end{matrix} +\begin{array}{l} +(A_3\,\Vert\,D_2\,\Vert\,\gamma_3) \\ +\,\left\vert +\begin{matrix} +\small\vphantom{a} \\ +\small\;\mathcal{S}_2[0,112) +\end{matrix} +\right. +\end{array} +\begin{matrix} +\quad\Large\Vert\quad \\ +\small\vphantom{a} \\ +\small\vphantom{a} +\end{matrix} +\begin{array}{l} +(\{0\}^{94}\,\Vert\,\{0\}^{2}\,\Vert\,\mathcal{id}_{\mathsf{SURB}}\,\Vert\,\{0\}^{128}) \\ +\,\left\vert +\begin{array}{l} +\small\;\mathcal{S}_3[0,240) \\ +\small\;\mathcal{S}_2[112,352) +\end{array} +\right. +\end{array} +\begin{matrix} +\quad\Large\Vert\quad \\ +\small\vphantom{a} \\ +\small\vphantom{a} +\end{matrix} +\begin{array}{l} +\{0\}^{112} \\ +\,\left\vert +\begin{matrix} +\small\;\mathcal{S}_0[576,688) \\ +\small\;\mathcal{S}_1[464,576) +\end{matrix} +\right. +\end{array}$$ + +4fee4c8aead7cb59360850db9fab86262acf1a5e: $$\widetilde\beta_1$$ + +2d2134af5fc9352587dc0c1dafe945e7328d6035: $$\begin{array}{l} +(A_2\,\Vert\,D_1\,\Vert\,\gamma_2) \\ +\,\left\vert +\begin{matrix} +\small\vphantom{a} \\ +\small\vphantom{a} \\ +\small\;\mathcal{S}_1[0,112) +\end{matrix} +\right. +\end{array} +\begin{matrix} +\quad\Large\Vert\quad \\ +\small\vphantom{a} \\ +\small\vphantom{a} \\ +\small\vphantom{a} +\end{matrix} +\begin{array}{l} +(A_3\,\Vert\,D_2\,\Vert\,\gamma_3) \\ +\,\left\vert +\begin{array}{l} +\small\vphantom{a} \\ +\small\;\mathcal{S}_2[0,112) \\ +\small\;\mathcal{S}_1[112,224) +\end{array} +\right. +\end{array} +\begin{matrix} +\quad\Large\Vert\quad \\ +\small\vphantom{a} \\ +\small\vphantom{a} \\ +\small\vphantom{a} +\end{matrix} +\begin{array}{l} +(\{0\}^{94}\,\Vert\,\{0\}^{2}\,\Vert\,\mathcal{id}_{\mathsf{SURB}}\,\Vert\,\{0\}^{128}) \\ +\,\left\vert +\begin{array}{l} +\small\;\mathcal{S}_3[0,240) \\ +\small\;\mathcal{S}_2[112,352) \\ +\small\;\mathcal{S}_1[224,464) +\end{array} +\right. +\end{array} +\begin{matrix} +\quad\Large\Vert\quad \\ +\small\vphantom{a} \\ +\small\vphantom{a} \\ +\small\vphantom{a} +\end{matrix} +\begin{array}{l} +\{0\}^{112} \\ +\,\left\vert +\begin{matrix} +\small\vphantom{a} \\ +\small\vphantom{a} \\ +\small\;\mathcal{S}_0[576,688) +\end{matrix} +\right. +\end{array}$$ + +6b141c9c8ef4d2edc78d8cfe29b9d8a0d8c81b53: $$(A_1\,\Vert\,D_0\,\Vert\,\gamma_1)$$ + +4c3eb7023f36051b6ec8c87bd4f9593fa573c8fc: $$\mathcal{S}_0[0,576)$$ + +95f711ecae576bf4097ba81dbfd12f139d44e067: $$\begin{matrix} +(A_1\,\Vert\,D_0\,\Vert\,\gamma_1) \\ +\small\vphantom{a} \\ +\small\vphantom{a} \\ +\small\vphantom{a} +\end{matrix} +\begin{matrix} +\quad\Large\Vert\quad \\ +\small\vphantom{a} \\ +\small\vphantom{a} \\ +\small\vphantom{a} +\end{matrix} +\begin{array}{l} +(A_2\,\Vert\,D_1\,\Vert\,\gamma_2) \\ +\,\left\vert +\begin{matrix} +\small\vphantom{a} \\ +\small\vphantom{a} \\ +\small\;\mathcal{S}_1[0,112) +\end{matrix} +\right. +\end{array} +\begin{matrix} +\quad\Large\Vert\quad \\ +\small\vphantom{a} \\ +\small\vphantom{a} \\ +\small\vphantom{a} +\end{matrix} +\begin{array}{l} +(A_3\,\Vert\,D_2\,\Vert\,\gamma_3) \\ +\,\left\vert +\begin{array}{l} +\small\vphantom{a} \\ +\small\;\mathcal{S}_2[0,112) \\ +\small\;\mathcal{S}_1[112,224) +\end{array} +\right. +\end{array} +\begin{matrix} +\quad\Large\Vert\quad \\ +\small\vphantom{a} \\ +\small\vphantom{a} \\ +\small\vphantom{a} +\end{matrix} +\begin{array}{l} +(\{0\}^{94}\,\Vert\,\{0\}^{2}\,\Vert\,\mathcal{id}_{\mathsf{SURB}}\,\Vert\,\{0\}^{128}) \\ +\,\left\vert +\begin{array}{l} +\small\;\mathcal{S}_3[0,240) \\ +\small\;\mathcal{S}_2[112,352) \\ +\small\;\mathcal{S}_1[224,464) +\end{array} +\right. +\end{array}$$ + +396a18ecfbeba4d28f8394ee1bc67d36407ec8d7: $$\widetilde\beta_0$$ + +2d93fc82879c2b260862c0db7a50b7456928922a: $$\begin{array}{l} +(A_1\,\Vert\,D_0\,\Vert\,\gamma_1) \\ +\,\left\vert +\begin{matrix} +\small\vphantom{a} \\ +\small\vphantom{a} \\ +\small\vphantom{a} \\ +\small\;\mathcal{S}_0[0,112) +\end{matrix} +\right. +\end{array} +\begin{matrix} +\quad\Large\Vert\quad \\ +\small\vphantom{a} \\ +\small\vphantom{a} \\ +\small\vphantom{a} \\ +\small\vphantom{a} +\end{matrix} +\begin{array}{l} +(A_2\,\Vert\,D_1\,\Vert\,\gamma_2) \\ +\,\left\vert +\begin{array}{l} +\small\vphantom{a} \\ +\small\vphantom{a} \\ +\small\;\mathcal{S}_1[0,112) \\ +\small\;\mathcal{S}_0[112,224) +\end{array} +\right. +\end{array} +\begin{matrix} +\quad\Large\Vert\quad \\ +\small\vphantom{a} \\ +\small\vphantom{a} \\ +\small\vphantom{a} \\ +\small\vphantom{a} +\end{matrix} +\begin{array}{l} +(A_3\,\Vert\,D_2\,\Vert\,\gamma_3) \\ +\,\left\vert +\begin{array}{l} +\small\vphantom{a} \\ +\small\;\mathcal{S}_2[0,112) \\ +\small\;\mathcal{S}_1[112,224) \\ +\small\;\mathcal{S}_0[224,336) +\end{array} +\right. +\end{array} +\begin{matrix} +\quad\Large\Vert\quad \\ +\small\vphantom{a} \\ +\small\vphantom{a} \\ +\small\vphantom{a} \\ +\small\vphantom{a} +\end{matrix} +\begin{array}{l} +(\{0\}^{94}\,\Vert\,\{0\}^{2}\,\Vert\,\mathcal{id}_{\mathsf{SURB}}\,\Vert\,\{0\}^{128}) \\ +\,\left\vert +\begin{array}{l} +\small\;\mathcal{S}_3[0,240) \\ +\small\;\mathcal{S}_2[112,352) \\ +\small\;\mathcal{S}_1[224,464) \\ +\small\;\mathcal{S}_0[336,576) +\end{array} +\right. +\end{array}$$ + +4ee96b101711d46d17d9f352525d16a8d4cbca47: $$\beta_0$$ + +e923388d6547284835806826e5000c40e1152e20: $$\begin{array}{l} +(A_2\,\Vert\,D_1\,\Vert\,\gamma_2) \\ +\,\left\vert +\begin{matrix} +\small\vphantom{a} \\ +\small\vphantom{a} \\ +\small\;\mathcal{S}_1[0,112) +\end{matrix} +\right. +\end{array} +\begin{matrix} +\quad\Large\Vert\quad \\ +\small\vphantom{a} \\ +\small\vphantom{a} \\ +\small\vphantom{a} +\end{matrix} +\begin{array}{l} +(A_3\,\Vert\,D_2\,\Vert\,\gamma_3) \\ +\,\left\vert +\begin{array}{l} +\small\vphantom{a} \\ +\small\;\mathcal{S}_2[0,112) \\ +\small\;\mathcal{S}_1[112,224) +\end{array} +\right. +\end{array} +\begin{matrix} +\quad\Large\Vert\quad \\ +\small\vphantom{a} \\ +\small\vphantom{a} \\ +\small\vphantom{a} +\end{matrix} +\begin{array}{l} +(\{0\}^{94}\,\Vert\,\{0\}^{2}\,\Vert\,\mathcal{id}_{\mathsf{SURB}}\,\Vert\,\{0\}^{128}) \\ +\,\left\vert +\begin{array}{l} +\small\;\mathcal{S}_3[0,240) \\ +\small\;\mathcal{S}_2[112,352) \\ +\small\;\mathcal{S}_1[224,464) +\end{array} +\right. +\end{array} +\begin{matrix} +\quad\Large\Vert\quad \\ +\small\vphantom{a} \\ +\small\vphantom{a} \\ +\small\vphantom{a} +\end{matrix} +\begin{array}{l} +\{0\}^{112} \\ +\,\left\vert +\begin{matrix} +\small\vphantom{a} \\ +\small\vphantom{a} \\ +\small\;\mathcal{S}_0[576,688) +\end{matrix} +\right. +\end{array}$$ + +1336e8828b80509dfd60da3b62b3fcf08a9fb9ab: $$\beta_1$$ + +48181c815eb41552774bdef5eb0568cc60eb517b: $$\begin{array}{l} +(A_1\,\Vert\,D_0\,\Vert\,\gamma_1) \\ +\,\left\vert +\begin{matrix} +\small\vphantom{a} \\ +\small\vphantom{a} \\ +\small\vphantom{a} \\ +\small\;\enclose{horizontalstrike}{\mathcal{S}_0[0,112)} \\ +\small\;\enclose{horizontalstrike}{\mathcal{S}_0[0,112)} +\end{matrix} +\right. +\end{array} +\begin{matrix} +\quad\Large\Vert\quad \\ +\small\vphantom{a} \\ +\small\vphantom{a} \\ +\small\vphantom{a} \\ +\small\vphantom{a} \\ +\small\vphantom{a} +\end{matrix} +\begin{array}{l} +(A_2\,\Vert\,D_1\,\Vert\,\gamma_2) \\ +\,\left\vert +\begin{array}{l} +\small\vphantom{a} \\ +\small\vphantom{a} \\ +\small\;\mathcal{S}_1[0,112) \\ +\small\;\enclose{horizontalstrike}{\mathcal{S}_0[112,224)} \\ +\small\;\enclose{horizontalstrike}{\mathcal{S}_0[112,224)} +\end{array} +\right. +\end{array} +\begin{matrix} +\quad\Large\Vert\quad \\ +\small\vphantom{a} \\ +\small\vphantom{a} \\ +\small\vphantom{a} \\ +\small\vphantom{a} \\ +\small\vphantom{a} +\end{matrix} +\begin{array}{l} +(A_3\,\Vert\,D_2\,\Vert\,\gamma_3) \\ +\,\left\vert +\begin{array}{l} +\small\vphantom{a} \\ +\small\;\mathcal{S}_2[0,112) \\ +\small\;\mathcal{S}_1[112,224) \\ +\small\;\enclose{horizontalstrike}{\mathcal{S}_0[224,336)} \\ +\small\;\enclose{horizontalstrike}{\mathcal{S}_0[224,336)} +\end{array} +\right. +\end{array} +\begin{matrix} +\quad\Large\Vert\quad \\ +\small\vphantom{a} \\ +\small\vphantom{a} \\ +\small\vphantom{a} \\ +\small\vphantom{a} \\ +\small\vphantom{a} +\end{matrix} +\begin{array}{l} +(\{0\}^{94}\,\Vert\,\{0\}^{2}\,\Vert\,\mathcal{id}_{\mathsf{SURB}}\,\Vert\,\{0\}^{128}) \\ +\,\left\vert +\begin{array}{l} +\small\;\mathcal{S}_3[0,240) \\ +\small\;\mathcal{S}_2[112,352) \\ +\small\;\mathcal{S}_1[224,464) \\ +\small\;\enclose{horizontalstrike}{\mathcal{S}_0[336,576)} \\ +\small\;\enclose{horizontalstrike}{\mathcal{S}_0[336,576)} +\end{array} +\right. +\end{array} +\begin{matrix} +\quad\Large\Vert\quad \\ +\small\vphantom{a} \\ +\small\vphantom{a} \\ +\small\vphantom{a} \\ +\small\vphantom{a} \\ +\small\vphantom{a} +\end{matrix} +\begin{array}{l} +\{0\}^{112} \\ +\,\left\vert +\begin{matrix} +\small\vphantom{a} \\ +\small\vphantom{a} \\ +\small\vphantom{a} \\ +\small\vphantom{a} \\ +\small\;\mathcal{S}_0[576,688) +\end{matrix} +\right. +\end{array}$$ + +bee0927ce9d9bec2f7cd28f0f9da2b2d2a7e9784: $$\mathcal{B}_0=(A_{1}\,\Vert\,D_0\,\Vert\,\gamma_{1})\;\Vert\;\beta_{1}$$ + +5422f16f25dfee2edbfd8dac7ab352a4d4ee63f5: $$\begin{array}{l} +(A_1\,\Vert\,D_0\,\Vert\,\gamma_1) \\ +\,\left\vert +\begin{matrix} +\small\vphantom{a} \\ +\small\vphantom{a} \\ +\small\vphantom{a} \\ +\small\;\mathcal{S}_0[0,112) +\end{matrix} +\right. +\end{array} +\begin{matrix} +\quad\Large\Vert\quad \\ +\small\vphantom{a} \\ +\small\vphantom{a} \\ +\small\vphantom{a} \\ +\small\vphantom{a} +\end{matrix} +\begin{array}{l} +(A_2\,\Vert\,D_1\,\Vert\,\gamma_2) \\ +\,\left\vert +\begin{array}{l} +\small\vphantom{a} \\ +\small\vphantom{a} \\ +\small\;\mathcal{S}_1[0,112) \\ +\small\;\mathcal{S}_0[112,224) +\end{array} +\right. +\end{array} +\begin{matrix} +\quad\Large\Vert\quad \\ +\small\vphantom{a} \\ +\small\vphantom{a} \\ +\small\vphantom{a} \\ +\small\vphantom{a} +\end{matrix} +\begin{array}{l} +(A_3\,\Vert\,D_2\,\Vert\,\gamma_3) \\ +\,\left\vert +\begin{array}{l} +\small\vphantom{a} \\ +\small\;\mathcal{S}_2[0,112) \\ +\small\;\mathcal{S}_1[112,224) \\ +\small\;\mathcal{S}_0[224,336) +\end{array} +\right. +\end{array} +\begin{matrix} +\quad\Large\Vert\quad \\ +\small\vphantom{a} \\ +\small\vphantom{a} \\ +\small\vphantom{a} \\ +\small\vphantom{a} +\end{matrix} +\begin{array}{l} +(\{0\}^{94}\,\Vert\,\{0\}^{2}\,\Vert\,\mathcal{id}_{\mathsf{SURB}}\,\Vert\,\{0\}^{128}) \\ +\,\left\vert +\begin{array}{l} +\small\;\mathcal{S}_3[0,240) \\ +\small\;\mathcal{S}_2[112,352) \\ +\small\;\mathcal{S}_1[224,464) \\ +\small\;\mathcal{S}_0[336,576) +\end{array} +\right. +\end{array}$$ + +927cff42bb522dc4a59050d609b8050ae26ba54d: $$\beta_0$$ + +0bf6dc4be8bee7c2f17488bcedeb03c1ba79247c: $$\mathcal{S}_0[0,688)$$ + +0ac2b2e81d6129cf46ed93866607f36c7c514b18: $$\{0\}^{112}$$ + +769c92dffdd3a0e4004b37cb42492cb7339b7d6c: $$\begin{matrix} +(A_1\,\Vert\,D_0\,\Vert\,\gamma_1) \\ +\small\vphantom{a} \\ +\small\vphantom{a} \\ +\small\vphantom{a} +\end{matrix} +\begin{matrix} +\quad\Large\Vert\quad \\ +\small\vphantom{a} \\ +\small\vphantom{a} \\ +\small\vphantom{a} +\end{matrix} +\begin{array}{l} +(A_2\,\Vert\,D_1\,\Vert\,\gamma_2) \\ +\,\left\vert +\begin{matrix} +\small\vphantom{a} \\ +\small\vphantom{a} \\ +\small\;\mathcal{S}_1[0,112) +\end{matrix} +\right. +\end{array} +\begin{matrix} +\quad\Large\Vert\quad \\ +\small\vphantom{a} \\ +\small\vphantom{a} \\ +\small\vphantom{a} +\end{matrix} +\begin{array}{l} +(A_3\,\Vert\,D_2\,\Vert\,\gamma_3) \\ +\,\left\vert +\begin{array}{l} +\small\vphantom{a} \\ +\small\;\mathcal{S}_2[0,112) \\ +\small\;\mathcal{S}_1[112,224) +\end{array} +\right. +\end{array} +\begin{matrix} +\quad\Large\Vert\quad \\ +\small\vphantom{a} \\ +\small\vphantom{a} \\ +\small\vphantom{a} +\end{matrix} +\begin{array}{l} +(\{0\}^{94}\,\Vert\,\{0\}^{2}\,\Vert\,\mathcal{id}_{\mathsf{SURB}}\,\Vert\,\{0\}^{128}) \\ +\,\left\vert +\begin{array}{l} +\small\;\mathcal{S}_3[0,240) \\ +\small\;\mathcal{S}_2[112,352) \\ +\small\;\mathcal{S}_1[224,464) +\end{array} +\right. +\end{array} +\begin{matrix} +\quad\Large\Vert\quad \\ +\small\vphantom{a} \\ +\small\vphantom{a} \\ +\small\vphantom{a} +\end{matrix} +\begin{array}{l} +\{0\}^{112} \\ +\,\left\vert +\begin{matrix} +\small\vphantom{a} \\ +\small\vphantom{a} \\ +\small\;\mathcal{S}_0[576,688) +\end{matrix} +\right. +\end{array}$$ + +c0a9ad2842b61b72d8000c7c39460295a233b98e: $$\begin{matrix} +\mathcal{B}_i \; = \ \\ +\vphantom{a} \\ +\vphantom{a} +\end{matrix} +\begin{array}{l} +(A_{i+1}\,\Vert\,D_i\,\Vert\,\gamma_{i+1}) \\ +\,\left\vert +\begin{matrix} +\small\enclose{horizontalstrike}{\mathcal{S}_i[0,112)} \\ +\small\enclose{horizontalstrike}{\mathcal{S}_i[0,112)} +\end{matrix} +\right. +\end{array} +\begin{matrix} +\quad\Large\Vert\quad \\ +\vphantom{a} \\ +\vphantom{a} +\end{matrix} +\begin{array}{l} +\mathsf{trunc}(\beta_{i+1}) \\ +\,\left\vert +\begin{matrix} +\small\enclose{horizontalstrike}{\mathcal{S}_i[112,576)} \\ +\small\enclose{horizontalstrike}{\mathcal{S}_i[112,576)} +\end{matrix} +\right. +\end{array} +\begin{matrix} +\quad\Large\Vert\quad \\ +\vphantom{a} \\ +\vphantom{a} +\end{matrix} +\begin{array}{l} +\{0\}^{112} \\ +\,\left\vert +\begin{matrix} +\small\vphantom{a} \\ +\small\;\mathcal{S}_i[576,688) +\end{matrix} +\right. +\end{array}\color{blue}$$ + +9f15adb3ecad75b797015f0eb511043a3d549565: $$\mathrm{The\ received\ } \beta_i\mathrm{\ is:}$$ + +5faa78e36335d3861ebfb3de8948c0abe2dc9569: $$\begin{matrix} +\beta_i \; = \ \\ +\vphantom{a} +\end{matrix} +\begin{array}{l} +(A_{i+1}\,\Vert\,D_i\,\Vert\,\gamma_{i+1}) \\ +\,\left\vert +\begin{matrix} +\small\;\mathcal{S}_i[0,112) +\end{matrix} +\right. +\end{array} +\begin{matrix} +\quad\Large\Vert\quad \\ +\vphantom{a} +\end{matrix} +\begin{array}{l} +\mathsf{trunc}(\beta_{i+1}) \\ +\,\left\vert +\begin{matrix} +\small\;\mathcal{S}_i[112,576) +\end{matrix} +\right. +\end{array}\color{blue}$$ + +355d1dcf119c29e03ba39f39ac87e0ac64c9b126: $$\mathrm{Before\ decrypting\ }\beta_i\mathrm{\ using\ }\mathcal{S}_i\mathrm{,\ we\ first\ append\ }\{0\}^{112}\mathrm{\ to\ it.\ Then\ we\ perform\ XOR\ operation\ +using\ }\mathcal{S}_i[0,688)\mathrm{:}$$ + +97321a713721b6c58ecdc347a78ae54e456fd993: $$\mathrm{which\ is\ nothing\ more\ than\ }(\beta_i\;\Vert\;\{0\}^{112})\;\oplus\;\mathcal{S}_i[0,688)\mathrm{:}$$ + +7cac66a64ca50ab6dce207204d4359fffbf5c4a9: $$\begin{matrix} +\mathcal{B}_i \; = \ \\ +\small\vphantom{a} +\end{matrix} +\begin{matrix} +(A_{i+1}\,\Vert\,D_i\,\Vert\,\gamma_{i+1}) \\ +\small\vphantom{a} +\end{matrix} +\begin{matrix} +\;\Large\Vert\; \\ +\vphantom{a} +\end{matrix} +\begin{matrix} +\mathsf{trunc}(\beta_{i+1}) \\ +\small\vphantom{a} +\end{matrix} +\begin{matrix} +\;\Large\Vert\; \\ +\vphantom{a} +\end{matrix} +\begin{array}{l} +\{0\}^{112} \\ +\,\left\vert +\begin{matrix} +\small\;\mathcal{S}_i[576,688) +\end{matrix} +\right. +\end{array} +\begin{matrix} +\; = \; \\ +\small\vphantom{a} +\end{matrix} +\begin{matrix} +(A_{i+1}\,\Vert\,D_i\,\Vert\,\gamma_{i+1}) \\ +\small\vphantom{a} +\end{matrix} +\begin{matrix} +\;\Large\Vert\; \\ +\vphantom{a} +\end{matrix} +\begin{matrix} +\beta_{i+1} \\ +\small\vphantom{a} +\end{matrix}$$ + +8eb8f0528da56fde1ac85b96d44f70b450b21a22: $$\mathrm{Intuition}$$ + +17712d4978a261c439b29c4bc9efd32255443f46: $$\beta_0 = ((A_1\,\Vert\,D_0\,\Vert\,\gamma_1)\;\Vert\;\mathsf{trunc}_{[0,464)}(\beta_1))\oplus\mathcal{S}_0[0,576)$$ + +b324ab9424d5fc9987be52104ca4ed914e3b3b52: $$\mathrm{which\ can\ be\ written\ as:}$$ + +c61223dd4dfedd0c1fd45a103ed223faa72054ba: $$\beta_i = ((A_{i+1}\,\Vert\,D_i\,\Vert\,\gamma_{i+1})\;\Vert\;\mathsf{trunc}_{[0,464)}(\beta_{i+1}))\oplus\mathcal{S}_i[0,576)$$ + +975629696fb9a7375aba2ba901d63a6e1e6096d9: $$\begin{array}{l} +(A_3\,\Vert\,D_2\,\Vert\,\gamma_3) \\ +\,\left\vert +\begin{matrix} +\small\vphantom{a} \\ +\small\;\mathcal{S}_2[0,112) +\end{matrix} +\right. +\end{array} +\begin{matrix} +\quad\Large\Vert\quad \\ +\small\vphantom{a} \\ +\small\vphantom{a} +\end{matrix} +\begin{array}{l} +(\{0\}^{94}\,\Vert\,\{0\}^{2}\,\Vert\,\mathcal{id}_{\mathsf{SURB}}\,\Vert\,\{0\}^{128}) \\ +\,\left\vert +\begin{array}{l} +\small\;\mathcal{S}_3[0,240) \\ +\small\;\mathcal{S}_2[112,352) +\end{array} +\right. +\end{array} +\begin{matrix} +\quad\Large\Vert\quad \\ +\small\vphantom{a} \\ +\small\vphantom{a} +\end{matrix} +\begin{array}{l} +\{0\}^{112} \\ +\,\left\vert +\begin{matrix} +\small\;\mathcal{S}_0[576,688) \\ +\small\;\mathcal{S}_1[464,576) +\end{matrix} +\right. +\end{array} +\begin{matrix} +\quad\Large\Vert\quad \\ +\small\vphantom{a} \\ +\small\vphantom{a} +\end{matrix} +\begin{array}{l} +\{0\}^{112} \\ +\,\left\vert +\begin{matrix} +\small\vphantom{a} \\ +\small\;\mathcal{S}_1[576,688) +\end{matrix} +\right. +\end{array}$$ + +945b476b9c50ca1789c642b70edc74f2afb6e207: $$\beta_2$$ + +a1481789839b12d880b0396bb26bd0851a777108: $$\begin{array}{l} +(A_2\,\Vert\,D_1\,\Vert\,\gamma_2) \\ +\,\left\vert +\begin{matrix} +\small\vphantom{a} \\ +\small\vphantom{a} \\ +\small\;\enclose{horizontalstrike}{\mathcal{S}_1[0,112)} \\ +\small\;\enclose{horizontalstrike}{\mathcal{S}_1[0,112)} +\end{matrix} +\right. +\end{array} +\begin{matrix} +\quad\Large\Vert\quad \\ +\small\vphantom{a} \\ +\small\vphantom{a} \\ +\small\vphantom{a} \\ +\small\vphantom{a} +\end{matrix} +\begin{array}{l} +(A_3\,\Vert\,D_2\,\Vert\,\gamma_3) \\ +\,\left\vert +\begin{array}{l} +\small\vphantom{a} \\ +\small\;\mathcal{S}_2[0,112) \\ +\small\;\enclose{horizontalstrike}{\mathcal{S}_1[112,224)} \\ +\small\;\enclose{horizontalstrike}{\mathcal{S}_1[112,224)} +\end{array} +\right. +\end{array} +\begin{matrix} +\quad\Large\Vert\quad \\ +\small\vphantom{a} \\ +\small\vphantom{a} \\ +\small\vphantom{a} \\ +\small\vphantom{a} +\end{matrix} +\begin{array}{l} +(\{0\}^{94}\,\Vert\,\{0\}^{2}\,\Vert\,\mathcal{id}_{\mathsf{SURB}}\,\Vert\,\{0\}^{128}) \\ +\,\left\vert +\begin{array}{l} +\small\;\mathcal{S}_3[0,240) \\ +\small\;\mathcal{S}_2[112,352) \\ +\small\;\enclose{horizontalstrike}{\mathcal{S}_1[224,464)} \\ +\small\;\enclose{horizontalstrike}{\mathcal{S}_1[224,464)} +\end{array} +\right. +\end{array} +\begin{matrix} +\quad\Large\Vert\quad \\ +\small\vphantom{a} \\ +\small\vphantom{a} \\ +\small\vphantom{a} \\ +\small\vphantom{a} +\end{matrix} +\begin{array}{l} +\{0\}^{112} \\ +\,\left\vert +\begin{matrix} +\small\vphantom{a} \\ +\small\vphantom{a} \\ +\small\;\mathcal{S}_0[576,688) \\ +\small\;\mathcal{S}_1[464,576) +\end{matrix} +\right. +\end{array} +\begin{matrix} +\quad\Large\Vert\quad \\ +\small\vphantom{a} \\ +\small\vphantom{a} \\ +\small\vphantom{a} \\ +\small\vphantom{a} +\end{matrix} +\begin{array}{l} +\{0\}^{112} \\ +\,\left\vert +\begin{matrix} +\small\vphantom{a} \\ +\small\vphantom{a} \\ +\small\vphantom{a} \\ +\small\;\mathcal{S}_1[576,688) +\end{matrix} +\right. +\end{array}$$ + +c5ea628856429f6fb0f62e2c93effd50727b4669: $$\mathcal{B}_1=(A_{2}\,\Vert\,D_1\,\Vert\,\gamma_{2})\;\Vert\;\beta_{2}$$ + +4eca15091b9bada98145d198a2d146ca3fb20cfa: $$\begin{matrix} +(A_2\,\Vert\,D_1\,\Vert\,\gamma_2) \\ +\small\vphantom{a} \\ +\small\vphantom{a} +\end{matrix} +\begin{matrix} +\quad\Large\Vert\quad \\ +\small\vphantom{a} \\ +\small\vphantom{a} +\end{matrix} +\begin{array}{l} +(A_3\,\Vert\,D_2\,\Vert\,\gamma_3) \\ +\,\left\vert +\begin{array}{l} +\small\vphantom{a} \\ +\small\;\mathcal{S}_2[0,112) +\end{array} +\right. +\end{array} +\begin{matrix} +\quad\Large\Vert\quad \\ +\small\vphantom{a} \\ +\small\vphantom{a} +\end{matrix} +\begin{array}{l} +(\{0\}^{94}\,\Vert\,\{0\}^{2}\,\Vert\,\mathcal{id}_{\mathsf{SURB}}\,\Vert\,\{0\}^{128}) \\ +\,\left\vert +\begin{array}{l} +\small\;\mathcal{S}_3[0,240) \\ +\small\;\mathcal{S}_2[112,352) +\end{array} +\right. +\end{array} +\begin{matrix} +\quad\Large\Vert\quad \\ +\small\vphantom{a} \\ +\small\vphantom{a} +\end{matrix} +\begin{array}{l} +\{0\}^{112} \\ +\,\left\vert +\begin{matrix} +\small\;\mathcal{S}_0[576,688) \\ +\small\;\mathcal{S}_1[464,576) +\end{matrix} +\right. +\end{array} +\begin{matrix} +\quad\Large\Vert\quad \\ +\small\vphantom{a} \\ +\small\vphantom{a} +\end{matrix} +\begin{array}{l} +\{0\}^{112} \\ +\,\left\vert +\begin{matrix} +\small\vphantom{a} \\ +\small\;\mathcal{S}_1[576,688) +\end{matrix} +\right. +\end{array}$$ + +1241226dc817c07e6304b4ab0f592c7ea6758989: $$\beta_1$$ + +fd604f83b2a0bc7c2ddb010ace6f2bbbf3607a7c: $$\mathcal{S}_1[0,688)$$ + +7288c1c12927904d88052d13d4caee78749f3abf: $$\beta_1 = ((A_2\,\Vert\,D_1\,\Vert\,\gamma_2)\;\Vert\;\mathsf{trunc}_{[0,464)}(\beta_2))\oplus\mathcal{S}_1[0,576)$$ + +d1f38c5f25d04d9c442ab8cdf8a11aee64301790: $$\{0\}^{112}$$ + +481bb43d5ba683727d0ec13d968baa32ccaa010f: $$\begin{array}{l} +(A_2\,\Vert\,D_1\,\Vert\,\gamma_2) \\ +\,\left\vert +\begin{matrix} +\small\vphantom{a} \\ +\small\vphantom{a} \\ +\small\;\mathcal{S}_1[0,112) +\end{matrix} +\right. +\end{array} +\begin{matrix} +\quad\Large\Vert\quad \\ +\small\vphantom{a} \\ +\small\vphantom{a} \\ +\small\vphantom{a} +\end{matrix} +\begin{array}{l} +(A_3\,\Vert\,D_2\,\Vert\,\gamma_3) \\ +\,\left\vert +\begin{array}{l} +\small\vphantom{a} \\ +\small\;\mathcal{S}_2[0,112) \\ +\small\;\mathcal{S}_1[112,224) +\end{array} +\right. +\end{array} +\begin{matrix} +\quad\Large\Vert\quad \\ +\small\vphantom{a} \\ +\small\vphantom{a} \\ +\small\vphantom{a} +\end{matrix} +\begin{array}{l} +(\{0\}^{94}\,\Vert\,\{0\}^{2}\,\Vert\,\mathcal{id}_{\mathsf{SURB}}\,\Vert\,\{0\}^{128}) \\ +\,\left\vert +\begin{array}{l} +\small\;\mathcal{S}_3[0,240) \\ +\small\;\mathcal{S}_2[112,352) \\ +\small\;\mathcal{S}_1[224,464) +\end{array} +\right. +\end{array} +\begin{matrix} +\quad\Large\Vert\quad \\ +\small\vphantom{a} \\ +\small\vphantom{a} \\ +\small\vphantom{a} +\end{matrix} +\begin{array}{l} +\{0\}^{112} \\ +\,\left\vert +\begin{matrix} +\small\vphantom{a} \\ +\small\vphantom{a} \\ +\small\;\mathcal{S}_0[576,688) +\end{matrix} +\right. +\end{array}$$ + +8d485fb63b6942804802c6a3c85306e80ca8cc0d: $$\begin{array}{l} +(\{0\}^{94}\,\Vert\,\{0\}^{2}\,\Vert\,\mathcal{id}_{\mathsf{SURB}}\,\Vert\,\{0\}^{128}) \\ +\,\left\vert +\begin{matrix} +\small\vphantom{a} \\ +\small\vphantom{a} \\ +\small\;\mathcal{S}_3[0,240) +\end{matrix} +\right. +\end{array} +\begin{matrix} +\quad\Large\Vert\quad \\ +\small\vphantom{a} \\ +\small\vphantom{a} \\ +\small\vphantom{a} +\end{matrix} +\begin{array}{l} +\{0\}^{112} \\ +\,\left\vert +\begin{matrix} +\small\;\mathcal{S}_0[576,688) \\ +\small\;\mathcal{S}_1[464,576) \\ +\small\;\mathcal{S}_2[352,464) +\end{matrix} +\right. +\end{array} +\begin{matrix} +\quad\Large\Vert\quad \\ +\small\vphantom{a} \\ +\small\vphantom{a} \\ +\small\vphantom{a} +\end{matrix} +\begin{array}{l} +\{0\}^{112} \\ +\,\left\vert +\begin{matrix} +\small\vphantom{a} \\ +\small\;\mathcal{S}_1[576,688) \\ +\small\;\mathcal{S}_2[464,576) +\end{matrix} +\right. +\end{array} +\begin{matrix} +\quad\Large\Vert\quad \\ +\small\vphantom{a} \\ +\small\vphantom{a} \\ +\small\vphantom{a} +\end{matrix} +\begin{array}{l} +\{0\}^{112} \\ +\,\left\vert +\begin{matrix} +\small\vphantom{a} \\ +\small\vphantom{a} \\ +\small\;\mathcal{S}_2[576,688) +\end{matrix} +\right. +\end{array}$$ + +b4f4e6acd2a44d5f589606e3cc9e911c2afcc9ab: $$\begin{array}{l} +(A_3\,\Vert\,D_2\,\Vert\,\gamma_3) \\ +\,\left\vert +\begin{matrix} +\small\vphantom{a} \\ +\small\;\mathcal{S}_2[0,112) +\end{matrix} +\right. +\end{array} +\begin{matrix} +\quad\Large\Vert\quad \\ +\small\vphantom{a} \\ +\small\vphantom{a} +\end{matrix} +\begin{array}{l} +(\{0\}^{94}\,\Vert\,\{0\}^{2}\,\Vert\,\mathcal{id}_{\mathsf{SURB}}\,\Vert\,\{0\}^{128}) \\ +\,\left\vert +\begin{array}{l} +\small\;\mathcal{S}_3[0,240) \\ +\small\;\mathcal{S}_2[112,352) +\end{array} +\right. +\end{array} +\begin{matrix} +\quad\Large\Vert\quad \\ +\small\vphantom{a} \\ +\small\vphantom{a} +\end{matrix} +\begin{array}{l} +\{0\}^{112} \\ +\,\left\vert +\begin{matrix} +\small\;\mathcal{S}_0[576,688) \\ +\small\;\mathcal{S}_1[464,576) +\end{matrix} +\right. +\end{array} +\begin{matrix} +\quad\Large\Vert\quad \\ +\small\vphantom{a} \\ +\small\vphantom{a} +\end{matrix} +\begin{array}{l} +\{0\}^{112} \\ +\,\left\vert +\begin{matrix} +\small\vphantom{a} \\ +\small\;\mathcal{S}_1[576,688) +\end{matrix} +\right. +\end{array}$$ + +6294e89061757a3cdf73a3478fb877e9f70aed15: $$\beta_3$$ + +ec0be150d40416a9b30d92562366043e973ebea2: $$\begin{array}{l} +(A_3\,\Vert\,D_2\,\Vert\,\gamma_3) \\ +\,\left\vert +\begin{array}{l} +\small\vphantom{a} \\ +\small\;\enclose{horizontalstrike}{\mathcal{S}_2[0,112)} \\ +\small\;\enclose{horizontalstrike}{\mathcal{S}_2[0,112)} +\end{array} +\right. +\end{array} +\begin{matrix} +\quad\Large\Vert\quad \\ +\small\vphantom{a} \\ +\small\vphantom{a} \\ +\small\vphantom{a} +\end{matrix} +\begin{array}{l} +(\{0\}^{94}\,\Vert\,\{0\}^{2}\,\Vert\,\mathcal{id}_{\mathsf{SURB}}\,\Vert\,\{0\}^{128}) \\ +\,\left\vert +\begin{array}{l} +\small\;\mathcal{S}_3[0,240) \\ +\small\;\enclose{horizontalstrike}{\mathcal{S}_2[112,352)} \\ +\small\;\enclose{horizontalstrike}{\mathcal{S}_2[112,352)} +\end{array} +\right. +\end{array} +\begin{matrix} +\quad\Large\Vert\quad \\ +\small\vphantom{a} \\ +\small\vphantom{a} \\ +\small\vphantom{a} +\end{matrix} +\begin{array}{l} +\{0\}^{112} \\ +\,\left\vert +\begin{matrix} +\small\;\mathcal{S}_0[576,688) \\ +\small\;\mathcal{S}_1[464,576) \\ +\small\;\mathcal{S}_2[352,464) +\end{matrix} +\right. +\end{array} +\begin{matrix} +\quad\Large\Vert\quad \\ +\small\vphantom{a} \\ +\small\vphantom{a} \\ +\small\vphantom{a} +\end{matrix} +\begin{array}{l} +\{0\}^{112} \\ +\,\left\vert +\begin{matrix} +\small\vphantom{a} \\ +\small\;\mathcal{S}_1[576,688) \\ +\small\;\mathcal{S}_2[464,576) +\end{matrix} +\right. +\end{array} +\begin{matrix} +\quad\Large\Vert\quad \\ +\small\vphantom{a} \\ +\small\vphantom{a} \\ +\small\vphantom{a} +\end{matrix} +\begin{array}{l} +\{0\}^{112} \\ +\,\left\vert +\begin{matrix} +\small\vphantom{a} \\ +\small\vphantom{a} \\ +\small\;\mathcal{S}_2[576,688) +\end{matrix} +\right. +\end{array}$$ + +4871e139d174c4312f621fb5bb4e702570af7d5e: $$\mathcal{B}_2=(A_{3}\,\Vert\,D_2\,\Vert\,\gamma_{3})\;\Vert\;\beta_{3}$$ + +2072818570b13f1efaeeff225b01c6a10045bd6d: $$\begin{matrix} +(A_3\,\Vert\,D_2\,\Vert\,\gamma_3) \\ +\small\vphantom{a} \\ +\small\vphantom{a} \\ +\small\vphantom{a} +\end{matrix} +\begin{matrix} +\quad\Large\Vert\quad \\ +\small\vphantom{a} \\ +\small\vphantom{a} \\ +\small\vphantom{a} +\end{matrix} +\begin{array}{l} +(\{0\}^{94}\,\Vert\,\{0\}^{2}\,\Vert\,\mathcal{id}_{\mathsf{SURB}}\,\Vert\,\{0\}^{128}) \\ +\,\left\vert +\begin{array}{l} +\small\vphantom{a} \\ +\small\vphantom{a} \\ +\small\;\mathcal{S}_3[0,240) +\end{array} +\right. +\end{array} +\begin{matrix} +\quad\Large\Vert\quad \\ +\small\vphantom{a} \\ +\small\vphantom{a} \\ +\small\vphantom{a} +\end{matrix} +\begin{array}{l} +\{0\}^{112} \\ +\,\left\vert +\begin{matrix} +\small\;\mathcal{S}_0[576,688) \\ +\small\;\mathcal{S}_1[464,576) \\ +\small\;\mathcal{S}_2[352,464) +\end{matrix} +\right. +\end{array} +\begin{matrix} +\quad\Large\Vert\quad \\ +\small\vphantom{a} \\ +\small\vphantom{a} \\ +\small\vphantom{a} +\end{matrix} +\begin{array}{l} +\{0\}^{112} \\ +\,\left\vert +\begin{matrix} +\small\vphantom{a} \\ +\small\;\mathcal{S}_1[576,688) \\ +\small\;\mathcal{S}_2[464,576) +\end{matrix} +\right. +\end{array} +\begin{matrix} +\quad\Large\Vert\quad \\ +\small\vphantom{a} \\ +\small\vphantom{a} \\ +\small\vphantom{a} +\end{matrix} +\begin{array}{l} +\{0\}^{112} \\ +\,\left\vert +\begin{matrix} +\small\vphantom{a} \\ +\small\vphantom{a} \\ +\small\;\mathcal{S}_2[576,688) +\end{matrix} +\right. +\end{array}$$ + +98bb20bdeba855d444acbb9ce7d8cd3197bc66f5: $$\mathcal{S}_2[0,688)$$ + +cdfb2d6eab74de94f596724d597f1f02167aa7f8: $$\beta_2 = ((A_3\,\Vert\,D_2\,\Vert\,\gamma_3)\;\Vert\;\mathsf{trunc}_{[0,464)}(\beta_3))\oplus\mathcal{S}_2[0,576)$$ + +393e91389730e91168f584bc179132d3f2511a87: $$\{0\}^{112}$$ + +9c3106a2087e9ad1b23a5796b0e37a1436485f14: $$\beta_2$$ + +382ae3fea18436e5e978ec228b80004f9b3c0e19: $$\begin{array}{l} +(\{0\}^{94}\,\Vert\,\{0\}^{2}\,\Vert\,\mathcal{id}_{\mathsf{SURB}}\,\Vert\,\{0\}^{128}) \\ +\,\left\vert +\begin{matrix} +\small\vphantom{a} \\ +\small\vphantom{a} \\ +\small\;\enclose{horizontalstrike}{\mathcal{S}_3[0,240)} \\ +\small\;\enclose{horizontalstrike}{\mathcal{S}_3[0,240)} +\end{matrix} +\right. +\end{array} +\begin{matrix} +\quad\Large\Vert\quad \\ +\small\vphantom{a} \\ +\small\vphantom{a} \\ +\small\vphantom{a} \\ +\small\vphantom{a} +\end{matrix} +\begin{array}{l} +\{0\}^{112} \\ +\,\left\vert +\begin{matrix} +\small\;\mathcal{S}_0[576,688) \\ +\small\;\mathcal{S}_1[464,576) \\ +\small\;\mathcal{S}_2[352,464) \\ +\small\;\mathcal{S}_3[240,352) +\end{matrix} +\right. +\end{array} +\begin{matrix} +\quad\Large\Vert\quad \\ +\small\vphantom{a} \\ +\small\vphantom{a} \\ +\small\vphantom{a} \\ +\small\vphantom{a} +\end{matrix} +\begin{array}{l} +\{0\}^{112} \\ +\,\left\vert +\begin{matrix} +\small\vphantom{a} \\ +\small\;\mathcal{S}_1[576,688) \\ +\small\;\mathcal{S}_2[464,576) \\ +\small\;\mathcal{S}_3[352,464) +\end{matrix} +\right. +\end{array} +\begin{matrix} +\quad\Large\Vert\quad \\ +\small\vphantom{a} \\ +\small\vphantom{a} \\ +\small\vphantom{a} \\ +\small\vphantom{a} +\end{matrix} +\begin{array}{l} +\{0\}^{112} \\ +\,\left\vert +\begin{matrix} +\small\vphantom{a} \\ +\small\vphantom{a} \\ +\small\;\mathcal{S}_2[576,688) \\ +\small\;\mathcal{S}_3[464,576) +\end{matrix} +\right. +\end{array} +\begin{matrix} +\quad\Large\Vert\quad \\ +\small\vphantom{a} \\ +\small\vphantom{a} \\ +\small\vphantom{a} \\ +\small\vphantom{a} +\end{matrix} +\begin{array}{l} +\{0\}^{112} \\ +\,\left\vert +\begin{matrix} +\small\vphantom{a} \\ +\small\vphantom{a} \\ +\small\vphantom{a} \\ +\small\;\mathcal{S}_3[576,688) +\end{matrix} +\right. +\end{array}$$ + +38fb8f27a22929ed16ac64889af9237fcf44c58f: $$\mathcal{B}_3=(\{0\}^{94}\,\Vert\,\{0\}^{2}\,\Vert\,\mathcal{id}_{\mathsf{SURB}}\,\Vert\,\{0\}^{128})\;\Vert\;(\mathsf{filler}\;\oplus\;\mathcal{S}_3[240,688)$$ + +8a9bc109a8091d3ac9b1a86c2e522c340b64018b: $$\begin{matrix} +(\{0\}^{94}\,\Vert\,\{0\}^{2}\,\Vert\,\mathcal{id}_{\mathsf{SURB}}\,\Vert\,\{0\}^{128}) \\ +\small\vphantom{a} \\ +\small\vphantom{a} \\ +\small\vphantom{a} \\ +\small\vphantom{a} +\end{matrix} +\begin{matrix} +\quad\Large\Vert\quad \\ +\small\vphantom{a} \\ +\small\vphantom{a} \\ +\small\vphantom{a} \\ +\small\vphantom{a} +\end{matrix} +\begin{array}{l} +\{0\}^{112} \\ +\,\left\vert +\begin{matrix} +\small\;\mathcal{S}_0[576,688) \\ +\small\;\mathcal{S}_1[464,576) \\ +\small\;\mathcal{S}_2[352,464) \\ +\small\;\mathcal{S}_3[240,352) +\end{matrix} +\right. +\end{array} +\begin{matrix} +\quad\Large\Vert\quad \\ +\small\vphantom{a} \\ +\small\vphantom{a} \\ +\small\vphantom{a} \\ +\small\vphantom{a} +\end{matrix} +\begin{array}{l} +\{0\}^{112} \\ +\,\left\vert +\begin{matrix} +\small\vphantom{a} \\ +\small\;\mathcal{S}_1[576,688) \\ +\small\;\mathcal{S}_2[464,576) \\ +\small\;\mathcal{S}_3[352,464) +\end{matrix} +\right. +\end{array} +\begin{matrix} +\quad\Large\Vert\quad \\ +\small\vphantom{a} \\ +\small\vphantom{a} \\ +\small\vphantom{a} \\ +\small\vphantom{a} +\end{matrix} +\begin{array}{l} +\{0\}^{112} \\ +\,\left\vert +\begin{matrix} +\small\vphantom{a} \\ +\small\vphantom{a} \\ +\small\;\mathcal{S}_2[576,688) \\ +\small\;\mathcal{S}_3[464,576) +\end{matrix} +\right. +\end{array} +\begin{matrix} +\quad\Large\Vert\quad \\ +\small\vphantom{a} \\ +\small\vphantom{a} \\ +\small\vphantom{a} \\ +\small\vphantom{a} +\end{matrix} +\begin{array}{l} +\{0\}^{112} \\ +\,\left\vert +\begin{matrix} +\small\vphantom{a} \\ +\small\vphantom{a} \\ +\small\vphantom{a} \\ +\small\;\mathcal{S}_3[576,688) +\end{matrix} +\right. +\end{array}$$ + +f5987f61849ccec30442d89d55f89ce7a62bb52c: $$\mathcal{S}_3[0,688)$$ + +ab0c8bed9007091e06ac0f767cb32f52f829d58c: $$\beta_3 = ((\{0\}^{94}\,\Vert\,\{0\}^{2}\,\Vert\,\mathcal{id}_{\mathsf{SURB}}\,\Vert\,\{0\}^{128})\;\oplus\;\mathcal{S}_3[0,240))\;\Vert\;\mathsf{filler}$$ + +5e75483f3186249bcf04cbb851d978e4bed502d1: $$\{0\}^{112}$$ + +3f3e7e688bdf753b4668d22b9f7ca1394122a32d: $$\beta_3$$ + +5ebbf95d3f6c6b0fe0a9466b8a5cee5232292826: $$\begin{array}{l} +(\{0\}^{94}\,\Vert\,\{0\}^{2}\,\Vert\,\mathcal{id}_{\mathsf{SURB}}\,\Vert\,\{0\}^{128}) \\ +\,\left\vert +\begin{matrix} +\small\vphantom{a} \\ +\small\vphantom{a} \\ +\small\;\mathcal{S}_3[0,240) +\end{matrix} +\right. +\end{array} +\begin{matrix} +\quad\Large\Vert\quad \\ +\small\vphantom{a} \\ +\small\vphantom{a} \\ +\small\vphantom{a} +\end{matrix} +\begin{array}{l} +\{0\}^{112} \\ +\,\left\vert +\begin{matrix} +\small\;\mathcal{S}_0[576,688) \\ +\small\;\mathcal{S}_1[464,576) \\ +\small\;\mathcal{S}_2[352,464) +\end{matrix} +\right. +\end{array} +\begin{matrix} +\quad\Large\Vert\quad \\ +\small\vphantom{a} \\ +\small\vphantom{a} \\ +\small\vphantom{a} +\end{matrix} +\begin{array}{l} +\{0\}^{112} \\ +\,\left\vert +\begin{matrix} +\small\vphantom{a} \\ +\small\;\mathcal{S}_1[576,688) \\ +\small\;\mathcal{S}_2[464,576) +\end{matrix} +\right. +\end{array} +\begin{matrix} +\quad\Large\Vert\quad \\ +\small\vphantom{a} \\ +\small\vphantom{a} \\ +\small\vphantom{a} +\end{matrix} +\begin{array}{l} +\{0\}^{112} \\ +\,\left\vert +\begin{matrix} +\small\vphantom{a} \\ +\small\vphantom{a} \\ +\small\;\mathcal{S}_2[576,688) +\end{matrix} +\right. +\end{array}$$ + +5cd88dd4896a1649b59e7f7a65422b82f6197eb7: $$(\{0\}^{94}\,\Vert\,\{0\}^{2}\,\Vert\,\mathcal{id}_{\mathsf{SURB}}\,\Vert\,\{0\}^{128})$$ + +%% +## Drawing +```compressed-json +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 +``` +%% \ No newline at end of file