题目
from gmpy2 import *
from Crypto.Util.number import *
import random
from secrets import flag
p1=getPrime(128)
q=getPrime(128)
n=p1**2+q**2
print('n=',n)
q=q+63066105847160076051036559850646146794
def gen_prime():
while True:
prime = sum([random.getrandbits(16) * q**i for i in range(6)])
if isPrime(prime):
return prime
p, q, r = [gen_prime() for i in range(3)]
n2=p*q*r
print('n2=',n2)
while True:
p1=next_prime(p1)
p=next_prime(p)
q=next_prime(q)
r=next_prime(r)
if (p-1)%7==0 and (q-1)%7 ==0 and (r-1)%7==0 and (p1-1)%7==0:
break
n3=p1**3*p*q*r
e=7
m=bytes_to_long(flag)
c=pow(m,e,n3)
print('c=',c)
n=86073852484226203700520112718689325205597071202320413471730820840719099334770
n2= 77582485123791158683121280616703899430016469065264033598472741751344256774648355531493586310864150337351815051848231793841751148287075688226384710343269278032576253497728407800522536152937473072438970839941923618053297480433385258911357458745700958378269978384670108026994918504237309072908971746160378531040480539649223970964653553804442759847964633088481940435582792404175653758785321463055628690804551479982557193366035172983893595403859872458966844805671311011033726279121149599533093604586152158331657286488305064843651636225644328162652701896037366058322959361248649656784810609391313
c= 260434870216758498838321584935711394249835963213639852217120194663627852693180232036075839403208332707552953757185774603238436545434522971149891312380970896040823539050341723863717581297624370198483155582245220695123793458717418658539983101802256991837534210806768587736557644192367876024337837658337683388449336720569707094997412847022794461117019613124291022681935875774139147643806772608929174881451749463825639214096129554621195116737322890163556732291246108250543079041977037626755130422879778449546701988814607595746282148723362288451970833214072743929855505520539885650891349827459470540263153862109871050950881032032388185414677989393461533362690744724752363346530211163516319373099647590952338730
分析过程
n
=
p
2
+
q
2
n = p^2+q^2
n=p2+q2,是一个平方和问题, 我们在sage
上使用two_squares()
分解n得到p1
和q1
,q2 = q1+63066105847160076051036559850646146794
,之后利用q2
构造整数环多项式分解n2
得到p,q,r
。然后循环分别取下一个素数直至满足条件为止,经计算e
和phi
的最大公约数为本身e
,进而演变成一个有限域开方问题,最后分别在
G
F
(
p
)
GF(p)
GF(p)、
G
F
(
q
)
GF(q)
GF(q)、
G
F
(
r
)
GF(r)
GF(r)上开7次方根,然后CRT
组合一下可得到flag
。
解题代码
#sage
from Crypto.Util.number import *
import gmpy2
n = 86073852484226203700520112718689325205597071202320413471730820840719099334770
n2 = 77582485123791158683121280616703899430016469065264033598472741751344256774648355531493586310864150337351815051848231793841751148287075688226384710343269278032576253497728407800522536152937473072438970839941923618053297480433385258911357458745700958378269978384670108026994918504237309072908971746160378531040480539649223970964653553804442759847964633088481940435582792404175653758785321463055628690804551479982557193366035172983893595403859872458966844805671311011033726279121149599533093604586152158331657286488305064843651636225644328162652701896037366058322959361248649656784810609391313
c = 260434870216758498838321584935711394249835963213639852217120194663627852693180232036075839403208332707552953757185774603238436545434522971149891312380970896040823539050341723863717581297624370198483155582245220695123793458717418658539983101802256991837534210806768587736557644192367876024337837658337683388449336720569707094997412847022794461117019613124291022681935875774139147643806772608929174881451749463825639214096129554621195116737322890163556732291246108250543079041977037626755130422879778449546701988814607595746282148723362288451970833214072743929855505520539885650891349827459470540263153862109871050950881032032388185414677989393461533362690744724752363346530211163516319373099647590952338730
p1,q1 = two_squares(n)
print(f"p1 = {p1}")
print(f"q1 = {q1}")
q2 = q1+63066105847160076051036559850646146794
poly = sum(e * x^i for i,e in enumerate(Integer(n2).digits(q2)))
(p, _), (q, _) ,(r, _)= poly.factor_list()
p, q ,r= p(x=q2), q(x=q2),r(x=q2)
while True:
p1 = gmpy2.next_prime(gmpy2.mpz(p1))
p = gmpy2.next_prime(gmpy2.mpz(p))
q = gmpy2.next_prime(gmpy2.mpz(q))
r = gmpy2.next_prime(gmpy2.mpz(r))
if (p-1)%7==0 and (q-1)%7 ==0 and (r-1)%7==0 and (p1-1)%7==0:
break
e = 7
R.<x> = Zmod(p)[]
f = x^e-c
f = f.monic()
results1 = f.roots()
R.<x> = Zmod(q)[]
f = x^e-c
f = f.monic()
results2 = f.roots()
R.<x> = Zmod(r)[]
f = x^e-c
f = f.monic()
results3 = f.roots()
for i in results1:
for j in results2:
for l in results3:
param1 = [int(i[0]),int(j[0]),int(l[0])]
param2 = [p,q,r]
m = CRT_list(param1,param2)
flag = long_to_bytes(int(m))
if b'DASCTF' in flag:
print(flag)
break
flag:
DASCTF{I_d0nt_kn0w_wh@t_i_w@nt_t0_d0_ju3t_d0_it_attack_we@k_prim4!!!}
【喜欢一个人,只喜欢一个人才是对的。】