MoeCTF2023 bad_E
from Crypto.Util.number import *
p = getPrime(512)
q = getPrime(512)
e = 65537
print(p) # 6853495238262155391975011057929314523706159020478084061020122347902601182448091015650787022962180599741651597328364289413042032923330906135304995252477571
print(q) # 11727544912613560398705401423145382428897876620077115390278679983274961030035884083100580422155496261311510530671232666801444557695190734596546855494472819
with open("flag.txt","r") as fs:
flag = fs.read().strip()
m = bytes_to_long(flag.encode())
c = pow(m,e,p*q)
print(c) # 63388263723813143290256836284084914544524440253054612802424934400854921660916379284754467427040180660945667733359330988361620691457570947823206385692232584893511398038141442606303536260023122774682805630913037113541880875125504376791939861734613177272270414287306054553288162010873808058776206524782351475805
题目给的e (e,phi)=e。。。
所以不存在逆元d
这题其实可以从 模为合数的情况退化到模为单素数的情况
即 c≡m^e(mod p) c≡m^e(mod q)
这里尝试后发现 取模为q的时候 是能够求出 modinv(e,q-1)的
所以exp:
from Crypto.Util.number import *
from primefac import *
from gmpy2 import *
from sympy import *
e = 65537
p = 6853495238262155391975011057929314523706159020478084061020122347902601182448091015650787022962180599741651597328364289413042032923330906135304995252477571
q = 11727544912613560398705401423145382428897876620077115390278679983274961030035884083100580422155496261311510530671232666801444557695190734596546855494472819
c = 63388263723813143290256836284084914544524440253054612802424934400854921660916379284754467427040180660945667733359330988361620691457570947823206385692232584893511398038141442606303536260023122774682805630913037113541880875125504376791939861734613177272270414287306054553288162010873808058776206524782351475805
n = p*q
phi = (p-1)*(q-1)
print(gcd(e,phi))
d = modinv(e,q-1)
m = pow(c,d,q)
print(long_to_bytes(m))
另解:
由于gcd(e,phi)=e=65537很大 可以用AMM开根
# sagemanth
import random
import math
import time
from libnum import n2s
p = 0
#设置模数
def GF(a):
global p
p = a
#乘法取模
def g(a,b):
global p
return pow(a,b,p)
def AMM(x,e,p):
GF(p)
y = random.randint(1, p-1)
while g(y, (p-1)//e) == 1:
y = random.randint(1, p-1)
print(y)
print("find")
#p-1 = e^t*s
t = 1
s = 0
while p % e == 0:
t += 1
print(t)
s = p // (e**t)
print('e =',e)
print('p =',p)
print('s =',s)
print('t =',t)
# s|ralpha-1
k = 1
while((s * k + 1) % e != 0):
k += 1
alpha = (s * k + 1) // e
#计算a = y^s b = x^s h =1
#h为e次非剩余部分的积
a = g(y, (e ** (t - 1) ) * s)
b = g(x, e * alpha - 1)
c = g(y, s)
h = 1
#
for i in range(1, t-1):
d = g(b,e**(t-1-i))
if d == 1:
j = 0
else:
j = -math.log(d,a)
b = b * (g(g(c, e), j))
h = h * g(c, j)
c = g(c, e)
#return (g(x, alpha * h)) % p
root = (g(x, alpha * h)) % p
roots = set()
for i in range(e):
mp2 = root * g(a,i) %p
assert(g(mp2, e) == x)
roots.add(mp2)
return roots
# def check(m):
# if 'flag' in m:
# print(m)
# return True
# else:
# return False
p=6853495238262155391975011057929314523706159020478084061020122347902601182448091015650787022962180599741651597328364289413042032923330906135304995252477571
q=11727544912613560398705401423145382428897876620077115390278679983274961030035884083100580422155496261311510530671232666801444557695190734596546855494472819
e=65537
c = 63388263723813143290256836284084914544524440253054612802424934400854921660916379284754467427040180660945667733359330988361620691457570947823206385692232584893511398038141442606303536260023122774682805630913037113541880875125504376791939861734613177272270414287306054553288162010873808058776206524782351475805
n = p*q
mps = AMM(c,e,p)
for mpp in mps:
solution = n2s(int(mpp))
if b'moectf' in solution:
#solution = int(mpp)
print(solution)