diff --git a/PROTOCOL.md b/PROTOCOL.md index bf48eef..99428ce 100644 --- a/PROTOCOL.md +++ b/PROTOCOL.md @@ -49,7 +49,7 @@ This document will define and bundle 2 distinct protocols to make up a token sys | Symbols | Description | |:-----:|:----------| -| $\parallel a\parallel $ | The absolute value of $a$ ; *e.g.* $\parallel a \parallel = \parallel -a \parallel$ | +| $\parallel a\parallel $ | The absolute value of $a$ ; *e.g.* $\parallel -12 \parallel = 12$ | | $\mid a \mid$ | The integer value of $a$ ; *e.g.* $\mid 12.34 \mid = 12$ | | $a \oplus b$ | The bitwise operation XOR between binary words $a$ and $b$ | | $h(m)$ | The digest of the message $m$ by a (consistent) secure cryptographic hash function $h()$ ; *e.g. sha512* | @@ -112,6 +112,45 @@ Because of the main property of cryptographic hash functions, the original data **Limitations** : It seams obvious that there is weaknesses due to hashing recursively a single data, but I do not know if such attack is known or even works. +##### Time Scrambling algorithm + +In order for the requests/responses to be only valid a few seconds in time, the tokens are scrambled using a [one-time pad](https://en.wikipedia.org/wiki/One-time_pad). + +The sender processes the data as follows: + +| Step | Description | Formula | +|:----:|:-----------|:-------| +| 1 | Process the sender's time id | $t\_s = \mid \frac{t_{now}^s}{W} \mid $ | +| 2 | process the sender's time parity | $ m_s = t_s \mod 2$ | +| 3 | Send the time parity | $ Send\ m_s$ | + +The receiver has to guess $t_s$ with the following steps: + +| Step | Description | Formula | +|:----:|:-----------|:-------| +| 1 | receive the sender's time parity | $Receive \ m_s$ | +| 2 | process the receiver's time id | $t\_r = \mid \frac{t_{now}^r}{W} \mid $ | +| 3 | process the receiver's time parity | $m_r = t_r \mod 2$ | +| 4 | Try to guess the sender's time id | $t_{s2} = t_r - \parallel m_s - m_r \parallel $ | + +As a result, the receiver will only be able to retrieve the sender's time id if the reception time is at most $W$ seconds after the sending time : + +$$t\_{now}^r \leq t\_{now}^s + W \implies t\_s = t_{s2}$$ + +In practice, the time id is **hashed** and used to achieve a [one-time pad](https://en.wikipedia.org/wiki/One-time_pad) with the token. Because they both result from the same hash function their sizes are the same. + +As a result from the sent token $x_1 = token \oplus h(t_s)$, it is impossible to guess the token nor $h(t_s)$ without the other. + +**Explanation** +* The time id corresponds to the index of the time slice where slices are $W$ seconds wide. By dividing the time in slices of $W$ seconds, if we process the same calculation at an interval of $W$ or less seconds, we will have either the same result or a result greater by 1. +* The window id parity $m_s$ allows us to adjust the receiver's time id $t_r$ when it receives the request. This difference of 1 second is caused by the division of time in slices, the precision is also divided by $W$. + + - $ t_{now}\mod W = 0 \implies \mid \frac{t_{now}}{W} \mid = \mid \frac{t_{now}+(W-1)}{W} \mid $; no need for adjustment + - $ t_{now}\mod W = 1 \implies \mid \frac{t_{now}}{W} \mid = \mid \frac{t_{now}+(W-1)}{W} \mid + 1 $; need to subtract $1$ + - $ t_{now}\mod W = 2 \implies \mid \frac{t_{now}}{W} \mid = \mid \frac{t_{now}+(W-1)}{W} \mid + 1 $; need to subtract $1$ + - $ ... $ + - $ t_{now}\mod W = (W-1) \implies \mid \frac{t_{now}}{W} \mid = \mid \frac{t_{now}+(W-1)}{W} \mid + 1 $; need to subtract $1$ + ## Protocol properties ##### (1) Token Chain @@ -162,7 +201,6 @@ Each token has a size defined by the *hash function*, which is `sha512` for this > For readability purposes, the tokens are sent as their hexadecimal representation ; each token is then a string of 128 characters. - ### 1. Request This case is the default where $i$ is far from $1$ so there is no key generation to do. @@ -171,24 +209,13 @@ This case is the default where $i$ is far from $1$ so there is no key generation |:----:|-------------|:--------| | `c1` | Decrement the shifting nonce | $i = i - 1$ | | `c2` | Calculate the one-time token $T_C$ | $T_C = h^{i}(K)$ | -| `c3` | Get the current window id $n_C$ | $n_C =\ \mid \frac{t_{now}}{W} \mid$ | -| `c4` | Calculate $m_C$, the parity of $n_C$ | $m_C = n_C \mod 2$ | -| `c5` | Calculate the time hash $h_{n_C}$ | $h_{n_C} = h(n_C)$ | -| `c6` | Calculate $T_{req}$, the scrambled *request token* | $T_{req} = T_C \oplus h_{n_C}$ | - -**Steps explanation** - -- `c2` - The window id corresponds to the index of the time slice where slices are $W$ seconds wide. By dividing the time in slices of $W$ seconds, if we process the same calculation at an interval of $W$ or less seconds, we will have either the same result or a result greater by 1. -- `c3` - The window id parity $m_C$ allows us to adjust the value of $n_S$ made on $S$ when it receives the request. This difference of 1 second is caused by the division of time in slices, the precision is also divided by $W$. - - $t_{now}\mod W = 0 \implies \mid \frac{t_{now}}{W} \mid = \mid \frac{t_{now}+(W-1)}{W} \mid$; no need for adjustment - - $t_{now}\mod W = 1 \implies \mid \frac{t_{now}}{W} \mid = \mid \frac{t_{now}+(W-1)}{W} \mid + 1$; need to subtract $1$ - - $t_{now}\mod W = 2 \implies \mid \frac{t_{now}}{W} \mid = \mid \frac{t_{now}+(W-1)}{W} \mid + 1$; need to subtract $1$ - - $...$ - - $t_{now}\mod W = (W-1) \implies \mid \frac{t_{now}}{W} \mid = \mid \frac{t_{now}+(W-1)}{W} \mid + 1$; need to subtract $1$ -- `c4` - $h(n_C)$ allows $h_{n_C}$ to be $L$ bits long and protects $n_C$ to be predictable from $h_{n_C}$. -- `c5` - we process a one-time pad between $T_C$ and $h_{n_C}$ it is crucial that both values have the same size of $L$ bits. It makes $T_C$ impossible to extract without having the value $h_{n_C}$, this property applies in both ways. - +| `c3` | Get the current window id $t_C$ | $t_C =\ \mid \frac{t_{now}}{W} \mid$ | +| `c4` | Calculate $m_C$, the parity of $t_C$ | $m_C = t_C \mod 2$ | +| `c5` | Calculate the time hash $h_{t_C}$ | $h_{t_C} = h(t_C)$ | +| `c6` | Calculate $x_1$, the scrambled *request token* | $x_1 = T_C \oplus h_{t_C}$ | +| `c7` | Calculate $x_2$, the next token + time parity | $x_2 = x_1 \oplus m_C$ | +**Security** : We process a one-time pad between $T_C$ and $h_{t_C}$ it is crucial that both values have the same size of $L$ bits. It makes $T_C$ impossible to extract without having the value $h_{t_C}$, this property applies in both ways. **Short formulas** @@ -227,14 +254,14 @@ This case is the default where $i$ is far from $1$ so there is no key generation **Steps explanation** - `s1` - If $C$ and $S$ have the same values for $K$ and $n^1$, $f(K,n^1)$ must result in the same output; in other words $T_C=T_S$. -- `s3`/`s4` - $\| m_C - m_s\|$ is the difference between $m_C$ and $m_S$. +- `s3`/`s4` - $\parallel m_C - m_s\parallel$ is the difference between $m_C$ and $m_S$. - If the receiver time window id ($n'$) is the same as the sender ($n_C$) $n'=n_C \implies m_S=m_C$ - $m_C=m_S \implies \| m_C - m_S\| = 0$ + $m_C=m_S \implies \parallel m_C - m_S\parallel = 0$ $n_S = n_C - 0$ $n_S=n_C$, the time ids are the same, $S$ can now unscramble the request to check the token - If the receiver time window if further the sender by $1$ - $n'=n_C+1 \implies \| m_C - m_S \| = 1$ + $n'=n_C+1 \implies \parallel m_C - m_S \parallel = 1$ $n_S = n_C + 1 - 1$ $n_S = n_C$, the time ids are the same, $S$ can now unscramble the request to check the token - If the receiver time window if further the sender by $2$ or more, let $k \in \N$