TCTF Quals 2020
baby ring
当时打Quals的时候还没怎么开始密码学,全程划水233,看了rxz大佬的exp发现他是拿线性基做的,这就是OI大佬吗,i了i了,但由于我是条懒狗,所以并没有去学线性基,就还是用最基本的线代知识做。
分析题目,可知是需要输入64组x,然后server计算
仔细思考就会发现,这其实是个模线性方程问题,即构造矩阵
这时再考虑
1 | from winpwn import * |
Simple Curve
这个题涉及到概念 hyperelliptic curve,具体的理论我在Way to Crypto中已添加,此处不做赘述,这篇wp讲的很好,推荐一看。
这里的曲线是基于
这里使用的超椭圆曲线即为:
之前的paper中提供了一种计算Jacobian阶的算法(看到Balsn是用的Magma,可以直接算)
Magma代码:
1 | P<x> := PolynomialRing(GF(2^256)); |
具体算法步骤可以参见Way to Crypto中的描述和exp中的代码
这里的F.fetch_int(n) 函数的意思是将整数n转为二进制序列,然后将其作为域F上多项式
而decode时的这个操作:
1 | x = [i.integer_representation() for i in x] |
其中于integer_representation()函数为fetch_int()的逆函数,即是将多项式转为了一个整数。
exp如下:
1 | from Crypto_tools import * |
TCTF2020 Final
Obviously Transfer
本题的关键是将
流程为:
- 先获取一组数据x0,x1,然后直接将x0发给server,则返回的m0p即为m0,则通过生成m0r再与m1p异或可以得到
- 考虑到其中
,考虑 ,则有 ,从而转化为已知enc,求m问题 - 想到可以通过partial oracle来实现,至于获取具体的low bit,是通过m0p的低位和m1p的高位异或而确定的,因为m0p的低位为
,而m1p的高位与m1相同概率很大(因为k1模n,其高位均匀分布,故当样本增多的时候产生影响不断降低),而m1的高位又与m0相同,故重复一定次数,根据概率即可确定lsb
exp如下:
1 | from winpwn import * |
由于其是有概率的,所以可能需要多试几次,成功时效果如下:
本地大概需要25秒左右可以跑出一字节flag。
CryptoCTF 2020
Decent RSA
这题学到了神奇的套路233,如果将n转化为
此题中,n在
1 | x^592 + x^589 + 2*x^559 + x^547 + 2*x^501 + 2*x^498 + 2*x^492 + 2*x^475 + 2*x^472 + 4*x^468 + 2*x^456 + 4*x^444 + 4*x^442 + 2*x^430 + 2*x^420 + 4*x^401 + 4*x^375 + 8*x^353 + 4*x^329 + 8*x^327 + 2*x^311 + 4*x^303 + 6*x^296 + 2*x^293 + 4*x^263 + 2*x^251 + 4*x^220 + 8*x^205 + 4*x^196 + 4*x^194 + 8*x^179 + 8*x^148 + 4*x^124 + 4*x^15 + 8 |
分解得p,q:
之后分解即可。
test demo:
1 | bits = 256 |
emmmmm,然而找上万轮也没找到2333,本来还想着可以拿来出题的233
abbout
这个题提醒了我密码中也要善用数学归纳法。。。
通过输出其实可以发现每个分数的倒数的绝对值的整数部分即是对应的字符的ascii值,依次写出逆函数,则有exp如下:
1 | import string |
以me函数分析其数学原理,以数列
通过数学归纳法,不难证明对于
埋个坑,下次用数学归纳法整个数列题玩玩2333
strip
终于用了点分析里的技巧2333,其实也是很常用的技巧,观察数列
则
然后就可以写出a的递推式了:
1 | def b(n): |
从而得到n:
1 | for i in range(2, 2**10): |
emmmmm但这个n太大了,yafu分解不了,factordb输入都不行,此时想到n其实是
1 | bits = bin(my_a(606))[::-1] |
计算phi,考虑到n太大了。。所以考虑使用n的因子
1 | def get_phi_a(index, return_list=False): |
其中index即为
然后思路有两种,一种是直接找到足够大的index,另一种是找两个大点的素数然后CRT,遗憾的是index到200的时候仍然无法获得flag,于是改为第二种:
1 | factors_list = list(get_phi_a(606, True)) |
得到所有prime大概需要7,8分钟,最终得到flag:
N1CTF 2020
easy RSA
本题有两层,一层是分解n,一层是恢复LWE,恢复LWE相对简单,与攻击GGH差不多,直接LLL后CVP即可,难点在于利用p,q生成弱点分解n。
则有
即有
目标向量为
则其范数上界为
则由Minkowski定理得
而
故知Minkowski上界满足,但仍需要满足格内各基向量均大于目标向量范数,即需要在原有矩阵上乘均衡系数T,可知
构造代码如下:
1 | M = matrix(ZZ, 10, 10) |
得到解向量后,直接多项式分解即可得到
1 | # factor n |
接下来恢复LWE即可,考虑
可知有
故构造格:
利用此格的正交基寻找CVP,改变s,发现
1 | from Crypto.Util.number import * |