不会,记录大神的解题方法
题目描述:
from Crypto.Util.number import *
from secret import y,a,b
flag=b'flag{}'
l = len(flag)
m1, m2 = flag[: l // 2], flag[l // 2:]
x = bytes_to_long(m1)
c = bytes_to_long(m2)
assert (x**2+1)*(y**2+1)-2*(x+y)*(x*y+1)==gift-4*x*y
'''
4*b**6-2*a**3+3*a*c = 5530346600323339885232820545798418499625132786869393636420197124606005490080520377416491241780814130580634432917029242402389788321303783584093278303358433856193188224687198306898483386282930376793701825481151610363517100498626293248
b**5+6*c**3+2*a*b*c = 2954615125181706551778975245956905163867066802909029011696374372323491135608656194836008189370779030694961333309906927038863656553775849501064217981385517049591593537202663734020724898058374757
3*a**3-3*a*c-3*b**6 = -5530346600323339885232820545798418499625132786869393636420197035566805062067013375355549877479840082835466426039196029766850808080041755202912921908993556467660683726675045317331817898077228454499973287809035537190311008571468738911
gift=18150211062729351455633481905222609221074385988870569666008228964942099019268333450225373082700058568213818917267125668494844006433076192398714708653476096
'''
题目分析:
第一部分
已知
(
x
2
+
1
)
(
y
2
+
1
)
−
2
(
x
+
y
)
∗
(
x
∗
y
+
1
)
=
g
i
f
t
−
4
x
y
⇒
g
i
f
t
=
(
x
2
+
1
)
(
y
2
+
1
)
−
2
(
x
+
y
)
∗
(
x
∗
y
+
1
)
+
4
x
y
⇒
g
i
f
t
=
x
2
y
2
+
x
2
+
y
2
−
2
x
2
y
−
2
x
y
2
−
2
x
−
2
y
+
4
x
y
+
1
⇒
g
i
f
t
=
x
2
(
y
2
−
2
y
+
1
)
−
2
x
(
y
2
−
2
y
+
1
)
+
(
y
2
−
2
y
+
1
)
⇒
g
i
f
t
=
(
x
−
1
)
2
(
y
−
1
)
2
开根号得到
g
i
f
t
=
(
x
−
1
)
(
y
−
1
)
求出
g
i
f
t
所有组合因子
(
d
i
v
i
s
o
r
s
(
)
)
,遍历加判断即可得到
f
l
a
g
1
\begin{aligned} &\text{已知} \\ &(x^2+1)(y^2+1)-2(x+y)*(x*y+1)=gift-4xy \\ &\Rightarrow gift=(x^2+1)(y^2+1)-2(x+y)*(x*y+1)+4xy \\ &\Rightarrow gift=x^2y^2+x^2+y^2-2x^2y-2xy^2-2x-2y+4xy+1 \\ &\Rightarrow gift=x^2(y^2-2y+1)-2x(y^2-2y+1)+(y^2-2y+1) \\ &\Rightarrow gift=(x-1)^2(y-1)^2 \\ &\text{开根号得到}\sqrt{gift}=(x-1)(y-1)\\ &\text{求出}\sqrt{gift}所有组合因子(divisors()),遍历加判断即可得到flag1 \end{aligned}\\
已知(x2+1)(y2+1)−2(x+y)∗(x∗y+1)=gift−4xy⇒gift=(x2+1)(y2+1)−2(x+y)∗(x∗y+1)+4xy⇒gift=x2y2+x2+y2−2x2y−2xy2−2x−2y+4xy+1⇒gift=x2(y2−2y+1)−2x(y2−2y+1)+(y2−2y+1)⇒gift=(x−1)2(y−1)2开根号得到gift=(x−1)(y−1)求出gift所有组合因子(divisors()),遍历加判断即可得到flag1
gift=18150211062729351455633481905222609221074385988870569666008228964942099019268333450225373082700058568213818917267125668494844006433076192398714708653476096
x_y = gmpy2.iroot(gift,2)[0]
div = divisors(x_y)
for i in div:
flag1 = long_to_bytes(int(i+1))
if b'flag' in flag1:
print(flag1)
break
第二部分
开始尝试用z3解方程,发现时间好长,不想等。。。
大神说使用resultant消元法解c,记下来了
“ 使用resultant消元法,通过消元把多项式方程组转化为一个变量只有c的形式,然后再构造一个新的一元多项式,最后解方程即可得到c ”
from Crypto.Util.number import *
from sage.matrix.matrix2 import Matrix
c1 = 5530346600323339885232820545798418499625132786869393636420197124606005490080520377416491241780814130580634432917029242402389788321303783584093278303358433856193188224687198306898483386282930376793701825481151610363517100498626293248
c2 = 2954615125181706551778975245956905163867066802909029011696374372323491135608656194836008189370779030694961333309906927038863656553775849501064217981385517049591593537202663734020724898058374757
c3 = -5530346600323339885232820545798418499625132786869393636420197035566805062067013375355549877479840082835466426039196029766850808080041755202912921908993556467660683726675045317331817898077228454499973287809035537190311008571468738911
R.<a,b,c> = PolynomialRing(ZZ)
f1 = 4*b**6-2*a**3+3*a*c-c1
f2 = b**5+6*c**3+2*a*b*c-c2
f3 = 3*a**3-3*a*c-3*b**6-c3
def resultant(f1, f2, var):
return Matrix.determinant(f1.sylvester_matrix(f2, var))
h1 = resultant(f1, f2, a) #b,c
h2 = resultant(f1, f3, a) #b,c
h3 = resultant(h1, h2, b) #c
m2 = h3.univariate_polynomial().roots()
# [(78042915855360415267901257437397052556186367517053, 1)]
print(long_to_bytes(m2[0][0]))
# 5f-af01-c883e3c8d9ca}
浅记一下
divisors(x)——求x中的所有组合因子
resultant消元法——传入两个式子消去一个公共因子
解方程又多了一种方法