Simple prediction
加密代码:
1 | from random import shuffle |
题目基于两部分加密,第一部分是一个决策形LCG,没什么难的,只要还原出a b m seed就可以进行判断
这四个我们可以通过gro来还原
exp1:
1 | from Crypto.Util.number import long_to_bytes, isPrime, inverse |
第二部分本质上是一个背包
具体做法可以见下面这题,一样的,我记得是当时在crewctf里面做过
还有这题,
1 | from random import shuffle |

但是会发现这个格出不了,那就把n放进去再搞一个格,稍微扩大一下

这个格就出了
1 | from Crypto.Util.number import long_to_bytes |
这边贴个exp:
1 | from Crypto.Util.number import long_to_bytes |
ss0Hurt!
加密代码:
1 | from Crypto.Util.number import * |
xyctf的原题,改了个数据而已,有兴趣可以去搜一下当时的fakeRSA,我这边就贴一下当时那题的做法,照猫画虎即可
加密代码:
1 | from Crypto.Util.number import * |

1 | https://www.wolframalpha.com/input/?i=%7B%7B3%2C1%2C0%7D%2C%7B0%2C3%2C1%7D%2C%7B0%2C0%2C3%7D%7D%5En |
计算通项公式

1 | #sage |
如果这边没有使用数学工具,可以按下面这样进行推导

本题exp:
1 | from Crypto.Util.number import * |
easymath
加密代码:
1 | from Crypto.Util.number import * |
思路很直接,先使用factor分解得到三个小n,然后在各自的模意义之下进行crt的组合即可
exp:
1 | x = var('x') |
sh1kaku_fw
加密代码:
1 | from Crypto.Util.number import getPrime |
这题其实和西湖论剑那题很像,只不过这题的数据量实在太大了,很吃配置,一般的笔记本跑不动,sage容易挂掉
所以我简单改了个题目,毕竟复现主要是学习知识
1 | from Crypto.Util.number import getPrime |
题目要求就是求出s
先说思路吧,这边会说的比较简单,如果要看详细思路的话可以看我西湖论剑的那题的复现
1 | https://suhanhan-cpu.github.io/2025/02/12/2025-%E8%A5%BF%E6%B9%96%E8%AE%BA%E5%89%91-New-Year-Ring4-wp%E5%A4%8D%E7%8E%B0/ |
这题看起来像lwe的板子,但是实际观察我们会发现,e相对于模数来说并不是小量,而且这题如果要造格的话本身的维度非常的大,这显然是不现实的
首先我们有如下的等式
然后这边的误差向量e都是从e_L这里面随机选择的,根据矩阵乘法的性质,就拿第一组等式来说,我们有
那么也就是
这边我是e_L中哪个我们是不知道的,但是无论如何,我们都会有如下的等式
这样我们就可以从第一组当中拿到一组等式,这边一共有19700组,也就是有19700组等式,现在我们只要看未知项是多少就可以决定能不能求解这个方程组
1 | from Crypto.Util.number import long_to_bytes |
这边是对应的项(这边我们只给出我们所需要使用的那几项,也就是最后的那几项)
1 | s0, s1, s2, s3, s4, s5, s6, s7, s8, s9, s10, s11, s12, s13, s14, s15, s16, s17, s18, s19, s20, s21, s22, s23, s24, s25, s26, s27, s28, s29, s30, s31, s32, s33, s34, s35, s36, s37, s38, s39, s40, s41, s42, s43, s44, s45, s46, s47, s48, s49, s50, s51, s52, s53, s54, s55, s56, s57, s58, s59, s60, s61, s62, s63, s64, s65, s66, s67, s68, s69, s70, s71, s72, s73, s74, s75, s76, s77, s78, s79, s80, s81, s82, s83, s84, s85, s86, s87, s88, s89, s90, s91, s92, s93, s94, s95, s96, s97, s98, s99, s100, s101, s102, s103, s104, s105, s106, s107, s108, s109, s110, s111, s112, s113, s114, s115, s116, s117, s118, s119, s120, s121, s122, s123, s124, s125, s126, s127, s128, s129, s130, s131, s132, s133, s134, s135, s136, s137, s138, s139, s140, s141, s142, s143, s144, s145, s146, s147, s148, s149, s150, s151, s152, s153, s154, s155, s156, s157, s158, s159, s160, s161, s162, s163, s164, s165, s166, s167, s168, s169, s170, s171, s172, s173, s174, s175, s176, s177, s178, s179, s180, s181, s182, s183, s184, s185, s186, s187, s188, s189, s190, s191, s192, s193, s194, s195, s196, 1] |
这时候根据等式我们可以构造出如下的矩阵
这边的L中包含着每组等式对应项对应的系数,R是每个多项式对应的常数项移到等式右边也可以构成一个列向量
这样解这个矩阵方程得到sol,再取他最后的196个元素即可拿到私钥s,另外这边因为s是限制在之间,所以我们还要遍历当中的每一个元素(因为原先运算都是在模q意义下的),当他大于的时候减掉就可以了
exp:
1 | from Crypto.Util.number import long_to_bytes |
这边矩阵L和R赋值的时候使用的是单进程的,如果要求速度更快些(像原先的题意那样,可以使用多进程来进行赋值,这样会快很多,但是多进程我写的好像一直有些问题,有没有大佬教教?(●´ω`●)ゞ)
并非RC4
加密代码:
1 | from Crypto.Util.number import * |
这题确实和对称加密没什么关系,首先我们很容易得到思路,应该是要拿到getrandbits生成的这些8位随机数,然后进行MT19937状态的重构,难点就在于如何得到这些随机数
这边我们对sbox进行测试,测试代码如下:
1 | from Crypto.Util.number import * |
查看一下my_test,我们会发现,他在迭代到两万多次的时候,会趋近于同一个字符,至于是什么,我们可以在0-256进行爆破,因为MT19937是需要32 * 624,也就是19968比特才能还原出状态,对应9比特的话也就是需要2496组,我们取后面的一万组,这完全足够了
然后就是预测的问题,这边我使用的这个板子
1 | https://github.com/JuliaPoo/MT19937-Symbolic-Execution-and-Solver |
exp:
1 | from Crypto.Util.number import long_to_bytes, inverse |