和0x401的师傅们参加了虎符,进入了决赛,被带飞的感觉真好2333。本篇将持续记录对赛题的复现。
RRSSAA
题目:
1 | from random import randint |
解题思路
part 1:
p,q的生成过程有缺陷,具体为p和q大约相差1 << int(nbits beta),那么可以爆破差值附近bit的值,来获得准确的q-p,利用(q-p)^ 2 + 4pq开方来获得p+q(iroot有解的时候说明q-p正确)。拿到p+q以后可以联立pq = n解出p,q,我使用的z3。
1 | # 分解p、q的代码(非预期) |
part2:
实际上是基于lucas序列的公钥密码体制LUC,原理详见“一种新的基于 Lucas 序列的公钥密码体制”这篇论文。最关键的部分是要理解lucas序列的元素递推组成一个群,其满足逆元的性质,比如递推e次得到的元素和递推d次得到的元素一样,将d记作e的逆元。de是在phi上互为逆元,phi的求法需利用勒让德符号,详见论文。
所以part2的关键在于求出r,再将r带入lucas递推公式求出v。
可利用的关系为:
注意:1、d为e模phi的逆2、由于v和c同余n所以seq(v,d)也要建立在模n上计算3、r小于n所以modn^2和modn结果是一致的4、最后求出r以后再将r,e带入lucas序列函数seq中求出v。在带入seq计算的时候,为了迅速计算,需要用矩阵快速幂优化。但由于sage的矩阵乘法已经优化为快速幂了,所以不需要自己实现。找矩阵系数的方法可以这样:
![](/.com//03/27/%E8%99%8E%E7%AC%A6CTF2022/1.png)
同时,sage也有lucas序列函数,sage.rings.finite_rings.integer_mod import lucas
part3:类同态解密
1 | from Crypto.Util.number import inverse, long_to_bytes |