---
# System prepended metadata

title: Misery Straightener

---

# Misery Straightener

## Overview

We are given a stream generators

* It has a list of $13$ states $[S_{0}, S_{1}, \dots, S_{12}]$ and a constant $C$
* Everytime, it computes new states $S$ using the strange function next() and updates the list to be $[S, S_{0}, S_{1}, \dots, S_{11}]$. After that, it outputs $S_{12}$.

The process performs fastforward and then XOR the flag by OTP generated by the generator. 

## Exploit

Look at the function name: next() and forward(), I think that the generator is, in fact, LFSR. As it's well-known of LFSR can be interpreted by matrix over $GF(2)$. So it seems we are able to find states after fastforward! Let's go deeper to the next() function.

### Analysis of next() function

```python=
res = self.pool[-1];
a = self.pool[12];
b = self.pool[6];
c = a ^ b;
c = c ^ (a >> 10);
c = c ^ ((b % (1 << 20)) << (self.bits - 20));
d = ((1 << self.bits) - 1) - c;
e = d;
if(self.pool[8] & 8):
	e ^= self.randomConstant;

self.pool.pop();
self.pool.insert(0,e);
return res;
```

First of all, notice that the calculation includes bits shift of states. Hence, it would be better to consider bits of states as varaibles. 

**Notation.** Let $s_{i,j}, c_{j}$ be the $j$-th significant bit of $S_{i}$ and $C$, respectively.

Now, we're going to construct the matrix step-by-step.

### Line 4

Remember that XOR is a bit-wise operation, so we have $s_{0,j}^{'} = s_{6, j} \oplus s_{12, j}$. In terns of matrix, it is simply 

$$
\begin{bmatrix}
    s_{0, 0}^{'} \\ \vdots \\ s_{0,42}^{'}
\end{bmatrix}
= \begin{bmatrix}
    0 & 0 & 0 & 0 & 0 & 0 & I & 0 & 0 & 0 & 0 & 0 & I 
\end{bmatrix}
\begin{bmatrix}
    s_{0, 0} \\ \vdots \\ s_{12,42}
\end{bmatrix}
$$ 

Here $0, I$ are zero matrix and identity matrix of size $42$.

### Line 5, Line 6

Next, we XOR the current $c$ by

    (a >> 10), ((b % (1 << 20)) << (self.bits - 20))

This means $s_{0, j}^{'} = s_{0, j}^{'} \oplus s_{12, j+10} \oplus s_{6, j-22}$. Therefore, the equation can be updated to

$$
\begin{bmatrix}
    s_{0, 0}^{'} \\ \vdots \\ s_{0,42}^{'}
\end{bmatrix}
= \begin{bmatrix}
    0 & 0 & 0 & 0 & 0 & 0 & I + B & 0 & 0 & 0 & 0 & 0 & I + A 
\end{bmatrix}
\begin{bmatrix}
    s_{0, 0} \\ \vdots \\ s_{12,42}
\end{bmatrix}
$$ 

where $A, B$ are given by

$$
A = 
\begin{bmatrix}
    0_{10, 32} &, 0_{10, 10} \\ I_{32, 32} &, 0_{32,10}
\end{bmatrix}, \quad
B = 
\begin{bmatrix}
    0_{20, 22} &, I_{20, 20} \\ 0_{22, 22} &, 0_{22,20}
\end{bmatrix}
$$ 

### Line 7

Notice that substraction is equivalent to addtion over $GF(2)$, thus the operation is just $s_{0, j}^{'} = s_{0, j}^{'} \oplus 1$. Currently, we don't have $1$ in the vector, let's append a constant $1$ in the end!

$$
\begin{bmatrix}
    s_{0, 0}^{'} \\ \vdots \\ s_{0,42}^{'}
\end{bmatrix}
= \begin{bmatrix}
    0 & 0 & 0 & 0 & 0 & 0 & I + B & 0 & 0 & 0 & 0 & 0 & I + A & 1_{42,1} 
\end{bmatrix}
\begin{bmatrix}
    s_{0, 0} \\ \vdots \\ s_{12,42} \\ 1
\end{bmatrix}
$$ 

Here, $1_{42,1}$ is the column vector of size $42$ and all the element is $1$.

### Line 9, 10

Rephrase the if condition: $s_{0, j}^{'} = s_{0, j}^{'} \oplus c_{j}$ when $s_{8, j} = 1$. This can be further simplified as $s_{0, j}^{'} = s_{0, j}^{'} \oplus s_{8,j}$ when $c_{j}=1$. Assume $c$ is the column vector $[c_{0}, \dots, c_{42}]^{T}$, we form the matrix

$$
C = 
\begin{bmatrix}
    0_{42, 38} & c & 0_{42, 3} 
\end{bmatrix}
$$ 

and obtain the matrix equation

$$
\begin{bmatrix}
    s_{0, 0}^{'} \\ \vdots \\ s_{0,42}^{'}
\end{bmatrix}
= \begin{bmatrix}
    0 & 0 & 0 & 0 & 0 & 0 & I + B & 0 & C & 0 & 0 & 0 & I + A & 1_{42,1} 
\end{bmatrix}
\begin{bmatrix}
    s_{0, 0} \\ \vdots \\ s_{12,42} \\ 1
\end{bmatrix}
$$ 

Finally, we only need to take $S_{1}^{'}, \dots, S_{12}^{'} = S_{0}, \dots, S_{11}$ into consideration. To make it simple, let $M$ be the matrix 

$$
M = \begin{bmatrix}
    0 & 0 & 0 & 0 & 0 & 0 & I + B & 0 & C & 0 & 0 & 0 & I + A & 1_{42,1} 
\end{bmatrix}
$$

We have the following transition equation

$$
\begin{bmatrix}
    s_{0, 0}^{'} \\ \vdots \\ s_{12,42}^{'} \\ 1
\end{bmatrix}
= \begin{bmatrix}
    M & \\ I_{12*42} & 0_{42, 12*42+1} \\ 0_{1, 13*42} & 1
\end{bmatrix}
\begin{bmatrix}
    s_{0, 0} \\ \vdots \\ s_{12,42} \\ 1
\end{bmatrix}
$$ 

Here the python code for matrix construction

```python=
N = 13*42
M = Matrix(Zmod(2), N+1, N+1)
M[42:N, :N-42] = Matrix.identity(N-42) 
M[-1, -1] = 1
randomConstant_bits = [0, 1, 0, 1, 1, 1, 0, 1, 0, 1, 1, 1, 1, 0, 1, 0, 0, 1, 1, 0, 0, 0, 1, 1, 0, 0, 1, 1, 0, 1, 0, 1, 1, 1, 1, 1, 0, 1, 1, 0, 0, 1]
for i in range(42):
    M[i, i+12*42] = 1
    M[i, i+6*42] = 1
    if i >= 10:
        M[i, i+12*42 - 10] = 1
    if i < 20:
        M[i, i+6*42 + 22] = 1
    M[i, -1] = 1
    M[i, 9*42-4] = randomConstant_bits[i]
```

It's easy to find the OTP now :)