Coverage for src\pqlattice\lattice\_bkz.py: 98%
48 statements
« prev ^ index » next coverage.py v7.11.0, created at 2026-01-07 03:12 +0100
« prev ^ index » next coverage.py v7.11.0, created at 2026-01-07 03:12 +0100
1from .._utils import as_integer, as_rational
2from ..typing import Matrix, SquareMatrix, Vector, validate_aliases
3from ._gso import gso
4from ._lll import lll
5from ._svp import schnorr_euchner_svp
8@validate_aliases
9def update_block(lattice_basis: SquareMatrix, new_vector: Vector, start_index: int, block_size: int) -> SquareMatrix:
10 B = as_integer(lattice_basis)
11 local_basis = as_integer([new_vector] + B[start_index : start_index + block_size].tolist())
12 reduced_local = lll(local_basis)
14 zero_vec = reduced_local[0]
15 if any(s != 0 for s in zero_vec):
16 raise ValueError("block update failed")
18 cleaned_basis = as_integer(reduced_local[1:])
20 for i in range(block_size):
21 B[start_index + i] = cleaned_basis[i]
23 return B
26@validate_aliases
27def bkz(lattice_basis: SquareMatrix, block_size: int = 10) -> SquareMatrix:
28 """_summary_
30 Parameters
31 ----------
32 lattice_basis : SquareMatrix
33 _description_
34 block_size : int, optional
35 _description_, by default 10
37 Returns
38 -------
39 SquareMatrix
40 _description_
41 """
42 n, m = lattice_basis.shape
44 B = lll(lattice_basis)
46 is_changed = True
47 while is_changed:
48 is_changed = False
49 for k in range(n - 1):
50 h = min(block_size, n - k)
51 local_basis: Matrix = B[k : k + h]
53 B_star, U = gso(local_basis)
54 B_norms2 = as_rational([sum(x * x for x in v) for v in B_star])
55 mu = U.T
56 coeffs = schnorr_euchner_svp(mu, B_norms2)
58 is_trivial = True
59 if abs(coeffs[0]) == 1:
60 is_trivial = all(c == 0 for c in coeffs[1:])
61 elif coeffs[0] == 0:
62 is_trivial = False
63 else:
64 is_trivial = False
66 if is_trivial:
67 continue
69 new_vector = as_integer([0] * m)
70 for i in range(h):
71 if coeffs[i] == 0:
72 continue
73 for d in range(m):
74 new_vector[d] += coeffs[i] * local_basis[i][d]
76 B = update_block(B, new_vector, k, h)
77 is_changed = True
78 return B