2023陕西技能大赛--职业院校组--ezMath

不会,记录大神的解题方法

题目描述:

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)(xy+1)=gift4xygift=(x2+1)(y2+1)2(x+y)(xy+1)+4xygift=x2y2+x2+y22x2y2xy22x2y+4xy+1gift=x2(y22y+1)2x(y22y+1)+(y22y+1)gift=(x1)2(y1)2开根号得到gift =(x1)(y1)求出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消元法——传入两个式子消去一个公共因子

解方程又多了一种方法

你可能感兴趣的:(赛事复现,陕西技能大赛,密码学,安全,解方程)