from subprocess import check_output from re import findall from sage.allimport *
defflatter(M): # flatter z = "[[" + "]\n[".join(" ".join(map(str, row)) for row in M) + "]]" ret = check_output(["flatter"], input=z.encode()) return matrix(M.nrows(), M.ncols(), map(int, findall(b"-?\\d+", ret))) p= A= B= A=matrix(GF(p),10,10,A) B=matrix(GF(p),10,10,B) A10=block_matrix(GF(p),[[zero_matrix(10) if(i!=j) else A for j inrange(10)] for i inrange(10)]) Bv=[[B[j][i]*identity_matrix(10) for j inrange(10)]for i inrange(10)] B10=block_matrix(GF(p),Bv) M=block_matrix(ZZ, [[identity_matrix(100),zero_matrix(100,100),A10], [zero_matrix(100,100),identity_matrix(100),-B10], [zero_matrix(100,100),zero_matrix(100,100),-p*identity_matrix(100)]])
C=[[0 for _ in range(25)]for __ in range(625)] tot=0 for i in range(25): xrow,ycol=i//5,i%5 for xcol in range(5): for yrow in range(5): C[xrow*125+xcol*25+yrow*5+ycol][tot]=A[xcol][yrow] tot+=1 C=matrix(C)
from subprocess import check_output from re import findall from sage.allimport * p= A= B= A=matrix(ZZ,5,5,A) C=[[0for _ inrange(25)]for __ inrange(625)] tot=0 for i inrange(25): xrow,ycol=i//5,i%5 for xcol inrange(5): for yrow inrange(5): C[xrow*125+xcol*25+yrow*5+ycol][tot]=A[xcol][yrow] tot+=1 C=matrix(C) M=block_matrix(ZZ, [ [identity_matrix(625),C], [zero_matrix(1,625),matrix([-i for i in B])], [zero_matrix(25,625),-p*identity_matrix(25)] ] ) Mb=diagonal_matrix([1]*625+[65536]+[2**8000]*25) from datetime import * print(datetime.now()) M3L=M.LLL() print(datetime.now()) #About 5 minutes. vec=M3L[1] X=[] Y=[] if(vec[0]<0): vec=-vec from Crypto.Util.number import * Y=[] for i inrange(25): xi=vec[i*25] for j inrange(25): xi=GCD(xi,vec[i*25+j]) X.append(xi) for j inrange(25): Y.append(vec[i*25+j]//xi) print(bytes(X)) print(bytes(Y[:25])) #NSSCTF{M@k3_N0n_L1ne@r_L1ne@r!}
n = 10 p = getPrime(256) M = Matrix(Zmod(p), n, n, pad(flag,n^2)) e = Matrix(Zmod(p), n, n, pad(b"",n^2)) W = random_matrix(Zmod(p), n, n) X = random_matrix(Zmod(p), n, n) Y = random_matrix(Zmod(p), n, n) Z = random_matrix(Zmod(p), n, n)
from subprocess import check_output from re import findall from sage.allimport *
defflatter(M): # flatter z = "[[" + "]\n[".join(" ".join(map(str, row)) for row in M) + "]]" ret = check_output(["flatter"], input=z.encode()) return matrix(M.nrows(), M.ncols(), map(int, findall(b"-?\\d+", ret))) p= W= X= Y= Z= C= Cexpand=C.copy() W,X,Y,Z,C=[matrix(GF(p),10,10,mati) for mati in [W,X,Y,Z,C]] A=W*X B=Y*Z Mx=[[0for _ inrange(100)] for __ inrange(100)] for u inrange(10): for v inrange(10): for i inrange(10): for j inrange(10): Mx[i*10+j][10*u+v]=A[u][i]*B[j][v] Mx=matrix(GF(p),Mx)
M=block_matrix(ZZ,[ [identity_matrix(100),zero_matrix(100),Mx,0], [zero_matrix(100),identity_matrix(100),identity_matrix(100),0], [zero_matrix(100),zero_matrix(100),-p*identity_matrix(100),0], [zero_matrix(1,100),zero_matrix(1,100),-matrix(Cexpand),1], ]) from datetime import * Mb=diagonal_matrix([1]*200+[2**8000]*100+[1]) print(datetime.now()) M3L=flatter(M*Mb) print(datetime.now()) for vec in M3L: if(vec[-1] in [1,-1]): vec=vec*vec[-1] print(bytes(vec))
from Crypto.Util.number import * from Crypto.Cipher import AES from random import randint from hashlib import md5 from secret import flag
n = len(flag) p = getPrime(256) secret = [randint(1,p) for i inrange(n)]
defencrypt(n,p,msg): while(1): L = [] R = [] for i inrange(n): temp = random_vector(Zmod(p), n) L.append(temp) R.append(msg[i]*temp) L = Matrix(Zmod(p),L).T R = Matrix(Zmod(p),R).T if(L.rank() == n and R.rank() == n): return (R*L^(-1))^(bytes_to_long(b"Tequila"))
from Crypto.Util.number import * from random import randint from secret import flag
n = len(flag) p = getPrime(256)
defencrypt(n,p,msg): while(1): L = [msg] R = [randint(1,p)*msg] for i inrange(n-1): temp = random_vector(Zmod(p), n) L.append(temp) R.append(randint(1,p)*temp) L = Matrix(Zmod(p),L).T R = Matrix(Zmod(p),R).T if(L.rank() == n and R.rank() == n): return (R*L^(-1))^(bytes_to_long(b"Tequila"))
from Crypto.Util.number import * from random import randint n = 42 sec=[randint(0,1435756428) for i inrange(42)] flagvec=Matrix(GF(1435756429),6,6,sec[:36])*vector(GF(1435756429),sec[36:42]) flag='{:08x}-{:08x}-{:08x}-{:08x}-{:08x}-{:08x}'.format(*list(flagvec.change_ring(ZZ))) flag='flag{'+flag+'}' p = getPrime(256)
from Crypto.Util.number import * from random import randint from secret import flag
n = len(flag)-4 p = getPrime(256)
defencrypt(n,p,msg): while(1): L = [] R = [] for i inrange(n): temp = vector(Zmod(p), [randint(1,p) for _ inrange(n-5)] + list(msg[i:i+5])) L.append(temp) R.append(randint(1,p)*temp) L = Matrix(Zmod(p),L).T R = Matrix(Zmod(p),R).T if(L.rank() == n and R.rank() == n): return (R*L^(-1))^(randint(1,p))
p= C= C=matrix(GF(p),47,47,C) vecs=C.eigenvectors_right() D=[] #构造取值集合 for i inrange(32,127): for j inrange(32,127): D.append((i*pow(j,p-2,p)%p,i,j,GCD(i,j)==1)) D=set(D) for _,v,_ in vecs: #计算比值,可能比值对应结果不唯一,但因为互素概率不低,因此 4 组数据肯定能有互素的:D v=v[0] judgarr=[v[-i]/v[-i+1] for i in [5,4,3,2]] R=[[],[],[],[]] for i inrange(4): for item in D: if(item[0]==judgarr[i]): R[i].append(item) for i inrange(4): if(len(R[i])==1): r=R[i][0] v=v/v[-5+i]*r[1] print(bytes(v[-5:])) break #最后需要把所有输出进行手动拼接,并且是乱序的,有点麻烦 #NSSCTF{U_h4Ve_C0mp1et3d_H@lF_0f_MATRIX_cha1LenGe5!}
然而我看了wp,发现这个题又被我非预期了:D。正解是把最后 $5$ 个分量拿进去规约。
1 2 3 4 5 6 7 8 9 10 11 12 13
p= C= C=matrix(GF(p),47,47,C) vecs=C.eigenvectors_right() defsolve3(v): M=block_matrix(ZZ,[matrix(v),p*identity_matrix(len(v))],nrows=2) M3L=M.LLL() return M3L[1] if M3L[1][0]>0else -M3L[1] arr=[] for _,v,_ in vecs[::]: v=v[0] s=(solve3(v[-5:])) print(bytes(s))
from Crypto.Util.number import * from random import randint from secret import flag
polyeval = lambda poly, x: sum(a*pow(x,i,n) for a,i in poly) % n
p = getPrime(256) q = getPrime(256) n = p*q e = 1337 m = bytes_to_long(flag)
nums = 10 g = [(randint(1,n), i) for i inrange(nums)] F = [] C = [] for i inrange(nums+1): f = [(randint(1,n), (randint(1,n))) for i inrange(nums)] F.append(f) C.append(polyeval(g,polyeval(f,m)))
n= c= F= C= R.<x_>=PolynomialRing(Zmod(n)) Rq.<x>=R.quotient(x_**1337-c) #降次关键 Fx=[] from tqdm import * for i in tqdm(range(len(F))): fx=sum([a*x**b for a,b in F[i]]) Fx.append(fx) M=[] for i inrange(len(Fx)): M.append([Fx[i]**j for j inrange(10)]+[-C[i]]) M=matrix(M) detM=M.det() from Crypto.Util.number import * deffxgcd(fx,gx): if(gx==0): return fx.monic() return fxgcd(gx,fx%gx) long_to_bytes(int(-fxgcd(R(list(detM)),x_**1337-c)%x_))
p= C= Y=[matrix(GF(p),10,10,C[i][1]) for i inrange(10)] Y=block_matrix(GF(p),Y,nrows=10) A=[matrix(GF(p),10,10,C[i][0]) for i inrange(10)] M=[[A[i]**j for j inrange(1,11)] for i inrange(10)] M=block_matrix(GF(p),M) Z=M.solve_right(Y) s=[] for i inrange(10): s+=list(Z[i]) bytes(s) #NSSCTF{M@tRiX_L4granGe_InterP0lati0n_1Sn't_H4rD}
from subprocess import check_output from re import findall from sage.allimport *
defflatter(M): # flatter z = "[[" + "]\n[".join(" ".join(map(str, row)) for row in M) + "]]" ret = check_output(["flatter"], input=z.encode()) return matrix(M.nrows(), M.ncols(), map(int, findall(b"-?\\d+", ret))) A,B=C[0][0],C[0][1] A=matrix(GF(p),15,15,A) B=matrix(GF(p),15,15,B) Aarr=[A**i for i inrange(1,16)] from datetime import * for v inrange(15): print(f'Round {1+v} start at',datetime.now()) Mx=[[0for _ inrange(15)]for __ inrange(225)] for u inrange(15): for T inrange(15): for i inrange(15): Mx[15*T+i][u]=Aarr[T][u][i] Mx=matrix(Mx) M=block_matrix(ZZ,[ [identity_matrix(225),Mx,zero_matrix(225,1)], [zero_matrix(15,225),-p*identity_matrix(15),zero_matrix(15,1)], [zero_matrix(1,225),-matrix((B.T)[v]),1] ]) Mb=diagonal_matrix([1]*225+[2**2000]*15+[1]) M3L=flatter(M*Mb) for vec in M3L: if(vec[-1] in [1,-1]): vec*=vec[-1] print(bytes(vec))
运行结果:
12.Matrix 9
题目很短,我们只知道 $B=f(A)$ 这一条信息,其中 $f$ 是一个 $10$ 次多项式。
1 2 3 4 5 6 7 8 9 10 11 12
from Crypto.Util.number import * from Crypto.Cipher import AES from hashlib import md5 from secret import flag
n = 10 A = random_matrix(GF(2), n, n) PR.<x> = PolynomialRing(GF(2)) B = PR.random_element(degree=n)(A)
for u inrange(10): for v inrange(10): for i inrange(10): M[u*10+v][10*i+v]+=int(B[u][i]) M[u*10+v][10*u+i]-=int(B[i][v]) M=matrix(GF(2),M)
K=M.right_kernel().matrix() Ks=[K[i] for i inrange(K.nrows())] from Crypto.Cipher import AES from hashlib import md5 for i inrange(2**len(Ks)): v=[bool(i&(1<<j)) for j inrange(len(Ks))] A=sum([vi*ki for vi,ki inzip(v,Ks)]) A=matrix(GF(2),10,10,A) s=(AES.new(key=md5(str(A).encode()).digest(), nonce=b"Tiffany", mode=AES.MODE_CTR).decrypt(enc)) if(all([s[i]<128and s[i]>32for i inrange(12)])): print(s) #b'NSSCTF{U31nG_C0mmut@t1vE_and_Bru7eF0rCe!}'
for u inrange(10): for v inrange(10): for i inrange(10): Mx[u*10+v][10*i+v]+=int(B[u][i]) Mx[u*10+v][10*u+i]-=int(B[i][v]) Mx=matrix(GF(p),Mx) K=Mx.right_kernel().matrix()
M=block_matrix(ZZ,[ [K], [-p*identity_matrix(100)] ]) M3L=M.LLL() s=(-M3L[11]) # ans='' for i inrange(len(s)): if(s[i]>=32and s[i]<=127): ans+=chr(s[i]) else: ans+='.' print(ans) #.SSCTF{St1l.LLL111lllI.I_1n_th3_k.rn3L!} #NSSCTF{St1llLLL111lllIII_1n_th3_k3rn3L!}