# ICRP: Internet-Friendly Cryptographic Relay-Detection Protocol
## 5 Performances
### Prototype Implementation  
Our proposal as displayed by Figures 11 and 12 has a very clear downside, which is its sequentiality. Indeed, with this representation, each time \(\mathcal{S}\) sends a packet, he has to wait for a response before sending the next one. This is especially problematic when ICRP runs in active mode and aims to send many consecutive packets. Hence, \(\mathcal{S}\) needs to concurrently perform the sending and the reception of \(\mathcal{R}\)'s responses. Similarly, if \(\mathcal{S}\) and \(\mathcal{R}\) need to run multiple consecutive sessions in active mode, the verification and authentication part of the protocol must not be realized sequentially as it would force \(\mathcal{S}\) to wait until the end of the session to start a new one. Figure 14 schematically shows the differences in terms of efficiency between 3 simplified models of implementation for \(\mathcal{S}\)'s side: the top one is the sequential implementation, the middle one displays 2 concurrent threads for the sending and the reception of acknowledgments, the bottom one displays 3 concurrent threads for sending, receiving and verifying. The dotted lines represent a repeated operation, while the solid lines represent inactive periods of time for the current thread. Our prototype is implemented according to the bottom model of Figure 14. The third part handling verification is separated into three threads for synchronization purposes. The other party \(\mathcal{R}\) is also implemented concurrently, with one thread handling the reception of packets and the sending of the response, and a second thread performing the cryptographic computations. We provide below a description of each thread's actions. On \(\mathcal{S}\)'s side:  
1. Thread send: this thread is in charge of sending all the packets to \(\mathcal{R}\) and generating a timestamp when it does. It then stores the timestamp in a structure shared by all threads. 2. Thread recv: this thread is in charge of receiving every response from \(\mathcal{R}\), generating a timestamp when it does, and computing the RTTs from the timestamps placed in the shared structure. 3. Thread pre_Hash: this thread is in charge of updating the Hash context with the values known beforehand by \(\mathcal{S}\). That is the content of packets \(\{p_{i}\}\) and the bits \(s_{i}\). Figure 13: Active and Passive mode overview. On \(\mathcal{R}\)'s side:  
1. Thread recv: this thread is in charge of receiving the packets and sending the responses to \(\mathcal{S}\). 2. Thread auth: this thread is in charge of updating the Hash context with the values known beforehand by \(\mathcal{R}\). That is the bits \(r_{i}\). It then waits for all the data it needs to be available from other threads (the content of packets \(\{p_{i}\}\) and the bits \(s_{i}\)), proceeds to Hash&Sign, and finally, sends the signature to \(\mathcal{S}\). Using multiple threads to boost up the performances forces the parties to tag each packet with a sequence number in order to link each message and response to the correct round and session and not get confused with the time measurements. Consequently, we added a 4 bytes header to indicate the sequence number. These 4 bytes are formed by 2 bytes indicating the current session number followed by 2 bytes indicating the current round number. Writing the round and session indexes on 2 bytes each is good enough to fit our experimental needs while being easily implemented in our prototype. In a real case scenario though, the number of rounds \(n\) for an ICRP session should not be greater than 512 because a relay detection can only occur once the \(n\) rounds are over. If \(n\) is at most 512, its associated field in the 4 bytes header can be limited to only 9 bits, leaving 23 bits for the session index. We choose to use a 4 bytes header as it is also the size used for the field SQN of the TCP header which serves the same purpose of keeping the sessions synchronized between the nodes.