三道后量子题目,记录一下目前能够理解的两道。
*BabyOracle1
题目:
1 | from Crypto.Util.Padding import pad |
题目基于用Goppa codes的McEliece System的实现,会先生成如下数据:
- 私钥矩阵G、P、S
- 公钥矩阵Gp = SGP
- 随机AES密钥key
提供三次交互机会,可以做以下事情:
- A,y:可以输入一条msg,拿到他的AES加密密文
- A,n:拿到flag的AES加密密文
- E,y:可以输入一条msg,拿到他的encode结果
- E,n:拿到AES的key的encode结果
由于只有三次交互机会,四个选项肯定不会全用。而稍微思考下就知道Ay选项显然是零帮助,所以主要是要想剩下几个怎么用。
而题目给出了一个seed值,在给定seed的情况下,其实作为私钥的S、P矩阵都能够确定,而生成矩阵G本身就是定的,所以说等于整个私钥全知道。因此我赛中的考虑是:
第一次机会,输入En,记得到结果为c,就有:
对于McEliece System来说,在知道私钥的情况下解码是这样的:
由于P^(-1)依然仅仅是做了置换,所以error的weight并不会变化,此时就可以对cP^(-1)做decode得到keyS,然后再求逆就得到key了。
第二次机会,输入An,然后用key去解密
然后赛中遇到的问题是sage似乎没有内置函数,可以对goppa codes进行有效的解码,所以捣鼓了好一会儿这个。赛后在yolbby的提示下发现,由于g(x)的度仅有50,记为t,而goppa codes的纠错能力如下:
可以算出就是最多纠50个错,因此对于期望为80的weight来说解码可能不太现实,这才是最根本的原因。
赛后请教了hashhash师傅这个问题,解决方法很简单——这个题和goppa codes并没有那么大的关联,由于有三次机会,所以可以输入两次En,就得到:
作差:
由于e1、e2都是weight在80左右的error,所以说通过这个差值可以确定较大部分error的位置,仅有小部分可能由于位置相同而正好减掉。然而由于对于任意一次的密文都有:
key仅有524个变量,所以我们选择e1、e2差值里为0的位置,他极大可能也是e1、e2共同为0的位置,所以选择其中524个位置去构造一个满秩矩阵方程就可以得到key了。
如果524还是很容易选到错误位置的话,由于key仅有128bit,前面全部由0在填充,所以其实选128组应该也就可以了。靶机关了,放点测试脚本吧:
1 | from Pwn4Sage.pwn import * |
BabyOracle2
题目:
1 | from Crypto.Util.Padding import pad |
题目基于同源,他先是完成了一次完整的SIKE,并且泄露了Bob的私钥skb,然后用共享密钥J的md5作为AES的密钥去加密flag。按顺序整理一下全部知道的值有:
然后对于无限次的oracle来说,选项E肯定是要用一次来拿flag的密文的,主要是看选项K能怎么用。选项K的作用是,我们能发送Eb上的两个点,这里我记为R和S,然后靶机会计算:
并返回如下判断结果:
由于Eba就是共享密钥,所以其实这个返回结果等价于在判断:
所以核心要围绕着怎么构造这样的R、S。
由于Pb1,Pb2都是2^a-torsion的点且阶都为2^a,也就有:
这其实也说明:
所以也就想到一个类似于RSA的LSB-oracle的思路,从最低位开始构造:
此时有:
稍微做下整理是:
此时就可以看出,如果ska-t模2为0,那么后一项由于Pb2阶为2^a的缘故,靶机会返回True;否则靶机会返回False。这就得到了ska的LSB,之后依次类推即可。
exp:
1 | from Pwn4Sage.pwn import * |