Lattice reduction-LLL
Lattice reduction-LLL
一直在使用LLL却没有了解它的具体操作,这里对其过程做简要分析
首先LLL的提出是为了解决格中的SVP问题,后来发现其对高维格的规约并不理想,所以产生了LLL的改进方案,deep_insertion_method以及分组Korkin_Zplotarev约减算法,可以看出,维数是LLL算法能否有效实施的一个判断依据
首先考虑最简单的二维情况
这里先介绍高斯格基约减算法,此算法采用的思想和LLL有相似之处
Gauss Lattice Reduction
对于v1,v2两个向量,满足||v1||<||v2||
v2*=v2-mv1,m=\( ⌈\frac{<v_1,v_2>}{||v_1||^2}⌋\)
这个想法基于Gram_Schmidt正交化,为了满足格的整系数条件做了系数四舍五入的处理
高斯证明了该算法能在有限步骤内结束,下面讨论算法结束时约化基的特征
根据约化步很容易得到当m=0时,约化结束,直观上来讲就是无法通过从v2中减去v1的整数倍的方法使v2变得更小
下面证明最后返回的v1即为格中的最短向量
此时满足\(| \frac{<v_1,v_2>}{||v_1||^2}|≤0.5\)
设v=av1+bv2(ab≠0)
=>||v||2=a2||v1||2+2ab<v1,v2>+b2||v2||2
≥a2||v1||2-2ab|<v1,v2>|+b2||v2||2
≥a2||v1||2-2ab|<v1,v2>|+b2||v2||2
≥a2||v1||2-ab||v1||2+b2||v1||2=(a2-ab+b2)||v1||2
\(a^2-ab+b^2=(a-\frac{1}{2}b)^2+\frac{3}{4}b^2\)
因为上式必为非负整数,等于0时当且仅当a=b=0
=>||v||2≥||v1||2=>||v||≥||v1||
综上返回值v1为格中最短向量
算法实现
#sage
def Gauss_reduction(v1,v2):
if v1.norm()>v2.norm():
v1,v2=v2,v1
m=round((v1*v2)/v1.norm()^2)
if m==0:
return (v1,v2)
else:
v2=v2-m*v1
return Gauss_reduction(v2,v1)
LLL
LLL算法可以视作是高斯约减算法在高维情况下的推广
首先我们用矩阵的形式描述Gram_Schmidt过程
\((v_1~~v_2~~...~~v_n)=(v_1^*~~v_2^*~~...~~v_n^*)*\left[\begin{matrix}1&u_{1,2}&u_{1,3}&...&u_{1,n}\\&1&u_{2,3}&...&u_{2,n}\\&&&...\\&&&&1\end{matrix}\right]\)
其中ui,j=\(\frac{<v_i^*,v_j>}{||v_i^*||^2}\)
LLL算法的是一种迭代算法,检测到满足条件后直接输出
- (size_reduce):对任意i<j≤n,有|ui,j|≤0.5
- (Lovász condition):\(||v_i^*||^2≥(\frac{3}{4}-u^2_{i-1,i})||v_{i-1}^*||^2\),对i∈(1,n]成立
最后输出的基称为LLL约减基,这两个条件能给我们的一个感受就是最后得到的向量的长度不会下降得过快
Lenstra,Lenstra和Lovász的结论表明LLL约减基是一组优质的基,并且这组LLL约减基可以在多项式时间内得到
条件1是很容易满足的,从un-1,n开始逐步减去对应行是1的向量的若干倍即可
关于条件二我搜到的是通过不断地交换初始约化基的向量位置,来得到满足此条件,且每次交换都会离优质基更加接近且接近比率固定
下面是LLL约化基满足的性质
- \(\prod_{i=1}^n||v_i||≤2^{\frac{n(n-1)}{4}}det(L)\)
- \(||v_1||≤2^{\frac{(n-1)}{4}}det(L)^{\frac{1}{n}}\)
- \(||v_1||≤2^{\frac{(n-1)}{2}}λ(L)\)
证明就是利用LLL算法检测的两个条件得出
这里需要知道的是Gram_Schmidt基和初始基具有一致的张成空间,可以利用这一点进行证明
算法实现:
由于对sage有关函数不是很熟悉,没写成,这里贴一个容易能看明白的网上的LLL简易实现
#sage
def max(a, b):
return a if a > b else b
def LLL_v0(M, delta=0.75):
B = deepcopy(M)
Q, mu = B.gram_schmidt()
n, k = B.nrows(), 1
while k < n:
# size reduction step
for j in reversed(range(k)):
if abs( mu[k][j] ) > 0.5:
B[k] = B[k] - round( mu[k][j] ) * B[j]
Q, mu = B.gram_schmidt()
# swap step
if Q[k].dot_product(Q[k]) >= (delta - mu[k][k-1]^2) * Q[k-1].dot_product(Q[k-1]):
k = k + 1
else:
B[k], B[k-1] = B[k-1], B[k]
Q, mu = B.gram_schmidt()
k = max(k-1,1)
return B
这个地方的delta默认为0.75实际上可以根据需要在[0.75,1]的范围内进行调整
更详细的过程可以参考这篇文章