[*CTF 2022]ezRSA

这是一道经典的对于p的处理和获得部分p值的patral-p问题求解,这种求解方法对于大量类似题型有极大的借鉴意义。

from Crypto.Util.number import getStrongPrime
from gmpy import next_prime
from random import getrandbits
from flag import flag

p=getStrongPrime(1024)
q=next_prime(p^((1<<900)-1)^getrandbits(300))
n=p*q
e=65537

m=int(flag.encode('hex'),16)
assert m<n
c=pow(m,e,n)

print(hex(n))
#0xe78ab40c343d4985c1de167e80ba2657c7ee8c2e26d88e0026b68fe400224a3bd7e2a7103c3b01ea4d171f5cf68c8f00a64304630e07341cde0bc74ef5c88dcbb9822765df53182e3f57153b5f93ff857d496c6561c3ddbe0ce6ff64ba11d4edfc18a0350c3d0e1f8bd11b3560a111d3a3178ed4a28579c4f1e0dc17cb02c3ac38a66a230ba9a2f741f9168641c8ce28a3a8c33d523553864f014752a04737e555213f253a72f158893f80e631de2f55d1d0b2b654fc7fa4d5b3d95617e8253573967de68f6178f78bb7c4788a3a1e9778cbfc7c7fa8beffe24276b9ad85b11eed01b872b74cdc44959059c67c18b0b7a1d57512319a5e84a9a0735fa536f1b3

print(hex(c))
#0xd7f6c90512bc9494370c3955ff3136bb245a6d1095e43d8636f66f11db525f2063b14b2a4363a96e6eb1bea1e9b2cc62b0cae7659f18f2b8e41fca557281a1e859e8e6b35bd114655b6bf5e454753653309a794fa52ff2e79433ca4bbeb1ab9a78ec49f49ebee2636abd9dd9b80306ae1b87a86c8012211bda88e6e14c58805feb6721a01481d1a7031eb3333375a81858ff3b58d8837c188ffcb982a631e1a7a603b947a6984bd78516c71cfc737aaba479688d56df2c0952deaf496a4eb3f603a46a90efbe9e82a6aef8cfb23e5fcb938c9049b227b7f15c878bd99b61b6c56db7dfff43cd457429d5dcdb5fe314f1cdf317d0c5202bad6a9770076e9b25b1

首先,我们分析题目,可知p是随机的,q是基于p生成的,其中p和q的后124为bit数值相同,q后900bit与(1<<900)-1)^getrandbits(300)进行异或求得,其中,中间600bit的部分我们可以求出。

第一步:

求出前124bit

p = k1 * (2^900) + k2

q = k1 * (2^900) + (2^900 - k2) +k3

n = p*q = k1^2 * (2^1800) + 2k1k2 * (2^900) + k1 * (2^1800) + L(可忽略不计)

我们即可对n//2^1800,即只剩下k1一个未知量,即可求解。

PR.<m> = PolynomialRing(Zmod(n))
f = int(n,16)//(2^1800) - m^2 - m
x = f.small_roots()
print(x)

top_bits = 20226195070633070235386534147535171929

 第二步

我们可知,当pq越相接近时,pq相乘的值越大。所以,我们一开始将p后900bit全部设置为1,而q全部为0,进行乘法运算与n进行大小比较,这样不断接近n值,从而求得中间的600bit数值

p = top_bits<<900 | (2**900 - 1)
q = top_bits<<900
# Start from 125th bits (1024-125)
for i in range(899, 301, -1):
	cur = 1<<i
	# Swap p to 0 and q to 1
	# if less than n then is correct order
	# else no changes
	if (p^cur) * (q^cur) < n:
		p ^= cur
		q ^= cur
print(hex(p))
print(hex(q))

 最后,就是典型的部分p泄露脚本带入即可。

PR.<x> = PolynomialRing(Zmod(n))
f = p + x
m = f.small_roots()
print(int(p+m[0]))

sb​​​​​​​starctf2022/exp.sage at main · sixstars/starctf2022 (github.com)(标准wp可见)

  • 1
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值