跳至主要內容

6.格相关的初步理解

Someijam大约 6 分钟CTFCryptography

06.格相关的初步理解

从此处开始,为了表述清晰,我们有必要进行符号的约定:

  • 数域,用黑板体表示,如“N,Z+”等
  • 向量,要么是v,要么是v
  • 矩阵,粗体,正的字体,比如“M”,通常是大写字母,小写字母通常表示退化成行列向量的矩阵
  • 变量,斜字体,不加粗,如x,y,z,ai
  • 有非数学含义的量,正着的字体,不加粗,如“flag”,“ciphertext”等
  • 微分符号d也是正着写的,但是这里应该不会用到

格与线性代数

通常我们在密码学题中说的“构造格”是构造一个高维的矩阵,矩阵里的行向量线性无关,由这些向量线性组合可以得到这个“格”规定空间中的其他向量,这些向量构成一个“格”。

线性代数只要超过三维就变得非常抽象(笑),我们简单地举个例子:

对于平面向量i=(0,1),j=(1,0)而言,它们进行线性组合可以得到平面直角坐标系上所有的“整点”,每个整点都对应一个向量,这些向量的集合就是i,j产生的格。

有了这样形象一点的理解,我们可以来点抽象但严谨的定义了:

给定n个线性无关的向量b1,b2,,bnRmn个向量,但是每个向量是m维,通常我们研究的这些向量只包含整数),由它们产生的格可以定义为:

L={i=1nxibi|xiZ}

并且称n个线性无关的向量b1,b2,,bn是格L的一组基向量。

我有时候会把基向量按照行向量的形式写成一个矩阵并管这叫格(有点不严谨,但是人家确实可以确定一个格),比如

M=[1000a00100a10010a20001a310000msgi]

这个格的基向量有33个,每一行都是。

常见格基规约可解的问题

格基规约的意思是在格中找到最短正交基,比如假如一个格的某组基向量长这样:

[888967101081024767410202639259291829136855851382556001309839100522331530746310524794779192951162071252468680787891643409005395070490188970755439198328798240840075917442897437]

我们可以看到,受最后一个数的影响,每个向量的长度都很长,进行格基规约后,生成新的一组向量要短于目前看到的向量,人话就是“想找最短的一组基向量”。进行格基规约后,得到这样的矩阵:

[882136111118102310119228151111931617710013155131481713111119101092014252215136888211144631518510113592318141092812167165914181111172118126350241442181241411]

新矩阵的这一组行向量通过线性组合,可以得到和原来一组向量线性组合一样的集合,但是新向量的长度明显短于原来的向量。

拿二维向量举个例子:

L=[47405902314740590241]L=[1001]

L中所有点恰好是平面直角坐标系的所有整点,又因为能生成平面直角坐标系的所有整点中最短的一组基恰好是L,故L可以约化为L

实现这一过程的算法有LLL算法和BKZ算法等,这些算法可以用于解决简单的背包密码问题。

import random

FLAG=b'flag{??????????????}'
A=[]
R=[]

for i in range(len(FLAG)):
    R.append(random.randint(2^255,2^256))
for it in FLAG:
    A.append(it)

print("r=",R)
s=0
for i in range(len(A)):
    s+=A[i]*R[i]
print("s=",s)

#r= [84708427087077223508746288063337494990202308717440648267330272467894135815924, 71870568665949375571123194758721886986214915618119682637155541122724587843538, 100602777684007543774082898599706333986772386698972675235175116918558786391962, 111285051187103927630378256146929087424914433805356274330547725319174973931277, 64578102072561422481461507204980221906000549452073284469375642403915658526944, 86322141979473667695571199744900761415805265093764192361364761268359524886683, 72011676602309218727623614360157790460724328388438553974216685545015819637985, 105078647996919751921291687976259108242130115531722942052727064034794843311713, 103368664162917561456868191521357206960937667181816315755562413488001589478969, 110217494630018693400232569191132571597769888106563150009902908082060581373688, 102102758556529646879850232401420434521525362134114601318994246006859815684022, 59737283987733589757667947492046903632395451150869436838717031849208989232792, 96939253886687385011366188281125159174552069495814805461361873644813397503683, 114641947042791145846017955279259816732740851376806201344445227298400592825026, 61510532473061488409080784977420763480768150226633374205381891642621350872652, 93205406280652930830657724311733637553372165292401644272052908684168046931905, 93263648785956684648159472389804327266831072351824149657922933965632190434279, 89242559636665509154695981891162231039148956916038357675627491174222218950010, 85806148229998038363438926244130009872932303916869110298400507055220763699223, 76194060752187389247644380773496301324990137770378156568752915597166731745582]
#s= 186821937016204430958110742375961411865713279663457753476144741561954080361297505

这一题的意思很简单,就是给定两个向量,其中一个向量数很大很大,另一个向量是flag的ASCii码,两个向量作数量积的结果也告诉我们了,我们要求的是flag的值。

抽象成数学问题就是已知一组数(向量r的各个数),和这一组数的某个线性组合后的值s,想要知道它们是如何进行线性组合的。

我们这样构造格:

A=[1000r10100r20010r30001rn0000s]

为什么要这样构造格呢?

首先,受r的影响,这个格给出的基向量都很长。并且,这些基向量经过线性组合,是可以生成这样一个特殊向量的:

y=(f1,f2,,fn,0)

其中f1,f2,,fn是flag的每一位ASCii码。怎么生成呢?在A的左边乘一个向量f即可:

f=(f1,f2,,fn,1)

虽然f并不就是格A中的向量,但是按照f进行线性组合是可以得到y的。恰好y相对其他向量而言,很有可能是格A中最短的向量了(基向量都是很大很大的数,能生成的短向量肯定屈指可数),我们对A进行格基规约的结果如下:

n=len(R)
A = Matrix(ZZ, n + 1, n + 1)
for i in range(n):
    A[i,i]=1
    A[i,-1]=R[i]

A[-1,-1]=-1*s
LA=A.LLL()
print(LA)

输出比较长,但是我们发现第一个行向量:

[102,108, 97, 103, 123, 116, 104, 105, 115, 95, 105, 115, 95, 97, 95, 102, 108, 97, 103, 125,0]

即:​flag{this_is_a_flag}

我通常管这种问题叫“寻找线性组合”的问题。

格密码

这部分的内容较为深奥,后续总结题型时会给出一些讲解。