[长安杯 2021]checkin

chall.py

from Crypto.Util.number import *
from secret import flag
p = getPrime(1024)
q = getPrime(16)
n = p*q
m = bytes_to_long(flag)
for i in range(1,p-q):
    m = m*i%n
e = 1049
print(pow(2,e,n))
print(pow(m,e,n))
#4513855932190587780512692251070948513905472536079140708186519998265613363916408288602023081671609336332823271976169443708346965729874135535872958782973382975364993581165018591335971709648749814573285241290480406050308656233944927823668976933579733318618949138978777831374262042028072274386196484449175052332019377
#3303523331971096467930886326777599963627226774247658707743111351666869650815726173155008595010291772118253071226982001526457616278548388482820628617705073304972902604395335278436888382882457685710065067829657299760804647364231959804889954665450340608878490911738748836150745677968305248021749608323124958372559270

这里有个技巧 可以用2^e-pow(2,e,n)=k*n算出k*n然后factor.db分解 根据p,q范围得出p,q
就可以解出m
然后利用威尔逊定理
可以将inv((p-q-1)!,p)转换为-1*(p-q)*...*(p)
这里将模数从n换成了p 可以得到flag(只是这里转换是严谨的吗?会不会损失m精度?虽说从做题角度考虑只能这么做)
solution.py

from Crypto.Util.number import *
from sympy import *
from primefac import *
from gmpy2 import *
from tqdm import tqdm

c1 = 4513855932190587780512692251070948513905472536079140708186519998265613363916408288602023081671609336332823271976169443708346965729874135535872958782973382975364993581165018591335971709648749814573285241290480406050308656233944927823668976933579733318618949138978777831374262042028072274386196484449175052332019377
c2 = 3303523331971096467930886326777599963627226774247658707743111351666869650815726173155008595010291772118253071226982001526457616278548388482820628617705073304972902604395335278436888382882457685710065067829657299760804647364231959804889954665450340608878490911738748836150745677968305248021749608323124958372559270
e = 1049
kn = 2**e - c1
# print(kn)
q = 34211
p = 170229264879724117919007372149468684565431232721075153274808454126426741324966131188484635914814926870341378228417496808202497615585946352638507704855332363766887139815236730403246238633855524068161116748612090155595549964229654262432946553891601975628848891407847198187453488358420350203927771308228162321231
"""
我们已经知道了 flag*(p-q-1)! mod n
由威尔逊定理 有 (p-1)! 同余 -1 mod p
可以反推求逆
只是这里还有个小问题 p和n的模数不一定能随意转换
""" 
n = p*q
phi = (p-1)*(q-1)
d = modinv(e,phi)
m = pow(c2,d,n)
q_p_1_inv = -1
for i in tqdm(range(p-q,p)):
    q_p_1_inv = q_p_1_inv * i %p
flag = (m*q_p_1_inv)%p
print(long_to_bytes(flag))

image

posted @ 2023-10-22 16:08  N0zoM1z0  阅读(40)  评论(0编辑  收藏  举报