Algorithm Search⌘K

Proofs: Kannan enumeration

These are the human proofs of Kannan enumeration, at full length.

Kannan's algorithm terminates and returns an HKZ-reduced basis of the same lattice full

This proof shows: correctness, termination.

Setting. The input is n≥1n \ge 1 linearly independent rows b1,…,bn∈Qmb_1, \ldots, b_n \in \mathbb{Q}^m of the lattice LL. We write bi∗b_i^* for the Gram-Schmidt vectors, Ni=∥bi∗∥2N_i = \|b_i^*\|^2, μij=⟨bi,bj∗⟩/Nj\mu_{ij} = \langle b_i, b_j^* \rangle / N_j for j<ij < i, and πk\pi_k for the orthogonal projection onto span⁡(b1,…,bk−1)⊥\operatorname{span}(b_1, \ldots, b_{k-1})^\perp, so that πk(L)=πk(L(bk,…,bn))\pi_k(L) = \pi_k(L(b_k, \ldots, b_n)) is a lattice of rank n−k+1n - k + 1 with basis πk(bk),…,πk(bn)\pi_k(b_k), \ldots, \pi_k(b_n) and Gram-Schmidt norms Nk,…,NnN_k, \ldots, N_n. Line numbers refer to the pseudocode on the page; indices are 1,…,n1, \ldots, n here, while the implementation counts from 0. The basis is HKZ-reduced when it is size-reduced, ∣μij∣≤1/2|\mu_{ij}| \le 1/2, and

Nk=λ1(πk(L))2for k=1,…,n.(1)N_k = \lambda_1(\pi_k(L))^2 \qquad \text{for } k = 1, \ldots, n. \tag{1}

We say that the basis is HKZ from kk when (1) holds for k,k+1,…,nk, k+1, \ldots, n. This depends only on b1,…,bk−1b_1, \ldots, b_{k-1} (through πk\pi_k) and on the projections πk(bk),…,πk(bn)\pi_k(b_k), \ldots, \pi_k(b_n).

Let ss be a common denominator of the input entries. All operations below are integer row operations, so the rows stay in 1sZm\frac1s \mathbb{Z}^m and s2jDjs^{2j} D_j, with Dj=N1⋯NjD_j = N_1 \cdots N_j, is a positive integer.

Lemma 1 (row operations). Each of the following keeps LL and the rows b1,…,bk−1b_1, \ldots, b_{k-1}, hence keeps πk\pi_k and the lattice πk(L)\pi_k(L):

  1. adding an integer multiple of an earlier row to a row at position ≥k\ge k;
  2. swapping two adjacent rows at positions ≥k\ge k;
  3. replacing bk,…,bnb_k, \ldots, b_n by an integer unimodular combination of them.

Operation 1 does not change any bi∗b_i^*.

Proof. All three are unimodular operations on the rows that do not touch positions below kk. Adding a multiple of an earlier row to bib_i keeps span⁡(b1,…,bi−1)\operatorname{span}(b_1, \ldots, b_{i-1}) and the component of bib_i orthogonal to it, so no Gram-Schmidt vector changes. □\square

Lemma 2 (line L4). The LLL step on positions k,…,nk, \ldots, n terminates; it uses only operations 1 and 2 of Lemma 1.

Proof. Size reduction is operation 1 and keeps every DjD_j. A swap of positions j−1,jj - 1, j with j−1≥kj - 1 \ge k is done only when Nj+μj,j−12Nj−1<34Nj−1N_j + \mu_{j,j-1}^2 N_{j-1} < \tfrac34 N_{j-1}; the left side is the new Nj−1N_{j-1}, so Dj−1D_{j-1} decreases and the other DiD_i are Gram determinants of the same sets of rows. The positive integer ∑js2jDj\sum_j s^{2j} D_j therefore decreases at each swap, and between two swaps the position rises at most nn times. □\square

Lemma 3 (line L7 is exact). The enumeration returns a nonzero x∈Zn−k+1x \in \mathbb{Z}^{n-k+1} such that πk(∑ixibk+i)\pi_k(\sum_i x_i b_{k+i}) is a shortest nonzero vector of πk(L)\pi_k(L), together with its squared length.

Proof. By the Gram-Schmidt decomposition, ∥πk(∑j≥0xjbk+j)∥2=∑j(xj−cj)2Nk+j\|\pi_k(\sum_{j \ge 0} x_j b_{k+j})\|^2 = \sum_j (x_j - c_j)^2 N_{k+j} with cj=−∑i>jxiμk+i,k+jc_j = -\sum_{i > j} x_i \mu_{k+i,k+j}, and this is 0 only for x=0x = 0. The search starts with the value NkN_k of x=(1,0,…,0)x = (1, 0, \ldots, 0) and fixes the coordinates from the last to the first. At each level it skips only values xjx_j whose partial sum already exceeds the current best: below the start of its scan by the choice ⌊cj⌋−⌊⌊q⌋⌋−1\lfloor c_j \rfloor - \lfloor \sqrt{\lfloor q \rfloor} \rfloor - 1 with q=max⁡(best−ρ,0)/Nk+jq = \max(\mathit{best} - \rho, 0)/N_{k+j}, since then cj−xj>qc_j - x_j > \sqrt q; while rising from below cjc_j; and above cjc_j once a value fails, since all further values are further from cjc_j. The best value only decreases, so a skipped value stays useless. Every level scans a bounded interval, so the search ends, and it returns the minimum over all nonzero xx. This is the same search as in BKZ, where the proof is written out in full. □\square

Lemma 4 (line L8). If the enumeration finds a squared length smaller than NkN_k, then gcd⁡(x)=1\gcd(x) = 1, and the gcd sweep replaces bk,…,bnb_k, \ldots, b_n by a unimodular combination whose first vector is v=∑ixibk+iv = \sum_i x_i b_{k+i}. Afterwards Nk=λ1(πk(L))2N_k = \lambda_1(\pi_k(L))^2.

Proof. If g=gcd⁡(x)>1g = \gcd(x) > 1, then x/gx / g would give a vector of squared length smaller by the factor g2g^2, which contradicts Lemma 3. The sweep runs from the end of the block to its front and, for two adjacent rows u,wu, w with current coefficients yj,yj+1y_j, y_{j+1} not both 0, uses g=gcd⁡(yj,yj+1)=syj+tyj+1g = \gcd(y_j, y_{j+1}) = s y_j + t y_{j+1} to replace them by yjgu+yj+1gw\frac{y_j}{g} u + \frac{y_{j+1}}{g} w and −tu+sw-t u + s w. This 2×22 \times 2 matrix has determinant 1 and keeps ∑jyjbk+j\sum_j y_j b_{k+j} with yj←gy_j \leftarrow g, yj+1←0y_{j+1} \leftarrow 0. At the end the coefficients are (1,0,…,0)(1, 0, \ldots, 0), so the new bkb_k is vv. This is operation 3 of Lemma 1, so πk\pi_k is unchanged and the new bk∗=πk(v)b_k^* = \pi_k(v) is a shortest nonzero vector of πk(L)\pi_k(L). □\square

Calls. The stack starts with the single task (1,start)(1, \mathrm{start}). When a task (k,start)(k, \mathrm{start}) is popped with the rest of the stack equal to σ\sigma, call the run from that moment until the stack is again equal to σ\sigma the call at kk. Every task pushed while it runs has index at least kk and lies above σ\sigma.

Lemma 5 (one call). For every kk, a call at kk terminates. It does not change b1,…,bk−1b_1, \ldots, b_{k-1} or LL, and when it ends the basis is HKZ from kk.

Proof. By downward induction on kk.

Case k=nk = n. Line L3 discards the task. The lattice πn(L)=Zbn∗\pi_n(L) = \mathbb{Z} b_n^* has λ12=Nn\lambda_1^2 = N_n, so the basis is HKZ from nn.

Case k<nk < n. Line L4 terminates by Lemma 2 and pushes (k,check)(k, \mathrm{check}) and then (k+1,start)(k + 1, \mathrm{start}), which is popped next. By induction the call at k+1k + 1 terminates, keeps b1,…,bkb_1, \ldots, b_k, and leaves the basis HKZ from k+1k + 1; then (k,check)(k, \mathrm{check}) is on top and is popped. From now on, every time (k,check)(k, \mathrm{check}) is popped, the basis is HKZ from k+1k + 1, which we use as an invariant.

Line L5 is operation 1 on bk+1b_{k+1}; it keeps all bi∗b_i^* and the projection πk+1(bk+1)\pi_{k+1}(b_{k+1}), so the basis stays HKZ from k+1k + 1, and afterwards ∣μk+1,k∣≤1/2|\mu_{k+1,k}| \le 1/2.

If Nk>4Nk+1N_k > 4 N_{k+1} on line L6, the swap is operation 2 and makes the new NkN_k equal to Nk+1+μk+1,k2Nk≤Nk+1+14Nk<12NkN_{k+1} + \mu_{k+1,k}^2 N_k \le N_{k+1} + \tfrac14 N_k < \tfrac12 N_k. The tasks (k,check)(k, \mathrm{check}) and (k+1,start)(k + 1, \mathrm{start}) are pushed; the call at k+1k + 1 restores the invariant and does not change bkb_k, so NkN_k keeps its new value. Thus each swap at this level halves NkN_k at least, while Nk≥λ1(πk(L))2>0N_k \ge \lambda_1(\pi_k(L))^2 > 0 always holds, because bk∗b_k^* is a nonzero vector of πk(L)\pi_k(L), a lattice that does not change during the call by Lemma 1. So line L6 swaps at most log⁡2 ⁣(Nk/λ1(πk(L))2)+1\log_2\!\big(N_k / \lambda_1(\pi_k(L))^2\big) + 1 times, with NkN_k its value at the first check.

When line L6 does not swap, line L7 computes λ1(πk(L))2\lambda_1(\pi_k(L))^2 by Lemma 3. If it is smaller than NkN_k, line L8 makes Nk=λ1(πk(L))2N_k = \lambda_1(\pi_k(L))^2 (Lemma 4) and pushes (k+1,start)(k + 1, \mathrm{start}). The call at k+1k + 1 does not change b1,…,bkb_1, \ldots, b_k, so (1) still holds at kk, and it makes the basis HKZ from k+1k + 1; then the stack is σ\sigma again and the call at kk ends, HKZ from kk. If instead the enumerated length equals NkN_k, then (1) already holds at kk, the invariant gives it from k+1k + 1 on, nothing is pushed, and the call ends.

Every step of the call is one of the operations of Lemma 1 at positions ≥k\ge k, so b1,…,bk−1b_1, \ldots, b_{k-1} and LL do not change. □\square

Theorem. The algorithm terminates and returns an HKZ-reduced basis of LL. Its first row is a shortest nonzero vector of LL.

Proof. The whole loop of lines L2 to L8 is the call at 1, with σ\sigma empty, so by Lemma 5 it terminates and leaves a basis of LL that satisfies (1) for every kk. Line L9 is a sequence of operations 1 of Lemma 1; it makes ∣μij∣≤1/2|\mu_{ij}| \le 1/2 for all j<ij < i and changes no Gram-Schmidt vector, so (1) still holds and the basis is HKZ-reduced. Since b1=b1∗b_1 = b_1^*, (1) at k=1k = 1 says ∥b1∥=λ1(L)\|b_1\| = \lambda_1(L). ■\blacksquare

Back to Kannan enumeration