XD
magic_lfsr
题目:
1 | from Crypto.Cipher import AES |
题目基于LFSR,随机生成128bit的key作为初始state,并用相同的key和四个不同的mask共同初始化四个不同的lfsr,之后给出270组combine过的lfsr,要求还原key来解AES,其中combine过程是这样的:
1 | def ff(x0, x1, x2, x3): |
这种combine的LFSR肯定首先需要测一下相关性,测试发现输出和四个lfsr的相关性分别是:
1 | 7/16 |
既然有相关性,比较自然的会想到correlation attack,然而由于key有128bit,所以直接用correlation attack需要爆2^128,显然不太可能,所以要用也得用fast correlation attack可能才行。
这个时候觉得完了,因为fast correlation attack我真的还没有学会,也从来没有真正意义上的自己调用过,所以想着多半是打不出了。
然而细看一下发现了一个盲点:给出的数据只有270组,怎么想调fast correlation attack估计都是不够用的,所以应该是其他方法。这个时候想到了前不久HitconCTF学到的一个零化子的思路,可以参考:
HITCON CTF 2024 Qual Crypto Writeup - Tanglee’s Blog
首先用sage求整个combine过程的真值表,并转化为一个简单一些的布尔函数看看形式:
1 | from sage.crypto.boolean_function import BooleanFunction |
1 | x0*x1*x2*x3 + x0*x1*x3 + x0 + x1*x2*x3 + x1*x3 + x2 + x3 |
如果我们能找到另一个布尔函数g使得下式恒成立:
称这样的g为annihilator,那么我们就可以得到一个事实:当f为1的时候g一定为0。而这样的g可以用如下的方式找到:
1 | g = BooleanFunction(F).algebraic_immunity(annihilator = True) |
1 | (1, x0 + x2 + x3 + 1) |
其中第二个返回值就是g,第一个返回值是g的degree。既然g的degree是1,这也就是说对于output中为1的地方,我们都可以拥有一个不含x1的线性等式是:
实际上测出来上面的多项式似乎应该反过来才对,也就是:
而由于四个LFSR的每个状态其实都是初始key的线性组合,比如对于LFSR1,其迭代过程可以写成一个线性等式:
那么记初始状态R和递推矩阵Li如下:
那假如output的第i个bit是1的话,其实就代表着如下线性等式成立:
下标0指得到向量的第一个值
因此output每有一个bit,我们就可以搜集到关于初始状态R的128个bit的线性等式。而实际上output共有127个bit,所以可以搜集到127组等式,虽然还是不满秩,但是小爆一下kernel就可以找到key了。
exp:
1 | from sage.crypto.boolean_function import BooleanFunction |
*decipher Diffie-Hellman
题目描述:
1 | 程序加密过程中忘记了键盘输入的内容,请根据已知的信息破译出flag |
hint:
1 | 有限空间爆破 |
题目:
1 | import random |