n = 24240993137357567658677097076762157882987659874601064738608971893024559525024581362454897599976003248892339463673241756118600994494150721789525924054960470762499808771760690211841936903839232109208099640507210141111314563007924046946402216384360405445595854947145800754365717704762310092558089455516189533635318084532202438477871458797287721022389909953190113597425964395222426700352859740293834121123138183367554858896124509695602915312917886769066254219381427385100688110915129283949340133524365403188753735534290512113201932620106585043122707355381551006014647469884010069878477179147719913280272028376706421104753
C = [5300743174999795329371527870190100703154639960450575575101738225528814331152637733729613419201898994386548816504858409726318742419169717222702404409496156167283354163362729304279553214510160589336672463972767842604886866159600567533436626931810981418193227593758688610512556391129176234307448758534506432755113432411099690991453452199653214054901093242337700880661006486138424743085527911347931571730473582051987520447237586885119205422668971876488684708196255266536680083835972668749902212285032756286424244284136941767752754078598830317271949981378674176685159516777247305970365843616105513456452993199192823148760, 21112179095014976702043514329117175747825140730885731533311755299178008997398851800028751416090265195760178867626233456642594578588007570838933135396672730765007160135908314028300141127837769297682479678972455077606519053977383739500664851033908924293990399261838079993207621314584108891814038236135637105408310569002463379136544773406496600396931819980400197333039720344346032547489037834427091233045574086625061748398991041014394602237400713218611015436866842699640680804906008370869021545517947588322083793581852529192500912579560094015867120212711242523672548392160514345774299568940390940653232489808850407256752]
m = Complex(getRandomRange(1, n), getRandomRange(1, n))
1
mh = {(m >> bits << bits).tolist()}
这里的m是个复数,而且这里很明显是m的高位泄露
那么接下来要干的事就很清晰了
既然是在复数域下,那我们就有 m = re + im * i
那么这里的高位泄露就可以表示为 $$
\begin{aligned}
re &= mh\_re + x \\
im &= mh\_im + y
\end{aligned}
$$ 加密过程非常简单 c = m3 (mod n)
那么这里就是复数的立方了 m3 = (re + im ⋅ i)3 = (re3 − 3 ⋅ re ⋅ im2) + (3 ⋅ re2 ⋅ im − im3) ⋅ i
这里出题的预期是解结式然后cooper,但是二元cooper可以直接出了,那么我们只用利用实部来列方程就好
for shifts in itertools.product(range(d), repeat=f.nvariables()):
g = base * prod(map(power, f.variables(), shifts))
G.append(g)
B, monomials = G.coefficient_matrix()
monomials = vector(monomials)
factors = [monomial(*bounds) for monomial in monomials]
for i, factor in enumerate(factors):
B.rescale_col(i, factor)
B = B.dense_matrix().LLL()
B = B.change_ring(QQ)
for i, factor in enumerate(factors):
B.rescale_col(i, 1 / factor)
H = Sequence([], f.parent().change_ring(QQ))
for h in filter(None, B * monomials):
H.append(h)
I = H.ideal()
if I.dimension() == -1:
H.pop()
elif I.dimension() == 0:
roots = []
for root in I.variety(ring=ZZ):
root = tuple(R(root[var]) for var in f.variables())
roots.append(root)
return roots
return []
n = 24240993137357567658677097076762157882987659874601064738608971893024559525024581362454897599976003248892339463673241756118600994494150721789525924054960470762499808771760690211841936903839232109208099640507210141111314563007924046946402216384360405445595854947145800754365717704762310092558089455516189533635318084532202438477871458797287721022389909953190113597425964395222426700352859740293834121123138183367554858896124509695602915312917886769066254219381427385100688110915129283949340133524365403188753735534290512113201932620106585043122707355381551006014647469884010069878477179147719913280272028376706421104753
C = [5300743174999795329371527870190100703154639960450575575101738225528814331152637733729613419201898994386548816504858409726318742419169717222702404409496156167283354163362729304279553214510160589336672463972767842604886866159600567533436626931810981418193227593758688610512556391129176234307448758534506432755113432411099690991453452199653214054901093242337700880661006486138424743085527911347931571730473582051987520447237586885119205422668971876488684708196255266536680083835972668749902212285032756286424244284136941767752754078598830317271949981378674176685159516777247305970365843616105513456452993199192823148760, 21112179095014976702043514329117175747825140730885731533311755299178008997398851800028751416090265195760178867626233456642594578588007570838933135396672730765007160135908314028300141127837769297682479678972455077606519053977383739500664851033908924293990399261838079993207621314584108891814038236135637105408310569002463379136544773406496600396931819980400197333039720344346032547489037834427091233045574086625061748398991041014394602237400713218611015436866842699640680804906008370869021545517947588322083793581852529192500912579560094015867120212711242523672548392160514345774299568940390940653232489808850407256752]
对于一个复数来说 c = a + b ⋅ i
它的模长是 $$
\left |c \right |=\sqrt{a^{2}+b^{2}}
$$ 那么对于它的平方也就是 c2 = (a2 − b2) + 2ab ⋅ i
它模长是 $$
\left |c^{2} \right |=\sqrt{(a^{2}-b^{2})^{2}+4a^{2}b^{2}}=a^{2}+b^{2}
$$
这里我们可以看复数平方的模长就是复数模长的平方,那么对于其他次幂能否满足这一条件呢,那当然也是满足的,这里就不在证明了,回到这道题
(3 + 7 ⋅ i)x ≡ (cre + cim) mod p
这里利用上面的性质 |3 + 7 ⋅ i|x ≡ |(cre + cim)| mod p
那么这里还有一个问题模长的根号内部不是二次剩余,所以我选择把模长平方掉
|(3 + 7 ⋅ i)2|x ≡ |(cre + cim)2| mod p
1 2 3 4 5 6 7 8 9 10 11 12
p = 1127236854942215744482170859284245684922507818478439319428888584898927520579579027
g = 3^2 + 7^2 a = 5699996596230726507553778181714315375600519769517892864468100565238657988087817 b = 198037503897625840198829901785272602849546728822078622977599179234202360717671908 c = (a^2 + b^2) % p
x = discrete_log(mod(c,p),mod(g,p)) flag = b"XYCTF{" + bytes.fromhex(hex(int(x))[2:]) + b"}" print(flag)
# XYCTF{___c0mp13x_d1p_15_3@5y_f0r_y0u___}
这个写法好理解一点,这是Dexter师傅的
这个是我的
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19
p = 1127236854942215744482170859284245684922507818478439319428888584898927520579579027