格
格的定义:
给定一组线性无关的基向量v1, v2, ..., vn
,那么这些基向量的所有整系数线性组合
所形成的集合,就叫做这组基向量所张成的格(lattice)。
系数不再是任何实数,变成了是任何整数
也就是说,从无数个连续的点变成了无数个离散的点。
不同的基底,可能会张成不同的lattice:
对原基底进行整系数线性转换得到的新的基底,张成的lattice仍旧不变:
注意:同一个lattice有很多组基底。
在lattice里面,有两个知名的难题:
-
SVP(最短向量问题,Shortest Vector Problem):给定lattice和基向量,找到lattice中的一个长度最短的非零向量。
(当给出的基底接近最短基底时,这无疑是容易解出的,但我们前面提到:对原基底进行整系数线性转换得到的新的基底,张成的lattice仍旧不变,当我们给出的基底是由两个比较小的基底进行无数次线性运算得到的非常大的基底是,想要逆推得到最短基底就没这么容易了。如果将这个问题推广到三维、四维甚至多维空间后,这个问题的就会成为一个几乎无解的难题)
-
CVP(最近向量问题,Closest Vector Problem):给定lattice和基向量,以及一个不在lattice上的目标向量,找到lattice中一个距离目标向量最近的格向量。
格密码就是基于这些数学难题而设计的。
深育杯 gege (CRYPTO)
from Crypto.Util.number import *
import gmpy2
from flag import flag
def encrypt(plaintext):
p = getStrongPrime(3072)
m = bytes_to_long(plaintext)
r = getRandomNBitInteger(1024)
while True:
f = getRandomNBitInteger(1024)
g = getStrongPrime(768)
h = gmpy2.invert(f, p) * g % p
c = (r * h + m * f) % p
return (h, p, c)
h, p, c = encrypt(flag)
with open("cipher.txt", "w") as f:
f.write("h = " + str(h) + "\n")
f.write("p = " + str(p) + "\n")
f.write("c = " + str(c) + "\n")
#h = 39679004095184914370911667153808021615328411590725195634713543364007509300099701771019533048619545021465707215069952245206317162611080716848828411023811447201776644349816085840752019078919642146042462194413253776021639571726425821581922234528456710075855569519224152004155380602474562136081123603616369127033803063864398462696456967509298116077838952946706392024724659205995425682276571529228430017927541169819926962037882