cdcq

梦幻小鱼干

导航

【攻防世界】babyrsa

这题表面上是一个裸rsa题,给了n,e和c,但实际上n不能分解

但是题目给了个服务器,允许你输入密文,然后告诉你对应的明文的奇偶性

这题我没想出来,看题解提示了两次才做出来,就直接说解法了:

知道m的奇偶性是没什么卵用的,但是如果知道2*m的奇偶性就很有用了

由于m<n,所以如果2*m<n,那么2*m一定是偶数,但是如果2*m>=n,注意服务器检测的实际上是2*m%n=2*m-n,所以会判断为奇数

那么如果2*m<n,就有m<=n/2,如果2*m>=n,有m>=n/2

这样就可以二分了

具体怎么二分呢,其实很简单

最开始l=0,r=n,每次让c*=2^e(让m*=2),然后判断c的奇偶性

如果c是偶数,就让r=mid,否则让l=mid

最后不用考虑选l还是r作为答案,因为l和r也就差1,眼睛可以直接看出来

正确性可以这样来考虑:

第一次判断的时候,根据奇偶性可以划分到n/2的两边

第二次由于m2=m*4,如果之前划到左边就不说了,如果划到右边,那么可以把m看成n/2+m'

这样就有4*(n/2+m')=2*n+4*m',这样就可以把m'划到n/4的左边或者右边

(注意,上一次的奇偶性对下一次的判断是没有关系的,因为m乘2了,所以上次的n/2对下次没有影响,这里我想错了,看了题解发现)

 

代码:

 1 from pwn import *
 2 from Crypto.Util.number import *
 3 
 4 # sh = remote('220.249.52.134', 35781)
 5 
 6 e = 0x10001
 7 n = 0x0b7...6db
 8 c = 0x4f3...be0
 9 
10 left, right = 0, n
11 last = 0
12 while left + 1 < right:
13     print(left, right)
14     mid = (left + right) >> 1
15     c = c * pow(2, e, n) % n
16     sh = remote('220.249.52.134', 48658)
17     for i in range(4):
18         s = sh.recvline()
19 
20     sh.sendline(str(hex(c)))
21     s = sh.recvline()
22     if s[0] == ord('e'):
23         right = mid
24     else:
25         left = mid
26 
27 ans = left
28 s = ''
29 while ans > 0:
30     s = s + chr(ans % 256)
31     ans = ans // 256
32 
33 print(s)
34 
35 '''
36 for i in range(4):
37     s = sh.recvline()
38     print(s)
39 
40 sh.sendline(str(c))
41 s = sh.recvline()
42 print(s)
43 '''
View Code

 

posted on 2020-12-22 16:46  cdcq  阅读(65)  评论(0编辑  收藏