Recreational Mathematics Club

Discussion #4
  
12-Eye Portal Seed and the LLL algorithm
  

Speaker: Dhairya Baxi, Mahek Shamsukha

Indian Institute of Science

1 What is a Linear Congruential Generator?

A Linear Congruential Generator (LCG) is a simple pseudorandom number generator (PRNG) defined by the recurrence relation:

seed :=  (a ⋅seed+ b)  mod  m

where the parameters are:

Each call to the generator updates the seed and outputs it (or some function of it) as the next pseudorandom value. The entire future sequence is thus fully determined by the initial seed and the triple (a,b,m).

2 Primer: Modular Inverses

The modular inverse of an integer a modulo m is the integer a1 such that:

a⋅a− 1 ≡ 1 (mod  m )

It exists if and only if gcd(a,m) = 1. When it does, it can be computed efficiently in O(log m) using the Extended Euclidean Algorithm:

Algorithm 1: mod_inverse(a,m)
1:   Input: integers a, m
2:   Output: a1 mod m
3:   g,x, _ ExtendedGCD(a,m)
4:   if g≠then
5:    return inverse does not exist
6:   end if
7:   return x mod m

Modular inverses let us “divide” in modular arithmetic, instead of computing x∕a mod m, we compute x a1 mod m.

3 Next and Forward Routines

We define two fundamental operations on an LCG state.

3.1 Primitive: next

next(x) applies one step of the recurrence:

next(x) = (a⋅x + b)  mod m

3.2 Naive forward

forward(x,n) applies next n times iteratively:

Algorithm 2: forward(x,n), naive O(n)
1:   Input: state x, step count n
2:   Output: nextn(x)
3:   for i = 1 to n do
4:    x (a x + b) mod m
5:   end for
6:   return x

This runs in O(n) time, which is impractical for large n.

3.3 Closed Form

Unrolling the recurrence n times gives:

                                                             n−1
forward (x,n) = a(a(...(a ⋅x+  b) ...)+ b) + b  mod m  = anx + b∑  ai  mod  m

                                                             i=0

Applying the geometric series formula (for a≠1):

                       (       )
forward (x,n) = anx + b  an −-1   mod  m
                         a − 1

This reduces the problem to computing an mod m, which can be done in O(log n) via fast modular exponentiation.

3.4 Efficient forward in O(log n)

Algorithm 3: forward(x,n), efficient O(log n)
1:   Input: state x, step count n
2:   Output: nextn(x)
3:   an ModPow(a, n, m)
4:   if a = 1 then
5:    return (x + b n) mod m
6:   end if
7:   inv_a1 ModInverse(a 1, m)
8:   return (an x + b (an 1) inv_a1) mod m

The modular inverse of (a 1) exists whenever gcd(a 1, m) = 1, which holds for typical LCG parameters.

4 Prev and Backward Routines

4.1 Primitive: prev

Just as next applies the recurrence forward, prev(x) inverts it, recovering the state that would have produced x. Starting from:

x = (a ⋅x   +  b)  mod  m
         prev

we solve for xprev:

xprev = a−1(x − b)  mod m

where a1 is the modular inverse of a modulo m (which exists when gcd(a,m) = 1). In code:

Algorithm 4: prev(x)
1:   Input: state x
2:   Output: the unique xprev such that next(xprev) = x
3:   inv_a ModInverse(a, m)
4:   return (inv_a (x b)) mod m

4.2 Primitive: backward

backward(x,n) applies prev n times, stepping the generator n steps into the past. The naive implementation runs in O(n):

Algorithm 5: backward(x,n)
1:   Input: state x, step count n
2:   Output: prevn(x)
3:   for i = 1 to n do
4:    x Prev(x)
5:   end for
6:   return x

Note that backward(x,n) is equivalent to forward(x,n), so an efficient O(log n) version follows from the same closed form as before, substituting a1 and b a1 as the new multiplier and increment respectively.

5 The Seed-Finding Problem

The general problem is to find an initial seed whose LCG outputs fall within prescribed intervals over several consecutive steps. For a concrete application of this framework to finding Minecraft world seeds with fully-filled stronghold portals, see Appendix A.

5.1 General Problem Formulation

More generally, the problem we study is:

Given bounds m1,M1,…,mk,Mk and an offset n, find an initial seed seed0 such that for each i ∈{1,…,k}:

mi ≤  seedn+i ≤  Mi

That is, we want k consecutive outputs of the LCG, starting from step n, to each fall within a prescribed interval. The challenge is to search over the space of possible seeds seed0 [0,m) efficiently, brute force is infeasible when m is large (e.g. m = 248 in Java’s Random).

5.2 Reducing to Constraints on seed0

Using the closed form for forward, every constraint on seedn+i can be written directly in terms of seed0. Crucially, the offset n is handled for free: given any candidate seedn, we can recover seed0 = backward(seedn,n) in O(log n), or equivalently jump ahead with forward(seed0,n). This means we can freely translate between constraints on seed0 and constraints on any other step.

Expressing seedn+i = forward(seed0, n + i) via the closed form, the system of k constraints becomes (shown here for n = 0, k = 12):

        ⌊           (a0 − 1) ⌋
min  ≤   a0seed0 + b ------    mod m  ≤  max
  0                   a− 1                0

        ⌊           (      ) ⌋
          1          a1-−-1
min1  ≤   a seed0 + b  a− 1     mod m  ≤  ma1x

...

       ⌊            ( 11    ) ⌋
min ≤   a11seed  + b a---−-1   mod  m  ≤  max
 11             0      a − 1                11

Each constraint is a modular interval condition on seed0. The problem reduces to finding all seed0 [0,m) satisfying all k such constraints simultaneously.

5.3 Removing the Modulus

The modular reduction is the main obstacle to solving the system directly. We eliminate it by observing that x mod m = x km for some integer k 0. That is, for each constraint i there exists an unknown integer ki such that:

          (       )
 i          ai −-1
a seed0 + b a − 1   − kim

is the true (non-reduced) value. Substituting this into the bounds and rearranging, moving the b(⋅⋅⋅) term to both sides, each modular inequality becomes an ordinary linear inequality:

      (       )                             (       )
        a0-−-1       0                        a0 −-1-
mi0n − b  a− 1    ≤ a  seed0 + k0m  ≤  max0 − b  a − 1

      (  1    )                             (  1    )
min − b a--−-1   ≤ a1 seed  + k m  ≤  max − b  a-−-1-
 1       a− 1             0   1        1      a − 1

.
..

       ( a11 − 1)                               ( a11 − 1)
min − b  -------  ≤  a11seed0 + k11m  ≤  max − b  -------
 11      a − 1                           11      a − 1

The system now has k + 1 unknowns (seed0 and the integers k0,…,kk1) and 2k linear inequalities over the integers. No modular arithmetic remains, the problem has been lifted to an integer linear feasibility problem.

5.4 Matrix Formulation

We can write the system compactly by collecting the unknowns into a vector ˆx = (seed0, k0, k1, …, kn1) and defining:

                                     ⌊             ⌋
                                        (   0    )
    ⌊  1     0  0   ⋅⋅⋅  0⌋          || b  aα1 −-1  ||
    |  α1                 |          ||  (  a− 1  ) ||
    || aα2   m   0   ⋅⋅⋅  0||          ||    aα2 −-1  ||
A = | a      0  m   ⋅⋅⋅  0| ,    ˆb = | b   a− 1    | ,
    |⌈   ...    ...   ...  ...  ...|⌉          ||      ..      ||
     aαn−1   0  0   ⋅⋅⋅ m            || (    .     )||
                                     ⌈b  aαn−1 −-1 ⌉
                                           a− 1

       ⌊       ⌋            ⌊        ⌋
         min0                  max0
 ^     || min1  ||            ||  max1  ||
min =  |⌈   ...   |⌉,    m^ax  = |⌈    ...   |⌉.

        minn− 1              maxn − 1

The entire seed-finding problem then reduces to finding an integer vector ˆx such that:

^min ≤  A ˆx+ ˆb ≤ m^ax

subject to 0 x1 = seed0 < m. Crucially, the possible values of Aˆx + ˆb mod m are exactly the possible tuples of consecutive LCG seeds, so any solution ˆx directly yields a valid initial seed.

5.5 Geometric Interpretation: A Lattice Problem

The columns of A generate a lattice, the set of all integer linear combinations Aˆx for ˆx n. The constraint ^min Aˆx + ˆb m^ax asks for lattice points that land inside the axis-aligned box [^min, m^ax] after the shift by ˆ
b .

Equivalently, applying A1 to both sides transforms the axis-aligned box into a (potentially skewed) parallelogram in the space of integer vectors ˆx, and we seek all integer points inside that parallelogram. This is illustrated below:

PIC

Figure 1: Left: the lattice spanned by columns a0,a1 of A, with the target box (grey) and lattice points inside it (green). Right: after applying A1, the lattice becomes n and the box becomes a skewed parallelogram, we now seek integer points inside it.

This reframing connects the seed-finding problem to classical problems in the geometry of numbers, and motivates the use of lattice reduction algorithms such as LLL to efficiently enumerate solutions.

6 Branch and Bound

Having reduced the problem to finding integer vectors ˆx satisfying ^
min Aˆx + ˆ
b m^ax, we now describe how to enumerate all such solutions via branch and bound.

6.1 The Linear Programme

Because A is lower triangular, the system ^
min Axˆ + ˆ
b ^max can be solved one variable at a time from the bottom row upward. Suppose components xi+1,…,xn1 have already been fixed. Row i of the system reads:

^               ∑          ˆ
mini ≤  Aiixi +    Aij xj + bi ≤ m^axi
                j◟>i--◝◜-----◞
                    known

Isolating xi gives the real interval:

     ^      ˆ   ∑                            ˆ   ∑
l =  mini-−-bi −--j>iAij xj-,   u  =  ^maxi-−-bi −--j>iAij xj
i             Aii                i             Aii

Since xi must be an integer, the feasible values are xi ∈{⌈li,…,ui⌋}. If li> ui, the partial assignment is infeasible and the branch is immediately pruned.

6.2 The Subroutine

The algorithm recurses from the last variable to the first, branching over all integer values in the feasible interval at each level:

Algorithm 6: BranchAndBound(A, ˆb , ^min, m^ax, ˆx, i)
1:   Input: system matrix A, offset ˆ b , bounds ^ min, m^ax,
       partial solution ˆx (components i+1,…,n1 fixed), current index i
2:   Output: all integer vectors ˆx satisfying ^min Aˆx + ˆb m^ax
3:   if i < then
4:    yield ˆx ⊳  full solution found
5:    return
6:   end if
7:   fixed j=i+1n1A ij xj
8:   l ^mini-−-ˆbi −-fixed       Aii, u m^axi-−-ˆbi −-fixed       Aii
9:   if l> u then
10:    return ⊳  prune: no valid integer exists
11:   end if
12:   for v = lto u do
13:    xi v
14:    yield from BranchAndBound(A, ˆb , m^in, ^max, ˆx, i 1)
15:   end for

The outermost call is BranchAndBound(A, ˆb , ^min, m^ax, x, n1). Each leaf that reaches i < 0 yields a valid ˆx, from which seed0 = x0 is read off directly.

PIC

The worst-case complexity is exponential in the number of solutions, but pruning makes it efficient in practice when the feasible parallelogram is small, which is precisely what LLL achieves by reducing the basis before running this search.

7 Basis Choice and Lattice Reduction

7.1 Different Bases, Same Lattice

A lattice has infinitely many bases. If B = (b1,…,bn) is one basis and U is any unimodular matrix (integer matrix with detU = ±1), then BU is another valid basis generating the same lattice.

Observation. Two bases for the same lattice can produce parallelograms of wildly different shapes. A skewed basis yields a thin, elongated parallelogram; an orthogonal basis yields a compact, box-like one.

7.2 What Makes a Good Basis?

We want a basis B = (b1,…,bn) where:

Such a basis makes the corresponding parallelepiped well-shaped and better aligned with the coordinate axes, dramatically improving the performance of branch-and-bound methods.

Motivation for the next step. Finding an optimal basis (e.g. shortest or most orthogonal) is NP-hard in general. However, efficient approximation algorithms exist. The most celebrated is the LLL algorithm (Lenstra–Lenstra–Lovász, 1982), which computes, in polynomial time, a basis that is nearly orthogonal and well-balanced. In particular, it guarantees that the first basis vector is within an exponential factor of the shortest nonzero lattice vector.

8 The LLL Algorithm

8.1 δ-LLL Reduced Basis

Let B = (b1,…,bn) be a basis of a lattice ℒ⊂ m. Let b1,…,bn be its Gram–Schmidt orthogonalization:

        ∑
bi = b∗i +   μi,jb∗j.
         j<i

Definition 8.1. Let δ (14,1). The basis B is called δ-LLL reduced if:

1.
For all i > j, |μi,j|≤1
2,
2.
For all i = 1,…,n 1,
∥b∗  ∥2 ≥  (δ − μ2  )∥b∗∥2.
  i+1            i+1,i  i

8.2 Bound on the Shortest Vector

Theorem 8.2. If B is a δ-LLL reduced basis of , then

         n−1
∥b1∥ ≤  2 2  ⋅λ1(ℒ ),

where λ1() is the length of the shortest nonzero lattice vector.

8.3 LLL Algorithm

Algorithm 7: LLL(B, δ)
1:   Input: B m×n, δ (14,1)
2:   Output: A δ-LLL reduced basis generating the same lattice
3:   B SizeReduce(B)
4:   if  i such that bi+12 < (δ μi+1,i2)bi2 then
5:    Swap bi,bi+1
6:    return LLL(B,δ)
7:   end if
8:   return B

8.4 Size Reduction via Column Operations

Recall the Gram–Schmidt decomposition

      ∗
B = B  M,

where B = (b1,…,bn) has orthogonal columns and M = (μi,j) is upper triangular with μi,i = 1.

Size reduction corresponds to modifying the columns of B using integer column operations so that

       1
|μi,j| ≤ 2 for all i > j.

We proceed column by column. For j = 1,…,n, and for i = j 1,j 2,…,1, perform the operation

bj ←  bj − ⌊μj,i⌉bi,

where ⌊⋅⌉ denotes rounding to the nearest integer.

This is an elementary column operation on B, and corresponds to updating the matrix M by

μj,i ←  μj,i − ⌊μj,i⌉,

which ensures

       1
|μj,i| ≤ 2.

Key point. Size reduction is achieved purely by integer column operations on B, preserving the lattice, while ensuring all Gram–Schmidt coefficients satisfy |μi,j|≤12.

8.5 Existence of LLL-Reduced Basis

Theorem 8.3. Let B m×n be an integer basis and let δ (14,1). Then there exists an integer basis Bsuch that:

1.
Bis δ-LLL reduced,
2.
Bgenerates the same lattice as B.

Proof. We prove correctness and finiteness of the LLL algorithm.

(Correctness). If the algorithm terminates, then no Lovász condition is violated, and the basis is size-reduced. Hence the output basis is δ-LLL reduced.

(Lattice preservation). All operations used are integer column operations:

Thus the output basis is obtained from the input by unimodular transformations, and therefore generates the same lattice.

(Finiteness) Define a potential

          ∏n
Φ (B) :=     det(ℒ (b1,...,bi)),
          i=1

where (b1,…,bi) denotes the lattice generated by b1,…,bi.

Equivalently, since

                                                       ∏i
det(ℒ(b1,...,bi)) = vol of the fundamental parallelepiped =    ∥b∗j∥,
                                                       j=1

we may write

         n  i
Φ (B) = ∏  ∏  ∥b∗∥.
                j
        i=1j=1

Effect of size reduction. Size reduction does not change the Gram–Schmidt vectors bj. Hence Φ(B) remains unchanged.

Effect of swapping bi,bi+1. All prefixes except the i-th remain unchanged, so only the factor

det(ℒ (b1,...,bi))

changes.

Let Φdenote the potential after swapping bi and bi+1.

First observe how the Gram–Schmidt vectors change. Consider the prefix

(b1,...,bi−1,bi+1 ).

For this sequence, the Gram–Schmidt vectors are

b∗1,...,b∗i−1, b∗i′+1,

where the first i 1 vectors remain unchanged, and

             i− 1
 ∗′          ∑        ∗    ∗          ∗
bi+1 = bi+1 −    μi+1,jbj = bi+1 + μi+1,ibi.
             j=1

Thus,

∥b∗′ ∥2 = ∥b∗  ∥2 + μ2   ∥b∗∥2.
  i+1      i+1      i+1,i  i

Now, since only the i-th prefix changes in the potential, we have

  ′                              ∗′
Φ--= det(ℒ-(b1,...,bi−1,bi+1))=  ∥bi+1∥-.
Φ        det(ℒ (b1,...,bi))        ∥b∗i∥

If the Lovász condition is violated, then

  ∗   2        2      ∗ 2
∥bi+1∥ < (δ − μi+1,i)∥bi∥ ,

and hence

  ∗′  2      ∗ 2
∥bi+1∥  < δ∥bi∥ .

Taking square roots,

Φ′   √--
--<   δ < 1.
Φ

Finiteness. Observe that for each i,

                   ∘ ----------
det(ℒ(b1,...,bi)) =   det(BTi Bi ),

where Bi is the matrix with columns b1,…,bi. Since Bi has integer entries, det(BiT Bi) is an integer, and hence each factor in Φ(B) is a square root of a positive integer.

Therefore, Φ(B) itself is a product of square roots of integers, and can take values only in a discrete subset of >0. In particular, in the interval (0,Φ(Bin)], it can assume only finitely many values.

Since each swap strictly decreases Φ(B) by at least a constant factor √ --
  δ < 1, the sequence of potentials is strictly decreasing and cannot be infinite.

Therefore, the algorithm terminates.

Combining the above, a δ-LLL reduced basis Bexists. □

References

A Appendix: Minecraft 12-Eyed Seed

In Minecraft, an End Portal consists of 12 slots, each of which requires an Ender Eye to be filled. When a world is generated, each slot may already be pre-filled.

Internally, this is determined using calls to a pseudorandom generator (Random::nextFloat() in Java), which maps the internal seed to a value in [0,1). A slot is filled if this value exceeds 0.9.

The Java random number generator is a linear congruential generator:

seedi+1 ≡ 25214903917 ⋅seedi + 11 (mod  248).

In the world-generation pipeline, the first 760 calls are irrelevant for the portal. Thus, we begin at seed761 and require that the next 12 calls all satisfy

nextFloat() > 0.9.

This translates to the constraint

seedi ∈ [253327472328704, 248 − 1],    i = 761,...,772,

since

0.9 ⋅248 = 253327472328704.

Connection to our problem. This is an instance of the LCG constraint problem with:

Thus, finding a 12-eyed seed reduces to finding integer points satisfying linear constraints derived from an LCG, precisely the type of problem we studied using lattice methods and the LLL algorithm.

PIC