crtrsa
来自2021巅峰极客,题目:
from secret import flagn,p,q
#p and q are two primes generated by getPrime
import random
def key_gen():
while True:
dp = random.randint(1,1<<20)
dq = random.randint(1,q-1)
if gcd(dp, p - 1) == 1 and gcd(dq, q - 1) == 1:
d = crt([dp,dq],[p-1,q-1])
phi = (p-1)*(q-1)
R = Integers(phi)
e = R(d)^-1
return p*q,e
n,e = key_gen()
print e
print n
print pow(flagn,int(e),n)
'''
e = 2953544268002866703872076551930953722572317122777861299293407053391808199220655289235983088986372630141821049118015752017412642148934113723174855236142887
N = 6006128121276172470274143101473619963750725942458450119252491144009018469845917986523007748831362674341219814935241703026024431390531323127620970750816983
flag = 4082777468662493175049853412968913980472986215497247773911290709560282223053863513029985115855416847643274608394467813391117463817805000754191093158289399
'''
思路:看到dp的范围,1到1<<20,不大,猜测可以爆破,等于dp知道了,接着往已知的公式入手进行推导,得到某个式子与n=p*q联立,取公因数得到p或q。
推导过程:
已知,
将两式子左右相乘,
再由欧拉定理,若存在gcd(a,x)=1,则有,取,且与p互素,则(先两侧同时加上k次方,再同时乘上一个x)
综上有与,通过两个关系可以得到p,便可以解了。代码如下:
from gmpy2 import *
from Crypto.Util.number import *
import libnum
e = 2953544268002866703872076551930953722572317122777861299293407053391808199220655289235983088986372630141821049118015752017412642148934113723174855236142887
N = 6006128121276172470274143101473619963750725942458450119252491144009018469845917986523007748831362674341219814935241703026024431390531323127620970750816983
flag = 4082777468662493175049853412968913980472986215497247773911290709560282223053863513029985115855416847643274608394467813391117463817805000754191093158289399
x = 1000000001
t0 = pow(x,e,N)#把这部分单独拿循环外头计算,爆破能快一点
for dp in range(1,1<<20+1):
t = pow(t0,dp,N)-x
p = gcd(t,N)
if p != 1:
print(p)
#p = 88483113499234291234797595363172914275282163218450540253170700235627922981203
q = N // p
try:
d = invert(e,(p-1)*(q-1))
m = pow(flag,d,N)
print(long_to_bytes(m))
except:
pass
break