CISCN-2018-Quals_MS

k e y w o r d s : keywords: keywords: 有限域GF(2)下的矩阵乘法

D e s c r i p t i o n Description Description

from Crypto.Util.number import getPrime,long_to_bytes,bytes_to_long
from Crypto.Cipher import AES
import hashlib
from random import randint
def gen512num():
    order=[]
    while len(order)!=512:
        tmp=randint(1,512)
        if tmp not in order:
            order.append(tmp)
    ps=[]
    for i in range(512):
        p=getPrime(512-order[i]+10)
        pre=bin(p)[2:][0:(512-order[i])]+"1"
        ps.append(int(pre+"0"*(512-len(pre)),2))
    return ps

def run():
    choose=getPrime(512)
    ps=gen512num()
    print "gen over"
    bchoose=bin(choose)[2:]
    r=0
    bchoose = "0"*(512-len(bchoose))+bchoose
    for i in range(512):
        if bchoose[i]=='1':
            r=r^ps[i]
    flag=open("flag","r").read()

    key=long_to_bytes(int(hashlib.md5(long_to_bytes(choose)).hexdigest(),16))
    aes_obj = AES.new(key, AES.MODE_ECB)
    ef=aes_obj.encrypt(flag).encode("base64")

    open("r", "w").write(str(r))
    open("ef","w").write(ef)
    gg=""
    for p in ps:
        gg+=str(p)+"\n"
    open("ps","w").write(gg)

run()

A n a l y s i s Analysis Analysis

首先介绍一个性质:
R e s u l t = R e s u l t ⊕ ( A b i n ⋅ B i ) Result = Result \oplus (A_{bin} \cdot B_i) Result=Result(AbinBi)
其中 A b i n A_{bin} Abin是一个数 A A A的各个二进制位; B i B_i Bi是一个数组的各个数值

意思就是 R e s u l t Result Result分别异或每一个 A b i n A_{bin} Abin B i B_i Bi的乘积

那么以上等式等价于在有限域 G F ( 2 ) GF(2) GF(2)上进行的矩阵乘法
M A ⋅ M B = M R M_A\cdot M_B = M_R MAMB=MR
其中 M A M_A MA是由数值 A A A的各个二进制位构成的一维行向量; M B M_B MB是由数组 B B B得到各个数值的各个二进制位构成的二维向量(其中需要数组中数值的个数等于二进制位个数,也就是该二维向量行列长度相同); M R M_R MR即为结果 R e s u l t Result Result的二进制位组成的一维行向量

例如假设 A = 5 A=5 A=5 B = [ 5 , 3 , 6 ] B = [5,3,6] B=[5,3,6];那么经计算 R e s u l t = 3 Result = 3 Result=3

等价式子:

( 1 0 1 ) ⋅ ( 1 0 1 0 1 1 1 1 0 ) = ( 0 1 1 ) \left( \begin{array}{rr} 1&0&1 \end{array} \right)\cdot \left( \begin{array}{rr} 1&0&1\\ 0&1&1\\ 1&1&0 \end{array} \right)= \left( \begin{array}{rr} 0&1&1 \end{array} \right) (101)101011110=(011)

二进制转十进制 R e s u l t = 3 Result =3 Result=3,与之前的结果一致


那么本题就是运用上述性质进行求解

flagAES_ECB加密,需要key;而keychoose,其二进制位bchoose构成了等价于上述性质的 A b i n A_{bin} Abin;所以我们要找到上述性质中出现的其他参数

首先生成了由 512 512 512个数值构成的数组ps,也就是 B B B

    ps=[]
    for i in range(512):
        p=getPrime(512-order[i]+10)
        pre=bin(p)[2:][0:(512-order[i])]+"1"
        ps.append(int(pre+"0"*(512-len(pre)),2))
    return ps

通过不断异或生成r

    r=0
    bchoose = "0"*(512-len(bchoose))+bchoose # 填充bchoose到512位二进制
    for i in range(512):
        if bchoose[i]=='1':
            r=r^ps[i]

r的生成过程就是等价于
r = r ⊕ ( B c h o o s e b i n ⋅ P S i ) r = r \oplus (Bchoose_{bin} \cdot PS_i) r=r(BchoosebinPSi)
那么由之前提到的性质,以上等式等价于在有限域 G F ( 2 ) GF(2) GF(2)上的矩阵乘法
M r = M b c h o o s e ⋅ M p s M_r = M_{bchoose}\cdot M_{ps} Mr=MbchooseMps
需要知道 M b c h o o s e M_{bchoose} Mbchoose;那么直接解矩阵乘法即可
M b c h o o s e = M r ⋅ M p s − 1 M_{bchoose}=M_r\cdot M_{ps}^{-1} Mbchoose=MrMps1
这样就能解到 b c h o o s e bchoose bchoose的大小,进而解出keyflag

S o l v i n g   c o d e Solving~code Solving code

import base64
from Crypto.Cipher import AES
import numpy
from Crypto.Util.number import *
import hashlib

f = open("ps","r")
ps = []
for line in f.readlines():
    ps.append(int(line.strip('\n')))
# print(ps)
f.close()
f = open("r","r")
r = int(f.read())
# print(r)
f.close()
f = open("ef","r")
ef = f.read()
enc = base64.b64decode(ef)
# print(ef)
f.close()

A = []
B = []
for i in ps:
    A.append([int(x) for x in bin(i)[2:].zfill(512)])
# print(A)
B=[int(x) for x in bin(r)[2:].zfill(512)]
# print(B)
A = matrix(GF(2),A)
B = matrix(GF(2),B)

Result = A.solve_left(B) # 这个函数是专门用来解矩阵乘法的,分为左乘、右乘
key = ""
# print(numpy.matrix.tolist(Result))
for i in numpy.matrix.tolist(Result)[0]:
    key += str(i)
key = int(key,2)
key = long_to_bytes(int(hashlib.md5(long_to_bytes(key)).hexdigest(),16))
aes_obj = AES.new(key, AES.MODE_ECB)
print(bytes.decode(aes_obj.decrypt(enc)))

R e f e r e n c e Reference Reference

(11条消息) CISCN2018]sm(矩阵)_前方是否可导?的博客-CSDN博客

  • 2
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 2
    评论
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

M3ng@L

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值