Coverage for src\pqlattice\lattice\_embeddings.py: 34%

1 import numpy as np

2

3 from .._utils import as_integer, zeros_mat

4 from ..linalg import hnf

5 from ..typing import Matrix, SquareMatrix, Vector, validate_aliases

6

7

8 def lwe_basis(A: Matrix, q: int) -> SquareMatrix:

9 """

10 _summary_

11

12 Parameters

13 ----------

14 A : Matrix

15 _description_

16 q : int

17 _description_

18

19 Returns

20 -------

21 SquareMatrix

22 _description_

23 """

24 # lattice: L = { x | Ax = 0 mod q }

25 m, _ = A.shape

26 Im = q * as_integer(np.identity(m))

27 G = np.vstack((A.T, Im))

28 H, _ = hnf(G)

29

30 return H[:m]

31

32

33 def sis_basis(A: Matrix, q: int) -> SquareMatrix:

34 """

35 _summary_

36

37 Parameters

38 ----------

39 A : Matrix

40 _description_

41 q : int

42 _description_

43

44 Returns

45 -------

46 SquareMatrix

47 _description_

48 """

49 # lattice: L = { y | y = xA mod q }

50 B_p = lwe_basis(A, q)

51 B_inv = np.linalg.inv(B_p.astype(float))

52 B_dual = np.round(q * B_inv.T).astype(int)

53 return B_dual

54

55

56@validate_aliases

57 def kannan(A: Matrix, b: Vector, q: int) -> SquareMatrix:

58 """

59 _summary_

60

61 Parameters

62 ----------

63 A : Matrix

64 _description_

65 b : Vector

66 _description_

67 q : int

68 _description_

69

70 Returns

71 -------

72 SquareMatrix

73 _description_

74 """

75 return bai_galbraith(A, b, q, 1)

76

77

78@validate_aliases

79 def bai_galbraith(A: Matrix, b: Vector, q: int, M: int) -> SquareMatrix:

80 """

81 _summary_

82

83 Parameters

84 ----------

85 A : Matrix

86 _description_

87 b : Vector

88 _description_

89 q : int

90 _description_

91 M : int

92 _description_

93

94 Returns

95 -------

96 SquareMatrix

97 _description_

98 """

99 m, n = A.shape

100

101 Im = as_integer(np.identity(m))

102 In = as_integer(np.identity(n))

103

104 Zmxn = zeros_mat(m, n)

105 Zmx1 = zeros_mat(m, 1)

106 Znx1 = zeros_mat(n, 1)

107 Z1xn = zeros_mat(1, n)

108

109 bT = b.reshape(1, -1)

110 IM = M * (zeros_mat(1, 1) + 1)

111

112 return np.block(

113 [

114 [q * Im, Zmxn, Zmx1],

115 [A.T, In, Znx1],

116 [-bT, Z1xn, IM],

117 ]

118 )

119

120

121@validate_aliases

122 def subset_sum(sequence: Vector, S: int) -> SquareMatrix:

123 """

124 _summary_

125

126 Parameters

127 ----------

128 sequence : Vector

129 _description_

130 S : int

131 _description_

132

133 Returns

134 -------

135 SquareMatrix

136 _description_

137 """

138 n = len(sequence)

139 A = as_integer(np.identity(n + 1) * 2)

140 A[-1] = 1

141 A[:-1, -1] = sequence

142 A[-1, -1] = S

143

144 return A

145

146

147@validate_aliases

148 def ntru() -> SquareMatrix:

149 raise NotImplementedError()