lift
题目描述:
import os
import gmpy2
from Crypto.Util.number import *
import random
from secrets import flag
def pad(s,l):
return s + os.urandom(l - len(s))
def gen():
g = getPrime(8)
while True:
p = g * random.getrandbits(138) + 1
if isPrime(p):
break
while True:
q = g * random.getrandbits(138) + 1
if isPrime(q):
break
N = p ** 5 * q
phi = p ** 4 * (p - 1) * (q - 1)
d = random.getrandbits(256)
e = inverse(d, phi)
E = e * g
hint = gmpy2.gcd(E, phi)
return N, E, hint
flag = pad(flag,64)
m = bytes_to_long(flag)
n,e,hint = gen()
c = pow(m,e,n)
print(f'hint = {hint}')
print(f'n = {n}')
print(f'e = {e}')
print(f'c = {c}')
# hint = 251
# n = 108960799213330048807537253155955524262938083957673388027650083719597357215238547761557943499634403020900601643719960988288543702833581456488410418793239589934165142850195998163833962875355916819854378922306890883033496525502067124670576471251882548376530637034077
# e = 3359917755894163258174451768521610910491402727660720673898848239095553816126131162471035843306464197912997253011899806560624938869918893182751614520610693643690087988363775343761651198776860913310798127832036941524620284804884136983215497742441302140070096928109039
# c = 72201537621260682675988549650349973570539366370497258107694937619698999052787116039080427209958662949131892284799148484018421298241124372816425123784602508705232247879799611203283114123802597553853842227351228626180079209388772101105198454904371772564490263034162
题目分析:
n
=
p
5
∗
q
e
∗
d
−
1
=
k
∗
p
h
i
e
∗
d
−
1
≡
0
m
o
d
p
4
e
∗
d
−
1
=
k
1
∗
p
4
,
可以看成是
n
的一部分
之后
c
o
p
p
e
r
求出
d
p
4
=
g
c
d
(
e
∗
d
−
1
,
n
)
,至此得到
p
,
q
n = p^5 * q\\ e * d - 1 = k * phi\\ e * d - 1 \equiv 0 \mod p^4\\ e * d - 1 = k_1 * p^4,可以看成是n的一部分\\ 之后copper求出d\\ p^4 = gcd(e * d - 1,n),至此得到p,q\\
n=p5∗qe∗d−1=k∗phie∗d−1≡0modp4e∗d−1=k1∗p4,可以看成是n的一部分之后copper求出dp4=gcd(e∗d−1,n),至此得到p,q
可以看看这篇文章
也可以参考参考论文
from gmpy2 import *
hint = 251
g = 251
n = 108960799213330048807537253155955524262938083957673388027650083719597357215238547761557943499634403020900601643719960988288543702833581456488410418793239589934165142850195998163833962875355916819854378922306890883033496525502067124670576471251882548376530637034077
e = 3359917755894163258174451768521610910491402727660720673898848239095553816126131162471035843306464197912997253011899806560624938869918893182751614520610693643690087988363775343761651198776860913310798127832036941524620284804884136983215497742441302140070096928109039
c = 72201537621260682675988549650349973570539366370497258107694937619698999052787116039080427209958662949131892284799148484018421298241124372816425123784602508705232247879799611203283114123802597553853842227351228626180079209388772101105198454904371772564490263034162
PR.<x> = PolynomialRing(Zmod(n))
f = (e//251) * x - 1
res = f.monic().small_roots(X = 2 ^ 256,beta = 0.44)[0]
p = iroot(gcd(ZZ(f(res)),n),4)[0]
q = n // (p) ** 5
print(p,q)
得到p,q后发现e和phi不互素
这里运用类似有限域开方的解法
参考:这里
from gmpy2 import *
from Crypto.Util.number import *
import itertools
n = 108960799213330048807537253155955524262938083957673388027650083719597357215238547761557943499634403020900601643719960988288543702833581456488410418793239589934165142850195998163833962875355916819854378922306890883033496525502067124670576471251882548376530637034077
e = 3359917755894163258174451768521610910491402727660720673898848239095553816126131162471035843306464197912997253011899806560624938869918893182751614520610693643690087988363775343761651198776860913310798127832036941524620284804884136983215497742441302140070096928109039
c = 72201537621260682675988549650349973570539366370497258107694937619698999052787116039080427209958662949131892284799148484018421298241124372816425123784602508705232247879799611203283114123802597553853842227351228626180079209388772101105198454904371772564490263034162
p,q=69367143733862710652791985332025152581988181 ,67842402383801764742069883032864699996366777
n_list = [p ** 5,q]
res=[]
for pi in n_list:
d = inverse(int(e//251),euler_phi(pi)) # 对n_listt 每一个 pi 求欧拉函数
m = pow(c,d,pi) # m = mm^251
res.append(Zmod(pi)(m).nth_root(251, all=True)) # nth_root # 最后一部分把 e 的公因数 251 去除之后用 sage 的 nth_root 直接开根即可
# 在每一个pi环里 找到可以开251次方的放进result里面
# 在环里开251次方
# 会出来 2 个 list表 对应每个 pi
for vc in itertools.product(*res):
_c = [int(x) for x in vc]
m = long_to_bytes(int(crt(_c, n_list)))
if b"flag" in m:
print(m)
# flag{4b68c7eece6be865f6da2a4323edd491}
关键词:
coppersmith,
n
=
p
r
∗
q
n = p^r * q
n=pr∗q, e与phi不互素,nth_root()
学艺不精,有待提高