先在此感谢Kicky_Mu的博客,保留了很多赛事的题面,让我的学习方便了很多
我玩青水的
题面:
1 | from Crypto.Util.number import * |
分析:
e = 2
,二次剩余,
我最开始的想法是二次剩余的特殊的情况,但是测试发现p%4!=3
,所以pass
然后也想到了rabin加密
,但是发现p无法分解,所以pass
最后,直接解有限域下的多项式方程即可
exp:
1 | from Crypto.Util.number import * |
Hard_ECC
题面:
1 | from flag import flag |
分析:
构造了一个椭圆曲线,进行了一次曲线的标量乘法,ECDLP秒了
主要注意这个secret是小端序
,所以最后的结果要倒置
exp:
1 | from Crypto.Util.number import * |
OEIS2
题面:
1 | from hashlib import * |
分析:
主要就是要算个upper的阶乘,用sage里的**factorial()**即可
exp:
1 | from hashlib import * |
fake_n
题面:
1 | from Crypto.Util.number import * |
分析:
fake_n_list:15个32bit的素数和一个n
fake_n是由这十六个因子乘积得到的,really_n则是前15个素数乘积得到的
直接用sage内置的factor得到所有因子,注意此时得到的因子是15个素数和p,q,一共17个
可以用itertools库中的combinations生成所有可能的组合,爆破一下就行
exp:
1 | from Crypto.Util.number import * |
begin_rsa
题面:
1 | from Crypto.Util.number import * |
分析:
题目生成两个素数p~1~,q~1~,并计算了 它们异或结果的低402位并记作p1_xor_q1_low,并判断了此值的十进制范围
取此值的next_prime为p2,并将p2的十进制前半段和后半段交换得到q2
-
我们要先求出p2,q2得到p1_xor_q1_low,再求出p1,q1
-
由前后半段交换我们可以记为:
$$
p_2\ =\ 10^{61}*a\ +\ b\
q_2\ =\ 10^{61}*b\ +\ a
$$ -
然后就有:
$$
n_2\ =\ (10^{61}*a+b)(10^{61}b+a)\
\
n_2\ =\ 10^{122}ab+10^{61}(a^2+b^2)+ab
$$1
2
3
4
5
6
7
8
9a b
* b a
-----------------
abh abl
aah aal
bbh bbl
abh abl
n[:60] n[60:121] ... n[-61:]可以发现n2的十进制低61位就是ab的低61位,高61位就是ab的高61位
考虑到有一位的进数影响,因此需要爆破一下
-
有了ab后就可以得到a^2^+b^2^,自然就可以解出a和b了,那么也就有了p1_xor_q1_low
-
最后,剪枝+coppersmith
exp:
1 | from Crypto.Util.number import * |
PAD
题面:
1 | import random, math |
同时给了一个附件GIFT.txt
分析:
$$
c\ =\ (e_2^{mbits}+m^{e_2})^{e_1}\ mod\ n
$$
其中mbits约等于512,考虑一般是不到的,我们取511
1<= e~1~ <=8,2<=e~2~<=8
但是直接去解并不容易,考虑可不可以找一组简单的数据直接解
在txt文件中找到了一组很好算的数据==>e~1~ = 1,e~2~ = 2
$$
c\ =\ (2^{511}+m^{2})\ mod\ n
$$
直接做差开方即可
exp:
1 | from Crypto.Util.number import * |
PAD_revenge
题面:
1 |
|
附件GIFT.txt
分析:
其实最重要的区别就是n_bits = 512变小了,以及e1*e2 >2
那么对于
$$
(e_2^{mbits}+m^{e_2})^{e_1}\ >\ n
$$
所以不能像PAD一样解,但可以从txt文件中找到多组(e1,e2)相等的数据,直接
中国剩余定理,启动!!!
exp:
这里找(e1,e2) = (3,3)的来解,解出结果后开三次方根即可
1 | from Crypto.Util.number import * |
baph
题面:
1 | from base64 import b64encode |