Coverage for src\pqlattice\_backends\_fast.py: 53%
57 statements
« prev ^ index » next coverage.py v7.11.0, created at 2026-01-10 12:32 +0100
« prev ^ index » next coverage.py v7.11.0, created at 2026-01-10 12:32 +0100
1from typing import Any, override
3from .._utils import as_integer
4from ..typing import Array, Matrix, SquareMatrix, Vector
5from ._protocol import BackendInterface
7try:
8 import fpylll
10 HAS_FPYLLL = True
11except ImportError:
12 HAS_FPYLLL = False
14try:
15 import flint
17 HAS_FLINT = True
18except ImportError:
19 HAS_FLINT = False
22class FastBackend(BackendInterface):
23 def __init__(self) -> None:
24 if not (HAS_FPYLLL and HAS_FLINT):
25 raise RuntimeError("Fast backend is unavailable - dependencies missing")
27 def _to_fpylll(self, a: Array) -> Any:
28 return fpylll.IntegerMatrix.from_matrix(a.tolist())
30 def _from_fpylll(self, mat: Any) -> Array:
31 data = [list(row) for row in mat]
32 return as_integer(data)
34 def _to_flint(self, a: Array) -> Any:
35 return flint.fmpz_mat(a.tolist())
37 def _from_flint(self, mat: Any) -> Array:
38 return as_integer(mat.table())
40 @override
41 def lll(self, lattice_basis: SquareMatrix, delta: float) -> SquareMatrix:
42 mat = self._to_fpylll(lattice_basis)
43 fpylll.LLL.reduction(mat, delta=delta)
44 return self._from_fpylll(mat)
46 @override
47 def bkz(self, lattice_basis: SquareMatrix, block_size: int, delta: float) -> SquareMatrix:
48 mat = self._to_fpylll(lattice_basis)
49 # fpylll.BKZ.reduction(mat, delta=delta)
50 mat_bkz = fpylll.BKZ.reduction(mat, fpylll.BKZ.Param(block_size=block_size))
51 return self._from_fpylll(mat_bkz)
53 @override
54 def hkz(self, lattice_basis: SquareMatrix, delta: float) -> SquareMatrix:
55 return self.bkz(lattice_basis, len(lattice_basis), delta)
57 @override
58 def shortest_vector(self, lattice_basis: SquareMatrix) -> Vector:
59 mat = self._to_fpylll(lattice_basis)
60 fpylll.LLL.reduction(mat)
61 sv = fpylll.SVP.shortest_vector(mat, pruning=False, preprocess=False)
62 return as_integer(sv)
64 @override
65 def closest_vector(self, lattice_basis: SquareMatrix, target_vector: Vector) -> Vector:
66 A = self._from_fpylll(lattice_basis)
67 t = target_vector.tolist()
68 v0 = fpylll.CVP.closest_vector(A, t)
69 return as_integer(v0)
71 @override
72 def hnf(self, matrix: Matrix) -> tuple[Matrix, SquareMatrix]:
73 mat = self._to_flint(matrix)
74 H, U = mat.hnf(transform=True)
75 return self._from_flint(H), self._from_flint(U)