LFSR StreamCipher

Attachmentscrypto - 5003 solves

Task Description

Time

Solved after the CTF with a lot of help from the admin (@asante).

Solution

In this challenge, we have a LFSR, a non-linear filter of algebraic degree 6, and its first 1001 outputs. Our goal is to recover its initial seed.

For LFSR clock LL and filter ff, the outputs bib_i are: f(s)=b0f(L(s))=b1f(L2(s))=b2f(Ln(s))=bn\begin{aligned} f(s) &= b_0\\ f(L(s)) &= b_1\\ f(L^2(s)) &= b_2\\ & \cdots \\ f(L^n(s)) &= b_n\\ \end{aligned} Degree of these equations are too large, it is infeasible to solve ss directly. We need to lower the degree to solve ss, and here comes the idea of annihilators: annihilator gg of ff with is: x:f(x)g(x)=0    x{z  f(z)=1}:g(x)=0\begin{aligned} & \forall x: f(x)g(x) = 0 \\ \implies& \forall x \in \{z\ |\ f(z) = 1\}: g(x) = 0 \\ \end{aligned}

If we can find a function g with lower degree, we can solve for following system of equations instead: g(Li(s))=0i:bi=1g(L^i(s)) = 0 \quad \forall i: b_i = 1

We can find such function using sage:

from sage.crypto.boolean_function import BooleanFunction
B = BooleanPolynomialRing(6, ['x0', 'x64', 'x96', 'x128', 'x192', 'x255'])
x0, x64, x96, x128, x192, x255 = B.gens()
p = x0*x64*x96*x128*x192*x255 + ... + x128*x192*x255
f = BooleanFunction(p)
print(f.annihilator(f.algebraic_immunity()))
# output x0 + x1 + x2 + x3 + x4 + x5 + 1
# which means x0 + x64 + x96 + x128 + x192 + x255 + 1

Now we have a great linear annihilator.

For more about annihilator, algebraic immunity, and algebraic attack on LFSR, see this awesome slide.

To solve the system of equations, we can express the LFSR in matrix form, apply our annihilator gg on the matrix, and solve for ss, formally: Let h=x0+x64+x96+x128+x192+x255L=(010000100001c0c1c2cn)\begin{aligned} \text{Let}\ h &= x^{0} + x^{64} + x^{96} + x^{128} + x^{192} + x^{255}\\ L &= \left(\begin{matrix} 0 & 1 & 0 & \cdots & 0 \\ 0 & 0 & 1 & \cdots & 0 \\ \vdots & \vdots & \vdots & \ddots & \\ 0 & 0 & 0 & \cdots & 1 \\ c_0 & c_1 & c_2 & \cdots & c_n \\ \end{matrix}\right) \\ \end{aligned} g(Li(s))=0i:bi=1    h(Li(s))+1=0i:bi=1    h(Li(s))=1i:bi=1    (hLi)s=1i:bi=1    (hLi0hLi1hLi2hLin)s=(1111)\begin{aligned} & g(L^i(s)) = 0 \quad & \forall i: b_i = 1 \\ \implies& h(L^i(s)) + 1 = 0 \quad & \forall i: b_i = 1 \\ \implies& h(L^i(s)) = 1 \quad & \forall i: b_i = 1 \\ \implies& (hL^i)s = 1 \quad & \forall i: b_i = 1 \\ \implies& \left(\begin{matrix} hL^{i_0} \\ hL^{i_1} \\ hL^{i_2} \\ \vdots \\ hL^{i_n} \\ \end{matrix}\right) s = \left(\begin{matrix} 1 \\ 1 \\ 1 \\ \vdots \\ 1 \\ \end{matrix}\right) \\ \end{aligned}

Solving for ss yields 4 solutions:

[+] Generated 293 equations
[+] Solution 0: ')A\x17U\xaf\x9d\x18\xbcn[\xed\x8aj\x00\xbc\xd4\xb39\xe1ef\xe7~/\xaa\xf2\xd7\x9e\x99\xdf\xc6j'
[+] Solution 1: 's\xf0Z\xea\x07\xa2\xc5H\xba\x1c*\xa5\x82_X\xf2\x1c\xfe\xd5\xb3\x11A%\xf0\x92\x0c\x8c\xbawa\x83w'
[+] Solution 2: '<\xdd,\xd8\xd3l\xa9\xa6\xe7s\xaap\xabn\xb4N\x9c\x95k\x97\x19\xc82\xb7\t\x92:P\xdd\xfad`'
[+] Solution 3: 'flag{StR34m_C1Ph3R_Annih1lat3D!}'