LLL reduction


There are a few issues that one may encounter when attempting to generalize Lagrange's algorithm to higher dimensions. Most importantly, one needs to figure what is the proper way to swap the vectors around and when to terminate, ideally in in polynomial time. A rough sketch of how the algorithm should look like is

def LLL(B):
d = B.nrows()
i = 1
while i<d:
if swap_condition(B):
i += 1
B[i],B[i-1] = B[i-1],B[i]
i = max(i-1,1)
return B

There are two things we need to figure out, in what order should we reduce the basis elements by and how should we know when to swap. Ideally, we also want the basis to be ordered in a way such that the smallest basis vectors comes first. Intuitively, it would also be better to reduce a vector by the larger vectors first before reducing by the smaller vectors, a very vague analogy to filling up a jar with big stones first before putting in the sand. This leads us to the following size reduction algorithm:

def size_reduce(B):
d = B.nrows()
i = 1
while i<d:
Bs,M = B.gram_schmidt()
for j in reversed(range(i)):
B[i] -= round(M[i,j])*B[j]
Bs,M = B.gram_schmidt()
return B

We can further improve this by optimizing the Gram Schmidt computation as this algorithm does not modify B\mathcal B^*at all. Furthermoreμ\muchanges in a very predictable fasion and when vectors are swapped, one can write explicit formulas for howB\mathcal B^*changes as well.

Next, we need to figure a swapping condition. Naively, we want

bibi+1\left\lVert b_i\right\rVert\leq\left\lVert b_{i+1}\right\rVert

for all ii. However, such a condition does not guarantee termination in polynomial time. As short basis vectors should be almost orthogonal, we may also want to incorperate this notion. Concretely, we want μi,j\left|\mu_{i,j}\right|to be somewhat small for all pairs of i,ji,j, i.e. we may want something like

μi,jc|\mu_{i,j}|\leq c

However, since μi,j=bi,bjbj,bj\mu_{i,j}=\frac{\langle b_i,b_j^*\rangle}{\langle b_j^*,b_j^*\rangle}, this condition is easily satisfied for a sufficiently long bjb_j^*, which is not what we want. The key idea is to merge these two in some way and was first noticed by Lovász - named the Lovász condition:

δbi2bi+1+μi+1,ibi2δ(14,1)\delta\left\lVert b_i^*\right\rVert^2\leq\left\lVert b_{i+1}^*+\mu_{i+1,i}b_i^*\right\rVert^2\quad\delta\in\left(\frac14,1\right)

It turns out that using this condition, the algorithm above terminates in polynomial time! More specifically, it has a time complexity of O(d5nlog3B)O\left(d^5n\log^3B\right)where we haveddbasis vectors as a subset of Rn\mathbb R^nand BBis a bound for the largest norm of bib_i. 14<δ\frac14<\delta ensures that the lattice vectors are ordered roughly by size and δ<1\delta<1ensures the algorithm terminates.

Polynomial time proof

This follows the proof provided by the authors of the LLL paper. We first prove that the algorithm terminates by showing it swaps the vectors finitely many times. Letddbe the number of basis vectors as a subset of Rn\mathbb R^n. Let did_ibe the volume of the lattice generated by {bj}j=1i\left\{b_j\right\}_{j=1}^iat each step of the algorithm. We have di=j=1ibjd_i=\prod_{j=1}^i\left\lVert b_j^*\right\rVert. Now consider the quantity


This quantity only changes whenever some bib_i^*changes, i.e when swaps happen. Let's consider what happens when we swap bib_iand bi+1b_{i+1}. Recall the Gram-Schmidt algorithm:

bi=bij=1i1μi,jbjμi,j=bi,bjbj,bjb_i^*=b_i-\sum_{j=1}^{i-1}\mu_{i,j}b_j^*\quad\mu_{i,j}=\frac{\langle b_i,b_j^*\rangle}{\langle b_j^*,b_j^*\rangle}

From this, see that when we swap bib_iand bi+1b_{i+1}, bib_i^*is replaced by bi+1+μi+1,ibib_{i+1}^*+\mu_{i+1,i}b_i^*. Now using the Lovász condition, we see that we havebi+1+μi+1,ibi2<δbi2\left\lVert b_{i+1}^*+\mu_{i+1,i}b_i^*\right\rVert^2<\delta\left\lVert b_i^*\right\rVert^2, hence the value of did_imust decrease by at least δ\delta, i.e. the new did_iis less than diδ\frac{d_i}\delta. All other dj,jid_j,j\neq imust remain the same as the volume remains fixed when we swap basis vectors around. Hence at each swap, DDdecreases by δ\delta. This is why we need δ<1\delta<1.Now we are left with showing did_iis bounded from below then we are done.

Let λ1(L)\lambda_1(L)be the length of the shortest (nonzero) vector in the lattice. We can treat did_ias the volume of the lattice LiL_igenerated by{bj}j=1i\left\{b_j\right\}_{j=1}^i. Let xix_ibe the shortest vector in the lattice in LiL_i. By using Minkowski's lattice point theorem, we have

(Note that the value of CiC_iisn't particularly important, one can use a easier value like i\sqrt i)

Hence we see that did_i, and hence DDhas a (loose) lower bound Dmin=i=1ddi,minD_{\min}=\prod_{i=1}^dd_{i,\min}, meaning that there are at most logDlogDminδ\frac{\log D}{\log D_{\min}\delta}swaps. Since at each iteration,kkeither increases by11when there is no swaps or decreases by at most11when there is swaps and kkranges from22todd, the number of time the loop runs must be at most 2logDlogDminδ+d2\frac{\log D}{\log D_{\min}\delta}+d, hence the algorithm terminates.

This proof also gives us a handle on the time complexity of the operation. LetBBis the length of the longest input basis vector. Since we have diBid_i\leq B^i, DBm2+m2D\leq B^{\frac{m^2+m}2}and the algorithm loops O(d2logB)O\left(d^2\log B\right)times. The Gram-Schmidt orthogonalization is the most expensive part in the entire process, taking up O(d2n)O\left(d^2n\right)arithmetic operations. By using classical algorithm for arithmetic operations, each takes O(nlogB)O\left(n\log B\right)time. From this, we deduce that the time complexity of the LLL algorithm is O(d5mlog2B)O\left(d^5m\log^2B\right), a somewhat reasonable polynomial time algorithm.

Let bib_ibe the output of the LLL algorithm, it turns out that we have the bound

b1(44δ1)d14vol(L)1d\left\lVert b_1\right\rVert\leq\left(\frac4{4\delta-1}\right)^{\frac{d-1}4}\text{vol}(L)^\frac1d

which requires δ>14\delta>\frac14. Such bounds for the shortest vector will be elaborated in more detail in the section on reduced basis.


1) Implement the LLL in sage and experimentally verify that DDdoes indeed decrease byδ\deltaeach time.

2) Show that the time complexity analysis is correct, and indeed each loop takes at most O(d2n)O\left(d^2n\right)operations.