LFSR

badmonkey的博客
最开始了解到LFSR的时候是在学习MT19937伪随机数生成器的时候,当时也是初步了解。也没有用代码实现过,最近做了几道相关的题,在这里记录一下。

原理

证明过程不太会,简单说一下大致的原理。LFSR是用于生成随机数序列的,每一个LFSR都是有级数的,级数决定了潜在的循环周期(即随机数序列的周期)。对于每个LFSR还需要有一个线性函数,用于生成随机数。比如

四级LFSR 参数
级数 4
最长循环周期 2^4-1
线性函数 x4+x2+x+1

这里的线性函数必须是二元域上的n阶不可约多项式,线性函数的作用有点类似掩码的功能,对上面的线性函数相当于mask 1011(x的系数非零则为1,不考虑常数项,从左到右次数依次递减)


对上面的例子,选取一个4位的seed用于生成随机数,假设seed为1010
step1
线性函数充当掩码的功能选取seed的对应位,即 seed & mask => 1010 & 1011 选取了第1,3,4位分别为 1,1,0 ,则有 1 xor 1 xor 0 => 0
step2
将上一步得到的结果和seed后三位进行拼接,所以新的随机数就是0100


同理下一个随机数为1000,若经过k次迭代后生成了和seed一样的的数,则称k为为循环周期,显然周期越长为好,MT19937的周期就很长可以达到2^19937-1。

题目

CISCN 2018 oldstreamgame

# coding=utf-8
flag = "flag{xxxxxxxxxxxxxxxx}"
assert flag.startswith("flag{")
assert flag.endswith("}")
assert len(flag)==14def lfsr(R,mask):output = (R << 1) & 0xffffffffi=(R&mask)&0xfffffffflastbit=0while i!=0:lastbit^=(i&1)i=i>>1output^=lastbitreturn (output,lastbit)
R=int(flag[5:-1],16)
mask = 0b10100100000010000000100010010100f=open("key","w")
for i in range(100):tmp=0for j in range(8):(R,out)=lfsr(R,mask)tmp=(tmp << 1)^outf.write(chr(tmp))
f.close()

相信看过原理之后应该可以理解代码,关键代码为

for i in range(100):tmp=0for j in range(8):(R,out)=lfsr(R,mask)tmp=(tmp << 1)^outf.write(chr(tmp))

初始的时候tmp为0,经过8次变化得到的新的tmp,将其转成字符写到文件中去。来看一下文件中的第一个字符的二进制形式00100000,其实仔细想想只有当每次的out为1的时候才能改变tmp的值,下一次tmp又会左移一位,所以8位的tmp对应8次lfsr的out。

也就是所根据文件的二进制可以知道每一次lfsr的out,而每一次的out其实就是对应生成的随机数的最低位,而且随机数的生成是每次左移+out构成的!

因此文件的前32位二进制数,是由seed生成的一个随机数。而且是第32个生成的随机数,而且我们能根据第32个随机数猜测第31个随机数,因为第31个随机数的低31位是第32个随机数的高31位。猜测32次后可以得到原始seed,即flag,exp脚本如下:

cipher = open('key','rb').read()
bin_out = ''.join([bin(ord(i))[2:].zfill(8) for i in cipher])R = int(bin_out[0:32],2)
mask = 0b10100100000010000000100010010100def lfsr(R,mask):output = (R << 1) & 0xffffffffi=(R&mask)&0xfffffffflastbit=0while i!=0:lastbit^=(i&1)i=i>>1output^=lastbitreturn (output,lastbit)def decry():cur = bin_out[0:32]res = ''for i in range(32):if lfsr(int('0'+cur[0:-1],2),mask)[0] == int(cur,2):res += '0'cur = '0'+cur[0:-1]else:res += '1'cur = '1' + cur[0:-1]return int(res[::-1],2)r = decry()
print hex(r)[2:].strip('L')

AFCTF TinyLFSR

# coding=utf-8
import sys
from binascii import unhexlifyif(len(sys.argv)<4):print("Usage: python Encrypt.py keyfile plaintext ciphername")exit(1)def lfsr(R, mask):output = (R << 1) & 0xffffffffffffffffi=(R&mask)&0xfffffffffffffffflastbit=0while i!=0:lastbit^=(i&1)i=i>>1output^=lastbitreturn (output,lastbit)R = 0
key = ""
with open(sys.argv[1],"r") as f:key = f.read()R = int(key,16)f.closemask = 0b1101100000000000000000000000000000000000000000000000000000000000
a = ''.join([chr(int(b, 16)) for b in [key[i:i+2] for i in range(0, len(key), 2)]])f=open(sys.argv[2],"r")
ff = open(sys.argv[3],"wb")
s = f.read()
f.close()
lent = len(s)
for i in range(0, len(a)):ff.write((ord(s[i])^ord(a[i])).to_bytes(1, byteorder='big'))for i in range(len(a), lent):tmp=0for j in range(8):(R,out)=lfsr(R,mask)tmp=(tmp << 1)^outff.write((tmp^ord(s[i])).to_bytes(1, byteorder='big'))
ff.close()

考点貌似不在LFSR,只是加密的时候用到了,seed就是key的int值,key也可以通过爆破来找,exp脚本如下:

# coding=utf-8
import binascii
pt = open('Plain.txt', 'rb').read()
et = open('cipher.txt', 'rb').read()
fl = open('flag_encode.txt', 'rb').read()
def lfsr(R, mask):output = (R << 1) & 0xffffffffffffffffi = (R & mask) & 0xfffffffffffffffflastbit = 0while i != 0:lastbit ^= (i & 1)i = i >> 1output ^= lastbitreturn (output, lastbit)def find_part():tmp = ''# 被密钥异或的公共部分for i, j in zip(et, fl):tmp += chr(i ^ j)tmp = bytes(tmp, encoding='utf-8')ans = ''# 异或明文恢复部分明文for i, j in zip(pt, tmp):ans += chr(i ^ j)return ans
def str_to_hexStr(string):str_bin = string.encode('utf-8')return binascii.hexlify(str_bin).decode('utf-8')def guess_key(size):key = ''for i,j in zip(pt[0:size],et[0:size]):key += chr(i ^ j)key = str_to_hexStr(key)return int(key, 16)def find_key():mask = 0b1101100000000000000000000000000000000000000000000000000000000000t = open('Plain.txt','r').read()for i in range(1,len(pt)):key = guess_key(i)cur = t[0:i]for j in range(i, len(pt)):tmp = 0for k in range(8):(key, out) = lfsr(key, mask)tmp = (tmp << 1) ^ outcur += chr(et[j] ^ tmp)# print(cur)if cur == t:return keyreturn -1def decry():flag = find_part()R = find_key()mask = 0b1101100000000000000000000000000000000000000000000000000000000000for i in range(104, len(fl)):tmp = 0for j in range(8):(R, out) = lfsr(R, mask)tmp = (tmp << 1) ^ outflag += chr(fl[i]^tmp)print(flag)decry()

2018强网杯

先挖个坑。。5道题。。

线性反馈移位寄存器-LFSR相关推荐

  1. 四类九种移位寄存器总结(循环(左、右、双向)移位寄存器、逻辑和算术移位寄存器、串并转换移位寄存器、线性反馈移位寄存器LFSR|verilog代码|Testbench|仿真结果)

    移位寄存器总结 一.前言 二.简单循环左移/右移/双向移位寄存器 2.1 简单循环左移/右移/双向移位寄存器 2.2 verilog代码 2.3 Testbench 2.4 仿真结果 三.逻辑移位与算 ...

  2. 线性反馈移位寄存器LFSR(斐波那契LFSR(多到一型)和伽罗瓦LFSR(一到多型)|verilog代码|Testbench|仿真结果)

    线性反馈移位寄存器LFSR 一.前言 二.LFSR简介 三.斐波那契LFSR和伽罗瓦LFSR 3.1 斐波那契LFSR 3.1.1 斐波那契LFSR 3.1.2 verilog代码 3.1.3 Tes ...

  3. 线性反馈移位寄存器(LFSR) ______FPGA产生基于LFSR的伪随机数

    FPGA产生基于LFSR的伪随机数 https://blog.csdn.net/qq_34070723/article/details/89736772 1.概念 通过一定的算法对事先选定的随机种子( ...

  4. 序列密码体制(python随机数密码,RC4,线性反馈移位寄存器

    目录 概念: Vernam密码技术(序列密码的起源 伪随机数 线性反馈移位寄存器: 线性反馈移位寄存器LFSR 概念: 明文按一定长度分组后表示成一个序列,称为明文流.加密时,由种子密钥通过密钥流生产 ...

  5. 流密码(一)同步流密码、自同步流密码以及线性反馈移位寄存器

    正式进入密码学领域,发现密码学更像是一门数学,主要是对数论.近世代数的简单应用以及运用在算法中,常常结合模运算以及数字逻辑运算. 流密码的第一部分主要是比较了同步流密码和自同步流密码,其中自同步流密码 ...

  6. 线性反馈移位寄存器(LSFR)

    线性反馈移位寄存器(LSFR) 流密码的流密钥产生器可以通过线性驱动和非线性组合两部分来实现.而线性驱动部分可以由线性反馈移位寄存器(LFSR)来实现. 线性反馈移位寄存器(LFSR):通常由移位寄存 ...

  7. 【数字IC/FPGA】线性反馈移位寄存器

    线性反馈移位寄存器 LFSR用于产生可重复的伪随机序列PRBS,该电路有n级触发器和一些异或门组成,如下图所示.它和移位寄存器最大的区别就是他有反馈. 其中,gng_ngn​为反馈系数,取值只能为0或 ...

  8. HDLBits 系列(21)LFSR(线性反馈移位寄存器)

    目录 5 bit LFSR 3 bit LFSR 32 bit LFSR 5 bit LFSR A linear feedback shift register is a shift register ...

  9. quartus仿真6:74194构建线性反馈移位寄存器计数器LFSR

    扭环形计数器具有8个有效状态,仍然有8个无效状态.进一步提高移位寄存器构建的计数器的有效状态数,可采用线性反馈移位寄存器计数器(Linear Feedback Shift-Register Count ...

最新文章

  1. OpenAI与GitHub联手推出AI代码生成工具,比GPT-3更强大
  2. 解决Raspberry Pi不识别RTL8188eu无线网卡芯片的问题
  3. RabbitMQ三种订阅模式
  4. HDU - 6184 Counting Stars(思维+三元环)
  5. java实现简易聊天窗口先运行服务器还是客户端_一个简易聊天功能的服务器端和客户端源码...
  6. iOS-数据持久化-偏好设置
  7. iframe 页面富文本框数据怎么保存_文字太多PPT怎么做都丑?估计是没注意这些细节!...
  8. 界面设计方法(2)— 6.功能按钮设计(删除,保存,提交)
  9. Spring整合Quartz实现定时任务
  10. 从零开始学前端:过渡和动画 --- 今天你学习了吗?(CSS:Day20)
  11. width:100%以什么为基准的测试
  12. 【离散数学】数理逻辑 第二章 谓词逻辑(4) 谓词逻辑的推理理论
  13. GitHub 微信公众号爬虫推荐
  14. mysql 环境_MySQL怎么配置环境变量?
  15. 贪心科技NLP实习面试
  16. 关于程序员的教育和培训
  17. spring boot(五) 用户注册功能
  18. windows server 2008 r2 设置显示文件后缀名
  19. matlab 三角波脉冲轨迹叠加,求解:两同频三角波叠加后的相位差(有程序,有图)...
  20. debussy和modelsim联合仿真配置

热门文章

  1. 单片机、嵌入式Linux开发大学自学路径
  2. 1元云购网站开通微信支付设置方法
  3. 定时清理数据--定时操作
  4. Windows API Hooking with MS Detours
  5. C语言实现复数的几个基本操作(四则运算,初始化,销毁...)
  6. Mp4 分割 怎么将mp4视频文件分割成几段
  7. uniapp 关于小程序图片高度不能自适应的问题[widthFix]
  8. AMap初级实战之二(MoveAnimation moveTo、moveAlong)
  9. 关联规则算法怎么实现?Python代码、PowerBI可视化详细解释给你听(下-实战篇)
  10. 测试工作4年,兢兢业业,领导一句“不如应届生”被裁员,后悔一直做的是最基础的工作