LFSR简介:
线性反馈移位寄存器(Linear feedback shift register,LFSR)是指给定前一状态的输出,将该输出的线性函数再用作输入的移位寄存器。线性反馈移位寄存器(LFSR)归属于移位寄存器(FSR),除此之外还有非线性移位寄存器(NFSR)。
GF(2)
上一个 n
级反馈移位寄存器由 n
个二元存储器与一个反馈函数 f(a1,a2,⋯,an)
组成,如下图所示:
如果此处的反馈函数是线性的,我们就把它称为LFSR,此时该反馈函数可以表示为
$$
f(a_1,a_2,…,a_n)\ =\ c_na_1⊕c_{n-1}a_2⊕…c_1a_n
$$
其中c~i~ = 0 或 1,⊕表示异或
接下来,通过一个例子来更直观的确定LFSR的概念,假设给定一个5级的LFSR,其初始状态(即a~1~到a~5~各个寄存器的初始值)为:
$$
(a_1,a_2,a_3,a_4,a_5)\ =\ (1,0,0,1,1)
$$
其反馈函数为:
$$
f(a_1,a_2,a_3,a_4,a_5)\ =\ a_4⊕a_1
$$
整个过程可以表示为下图所示形式:
$$
LFSR的输出序列{a_n}满足\left{
\begin{aligned}
a_{n+1}& =c_1a_n⊕c_2a_{n-1}⊕…⊕c_na_1\
a_{n+2}& =c_1a_{n+1}⊕c_2a_{n}⊕…⊕c_na_2\
.\
.\
.\
a_{n+i}& =c_1a_{n+i-1}⊕c_2a_{n+i-2}⊕…⊕c_na_i
\end{aligned}
\right.
$$
接下来,我们来计算该LFSR的输出序列,输出序列的前5位即为我们的初始状态10011,第6位的计算过程如下,
$$
a_6\ =\ a_4⊕a_1\ =\ 1⊕1\ =\ 0
$$
第7位的计算过程如下:
$$
a_7\ =\ a_5⊕a_2\ =\ 1⊕0\ =\ 1
$$
由此类推,可以得到前31位的计算结果如下:
1 | 1001101001000010101110110001111 |
此处可以借助代码辅助理解:
1 | a = '10011' |
对于一个n级的LFSR来讲,其最大周期为2^n-1,因此对于我们上面的5级LFSR来讲,其最大周期为 2^5^-1=31,再后面的输出序列即为前31位的循环。
对于一个LFSR
来讲,目前主要关心三个部分:初始状态、反馈函数和输出序列,那么对于CTF中考察LFSR的题目来讲也是如此,大多数情况下,我们在CTF中的考察方式都可以概括为:给出反馈函数和输出序列,要求我们反推出初始状态,初始状态即为我们需要的flag,另外大多数情况下,初始状态的长度我们也是已知的。
例题:
2018 CISCN 线上赛 oldstreamgame
1 | flag = "flag{xxxxxxxxxxxxxxxx}" |
我们先分析一下已知条件:
已知初始状态的长度为4个十六进制数,即32位
已知反馈函数的代码形式,我们要提取出它的数学表达式
已知输出序列
那么我们的任务很明确,就是通过分析lfsr
函数,整理成数学表达式的形式求解即可
接着我们就来逐行分析此函数
1 | def lfsr(R,mask): |
1 | output = (R<<1) & 0xffffffff |
1 | i = (R & mask) & 0xffffffff |
1 | lastbit = 0 |
1 | output ^= lastbit |
1 | return (output,lastbit) |
经过以上分析,我们发现lfsr
函数本质上就是一个输入R,输出lastbit的函数
虽然我们已经清楚了R是如何经过一系列运算得到lastbit,但我们前面的反馈函数都是数学公式的形式,
我们怎么把他整理成一个表达式的形式呢?
mask只有第3、5、8、12、20、27、30、32这几位为1,其余位均为0。
mask与R做按位与运算得到i,当且仅当R的第3、5、8、12、20、27、30、32这几位中也出现1时,i中才可能出现1,否则i中将全为0。
lastbit是由i的最低位向i的最高位依次做异或运算得到的,在这个过程中,所有为0的位我们可以忽略不计(因为0异或任何数等于任何数本身,不影响最后运算结果),
因此lastbit的值仅取决于i中有多少个1:当i中有奇数个1时,lastbit等于1;当i中有偶数个1时,lastbit等于0。 当R的第3、5、8、12、20、27、30、32这几位依次异或结果为1时,即R中有奇数个1,因此将导致i中有奇数个1;当R的第3、5、8、12、20、27、30、32这几位依次异或结果为0时,即R中有偶数个1,因此将导致i中有偶数个1。
因此我们可以建立出联系:lastbit等于R的第3、5、8、12、20、27、30、32这几位依次异或的结果。
将其写成数学表达式的形式:
$$
lastbit\ =\ R_3⊕R_5⊕R_8⊕R_{12}⊕R_{20}⊕R_{27}⊕R_{30}⊕R_{32}
$$
显然,lastbit和R之间满足线性关系,那么接下来我们就可以开始求解了
我们想象:当即将输出第32位lastbit时,此时R已经左移了31位,根据上面的数学表达式,可以有
我们可以求出R的第1位,同样的方法,我们可以求出R的第2位:
以此类推,R的全部32位我们都可以依次求出了,代码形式如下:
1 | mask = '10100100000010000000100010010100' |
如下题目的分析方法同上:
2018 强网杯 线上赛 streamgame1
2018 强网杯 线上赛 streamgame2
2018 强网杯 线上赛 streamgame4
2018 HITB-XCTF 线上赛 streamgamex