Matrices Matrices Matrices
1 | from sage.all import GF, Matrix |
已知$a_{70 \times 30}*s_{30 \times 1}+e=b$,已知a,b求s
由于q是271,而我们的flag是在[32,256]的,所以不能直接对flag进行格规约,只能规约出e后再对方程进行求解得到flag,所以构造下面的格
$\begin{bmatrix}k_0&k_1&\dots&k_{m-1}&-1\end{bmatrix}\times\begin{bmatrix}a_{0,0} & a_{1,0} & \dots & a_{m-1,0} \\a_{0,1} & a_{1,1} & \dots & a_{m-1,1} \\\vdots & \vdots & \ddots & \vdots \\a_{0,n-1} & a_{1,n-1} & \dots & a_{m-1,n-1} \\p & & & \\& p & & \\& & \ddots & \\& & & p\end{bmatrix}=\begin{bmatrix}e_0&e_1&\dots&e_{m-1}\end{bmatrix}$
代码如下:
1 | from pk import * |
key in the haystack
1 | from Crypto.Util import number |
先理解题目大意,前面就是一个常规的rsa加密,所以攻击点肯定是后面add_hay对于p,q的一个泄露
1 | def add_hay(stack, straw): |
仔细阅读add_hay函数,$stack[i,j]=stack[i-1,j]+straw\times stack[i-1,j-1]$,所以
$$
\sum_{j=1}^n{stack[i,j]}=\sum_{j=1}^n{stack[i-1,j]+straw\times stack[i-1,j-1]}=(1+straw)\times \sum_{j=1}^n{stack[i-1,j]}
$$
设$f(x)=\sum_{j=1}^n{stack[x,j]}$,所以$f(x)=(1+straw)*f(x-1)$,题目中给出的$stack$就是$f(x)$的系数,现在分析清楚$stack$后,回去阅读源码可以看出来p,q都经
过了两次了add_hay,其他素数只经过了一次,所以
$$
f(x)=(1+p)^2\times(1+q)^2\times (1+x_0)\times \dots \times (1+x_{63})
$$
我们要求的素数就是方程$f(x)$的根,但是直接对这个方程求解是求解不出来的,所以考虑对$f(x)$求导,设$g(x)=(1+x_0)\times \dots \times (1+x_{63})$
$$
f’(x)=2(1+p)\times 2(1+q) \times g(x)+(1+p)^2\times(1+q)^2\times g’(x)=(1+p)\times (1+q)\times (4\times g(x)+(1+p)\times (1+q)\times g’(x))
$$
所以$gcd(f(x),f’(x))=(1+p)\times (1+q)$
然后对于上的方程求解就可以拿到p,q了,再进行常规的rsa解密即可
代码如下:
1 | from output import * |
Lightning Fast Scrambling
1 | from hashlib import sha256 |
题目大意是生成一个key然后对flag进行加密,我们需要通过密文还原key后进行解密即可
主要是观察secret_byte_stream函数
1 | def secret_byte_stream(key): |
第一个a就是x的低八位,key有8字节长,的对于后面的a我们先设$x=\sum_{i=0}^{64}e_i\times 2^i,e_i\in [0,1]$
$$
a=x_{0-7}\\
y=e_8+e_9\times 2+ \dots+e_{63}\times 2^{55}\\
x = e_8+e_9\times 2+ \dots+e_{63}\times 2^{55}\\
y=e_9+e_{10}\times 2 \dots+e_{63}\times 2^{54}\\
a=x_{0-7}\oplus x_{9,16}\\
y=e_{23}+e_{24}\times 2 \dots+e_{63}\times 2^{40}\\
a=x_{0-7}\oplus x_{9-16} \oplus x_{23-30}\\
y=e_{40}+e_{41}\times 2 \dots+e_{63}\times 2^{23}\\
a=x_{0-7}\oplus x_{9-16} \oplus x_{23-30}\oplus x_{40,47}\\
x=e_8+e_9\times 2+ \dots+e_{63}\times 2^{55}+a\times 2^{56}\\
$$
所以在前面8次的secret_byte_stream就是获得key的值,我们已知message的前缀是KSUS{,所以可以通过异或的方式还原key的前40比特,而key是63个比特,所以还需要遍历23个比特就可以拿到正确的key还原flag
代码如下
1 | import base64 |
key in the big haystack
1 | from Crypto.Util import number |
这个题和前面的key in the haystack类似,只是进行的add_hay次数更多了,数据量更大了,所以直接使用之前的方法是不行的,然后考虑使用hgcd,但是发现由于数据量太大了,4gb的内存仍然是会跑崩溃的,所以需要采取优化,将多项式从整数环更换到一个有限域下进行hgcd,将多项式取模后,然后可以通过gcd求得$(p+1)\times(q+1)$
代码如下:
1 | from big_output import * |
Feistel <3
1 | from Crypto.Util.number import bytes_to_long, getPrime, long_to_bytes |
主要是encrypt_block函数
1 | if shortcut and sub_block_1 == b"\xff\xff": |
所以如果sub_block_1等于b"\xff\xff"就会提前跳出循环,输出密文,我们可以依次拿到sub_block_2的值,也就是f(sub_block_3, round_key, modulus)的值了
1 | def f(sub_block, round_key, modulus): |
$$
(subblock+(65537^{key}\bmod N))\bmod (1<<17-1)
$$
由于知道subblock,上面式子的未知数只有一个key了,但是由于$65537^{key}\bmod N$后是远大于$1<<17-1$的,但是无法使用rsa的解密方法,只有通过遍历两个字节的key寻找正确的key,这个部分可以先进行预处理来优化。
然后通过改变明文,使得加密函数在指定的循环次数后跳出就可以拿到对应的密文,可以从密文中拿到sub_block_2,但是sub_block_3需要的是上一组的,我们可以自己通过现在已知的key自己跑一下函数拿到sub_block_3,但是对于同一组sub_block_2,sub_block_3可能有多个key满足,所以用dfs即可找到正确的key。
找到key后的问题就是这个题只给了加密函数,没有解密函数,还需要自己写一个解密函数,由于对于相同的位置可能有多个字符满足解密的条件,所以有的时候解密结果会有几个字符是乱码,有乱码的时候就需要对那两个字符进行遍历了,然后通过加密通过密文就可以找到正确的flag。
1 | def decrypt_block(cipher_block, key, modulus, rounds=8): |
代码如下:
1 | from Crypto.Util.number import * |
Back the Hank
1 | The Kindasus Bank prioritizes the security of its users by implementing two separate databases to store partial user information. |
题目只有这些,也没有附件,感觉需要web的相关知识,算了不看了😁😁
总体来说题目质量还是不错的,国际赛还是挺好玩的
如果您喜欢此博客或发现它对您有用,则欢迎对此发表评论。 也欢迎您共享此博客,以便更多人可以参与。 如果博客中使用的图像侵犯了您的版权,请与作者联系以将其删除。 谢谢 !