kryptools 0.5__tar.gz → 0.6__tar.gz

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (28) hide show
  1. {kryptools-0.5 → kryptools-0.6}/PKG-INFO +1 -1
  2. {kryptools-0.5 → kryptools-0.6}/kryptools/__init__.py +1 -1
  3. {kryptools-0.5 → kryptools-0.6}/kryptools/la.py +14 -2
  4. {kryptools-0.5 → kryptools-0.6}/kryptools/lat.py +13 -4
  5. {kryptools-0.5 → kryptools-0.6}/kryptools/poly.py +25 -8
  6. {kryptools-0.5 → kryptools-0.6}/kryptools.egg-info/PKG-INFO +1 -1
  7. {kryptools-0.5 → kryptools-0.6}/pyproject.toml +1 -1
  8. {kryptools-0.5 → kryptools-0.6}/LICENSE +0 -0
  9. {kryptools-0.5 → kryptools-0.6}/README.md +0 -0
  10. {kryptools-0.5 → kryptools-0.6}/kryptools/Zmod.py +0 -0
  11. {kryptools-0.5 → kryptools-0.6}/kryptools/dlp.py +0 -0
  12. {kryptools-0.5 → kryptools-0.6}/kryptools/dlp_bsgs.py +0 -0
  13. {kryptools-0.5 → kryptools-0.6}/kryptools/dlp_ic.py +0 -0
  14. {kryptools-0.5 → kryptools-0.6}/kryptools/dlp_qs.py +0 -0
  15. {kryptools-0.5 → kryptools-0.6}/kryptools/dlp_rho.py +0 -0
  16. {kryptools-0.5 → kryptools-0.6}/kryptools/ec.py +0 -0
  17. {kryptools-0.5 → kryptools-0.6}/kryptools/factor.py +0 -0
  18. {kryptools-0.5 → kryptools-0.6}/kryptools/factor_dix.py +0 -0
  19. {kryptools-0.5 → kryptools-0.6}/kryptools/factor_ecm.py +0 -0
  20. {kryptools-0.5 → kryptools-0.6}/kryptools/factor_fmt.py +0 -0
  21. {kryptools-0.5 → kryptools-0.6}/kryptools/factor_pm1.py +0 -0
  22. {kryptools-0.5 → kryptools-0.6}/kryptools/factor_qs.py +0 -0
  23. {kryptools-0.5 → kryptools-0.6}/kryptools/nt.py +0 -0
  24. {kryptools-0.5 → kryptools-0.6}/kryptools/primes.py +0 -0
  25. {kryptools-0.5 → kryptools-0.6}/kryptools.egg-info/SOURCES.txt +0 -0
  26. {kryptools-0.5 → kryptools-0.6}/kryptools.egg-info/dependency_links.txt +0 -0
  27. {kryptools-0.5 → kryptools-0.6}/kryptools.egg-info/top_level.txt +0 -0
  28. {kryptools-0.5 → kryptools-0.6}/setup.cfg +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.1
2
2
  Name: kryptools
3
- Version: 0.5
3
+ Version: 0.6
4
4
  Summary: Implemenation of same basic algorithms used in cryptography.
5
5
  Author-email: Gerald Teschl <gerald.teschl@univie.ac.at>
6
6
  Project-URL: Homepage, https://github.com/teschlg/kryptools
@@ -8,6 +8,6 @@ from .factor import factorint
8
8
  from .dlp import dlog
9
9
  from .ec import EC_Weierstrass
10
10
  from .la import Matrix, zeros, eye
11
- from .lat import gram_det, hadamard_ratio, hermite_nf, gram_schmidt, babai_round_cvp, babai_plane_cvp, lagrange_lr, lll, random_unimodular_matrix
11
+ from .lat import gram_det, hadamard_ratio, hermite_nf, gram_schmidt, babai_round_cvp, babai_round_bnd, babai_plane_cvp, babai_plane_bnd, lagrange_lr, lll, random_unimodular_matrix
12
12
  from .poly import Poly
13
13
  from .Zmod import Zmod
@@ -4,7 +4,7 @@ Linear algebra
4
4
 
5
5
  from math import inf, sqrt, prod
6
6
  from numbers import Number
7
-
7
+ from fractions import Fraction
8
8
 
9
9
  class Matrix:
10
10
  """
@@ -148,6 +148,8 @@ class Matrix:
148
148
  for j in range(other.cols):
149
149
  for k in range(other.rows):
150
150
  result.matrix[i][j] += self.matrix[i][k] * other.matrix[k][j]
151
+ if self.rows == 1 and other.cols == 1:
152
+ return result.matrix[0][0]
151
153
  return result
152
154
 
153
155
  def __add__(self, other) -> "Matrix":
@@ -176,7 +178,7 @@ class Matrix:
176
178
 
177
179
  def __rmul__(self, other) -> "Matrix":
178
180
  if isinstance(other, Number) or type(other) == type(self.matrix[0][0]):
179
- return Matrix([ [item * other for item in row] for row in self.matrix ])
181
+ return Matrix([ [item * other for item in row] for row in self.matrix ])
180
182
  return NotImplemented
181
183
 
182
184
  def rref(self) -> "Matrix":
@@ -246,6 +248,16 @@ class Matrix:
246
248
  raise ValueError("Matrix is not invertible!")
247
249
  return MM[:,n:]
248
250
 
251
+ def is_unimodular(self) -> bool:
252
+ "Test if the matrix is unimodular."
253
+ if self.rows != self.rows:
254
+ return False
255
+ def is_integer(i):
256
+ if isinstance(i, int) or (isinstance(i, Fraction) and i.denominator == 1):
257
+ return True
258
+ return False
259
+ return all([is_integer(i) for i in self]) and self.det()**2 == 1
260
+
249
261
  def zeros(self, m: int = None, n: int = None):
250
262
  "Returns a zero matrix of the same dimension"
251
263
  if not m and not n:
@@ -2,7 +2,7 @@
2
2
  Lattice tools
3
3
  """
4
4
 
5
- from math import prod
5
+ from math import prod, floor
6
6
  from fractions import Fraction
7
7
  from random import choice, sample
8
8
  from .la import Matrix, zeros
@@ -73,19 +73,28 @@ def hadamard_ratio(M: Matrix) -> float:
73
73
  return (gram_det(M) / prod([M[:, i].norm() for i in range(m)])) ** (1 / m)
74
74
 
75
75
  def babai_round_cvp(x: Matrix, U: Matrix) -> Matrix:
76
- "Babai's rounding algorithm for solving the CVP."
76
+ "Babai's rounding algorithm for approximately solving the CVP."
77
77
  s = U.inv() * x
78
78
  k = s.applyfunc(round)
79
79
  return U * k
80
80
 
81
+ def babai_round_bnd(U: Matrix) -> float:
82
+ "Bound for Babai's rounding algorithm for solving the CVP."
83
+ return floor(1 / (2 * max([ U.inv()[i,:].norm(1) for i in range(U.rows)])))
84
+
81
85
  def babai_plane_cvp(x: Matrix, U: Matrix) -> Matrix:
82
- "Babai's closest plane algorithm for solving the CVP."
86
+ "Babai's closest plane algorithm for approximately solving the CVP."
83
87
  Us = gram_schmidt(U)[0]
84
88
  y = x
85
89
  for k in range(U.cols - 1, -1, -1):
86
90
  y = y - round(y.dot(Us[:, k]) / norm2(Us[:, k])) * U[:, k]
87
91
  return (x - y).applyfunc(round)
88
92
 
93
+ def babai_plane_bnd(U: Matrix, p = 2) -> float:
94
+ "Bound for Babai's closest plane algorithm for solving the CVP."
95
+ Us = gram_schmidt(U)[0]
96
+ return float(0.5 * min([Us[:, i].norm(p) for i in range(Us.rows)]))
97
+
89
98
  def lagrange_lr(V: Matrix) -> Matrix:
90
99
  "Lagrange lattice reduction."
91
100
  assert (V.rows, V.cols) == (2, 2)
@@ -99,7 +108,7 @@ def lagrange_lr(V: Matrix) -> Matrix:
99
108
  return Matrix([list(v1), list(v3)]).transpose()
100
109
 
101
110
  def lll(V: Matrix, delta: float = 0.75, sort: bool = True) -> Matrix:
102
- "lll algorithm for lattice reduction"
111
+ "LLL algorithm for lattice reduction."
103
112
 
104
113
  assert 0 < delta <= 1, f"LLL reqires 0 < delta={delta} <= 1"
105
114
  j = 1
@@ -94,10 +94,13 @@ class Poly:
94
94
  "Apply a given function to all coefficients."
95
95
  self.coeff = list(map(func, self.coeff))
96
96
 
97
+ def _check_type(self, other):
98
+ return isinstance(other, int) or (isinstance(other, Number) and isinstance(self.coeff[0], Number)) or type(other) == type(self.coeff[0])
99
+
97
100
  def __add__(self, other: "Poly") -> "Poly":
98
101
  if not isinstance(other, self.__class__):
99
- tmp = self.coeff[:]
100
- if isinstance(other, int) or type(other) == type(tmp[0]):
102
+ if self._check_type(other):
103
+ tmp = self.coeff[:]
101
104
  tmp[0] += other
102
105
  return self.__class__(tmp, modulus=self.modulus)
103
106
  return NotImplemented
@@ -117,7 +120,7 @@ class Poly:
117
120
 
118
121
  def __radd__(self, other: "Poly") -> "Poly":
119
122
  if not isinstance(other, self.__class__):
120
- if isinstance(other, Number) or type(other) == type(self.coeff[0]):
123
+ if self._check_type(other):
121
124
  tmp = self.coeff[:]
122
125
  tmp[0] += other
123
126
  return self.__class__(tmp, modulus=self.modulus)
@@ -128,7 +131,7 @@ class Poly:
128
131
 
129
132
  def __sub__(self, other: "Poly") -> "Poly":
130
133
  if not isinstance(other, self.__class__):
131
- if isinstance(other, int) or type(other) == type(self.coeff[0]):
134
+ if self._check_type(other):
132
135
  tmp = self.coeff[:]
133
136
  tmp[0] -= other
134
137
  return self.__class__(tmp, modulus=self.modulus)
@@ -149,7 +152,7 @@ class Poly:
149
152
 
150
153
  def __rsub__(self, other: "Poly") -> "Poly":
151
154
  if not isinstance(other, self.__class__):
152
- if isinstance(other, int) or type(other) == type(self.coeff[0]):
155
+ if self._check_type(other):
153
156
  tmp = self.coeff[:]
154
157
  tmp[0] -= other
155
158
  return self.__class__(tmp, modulus=self.modulus)
@@ -157,7 +160,7 @@ class Poly:
157
160
 
158
161
  def __mul__(self, other: "Poly") -> "Poly":
159
162
  if not isinstance(other, self.__class__):
160
- if isinstance(other, int) or type(other) == type(self.coeff[0]):
163
+ if self._check_type(other):
161
164
  return Poly([other * s for s in self.coeff], modulus = self.modulus)
162
165
  return NotImplemented
163
166
  ls, lo = len(self.coeff), len(other.coeff)
@@ -174,11 +177,25 @@ class Poly:
174
177
  modulus = other.modulus
175
178
  return self.__class__(coeff, modulus = modulus)
176
179
 
177
- def __rmul__(self, other: int) -> "Poly":
178
- if isinstance(other, int) or type(other) == type(self.coeff[0]):
180
+ def __rmul__(self, other) -> "Poly":
181
+ if self._check_type(other):
179
182
  return self.__class__([other * s for s in self.coeff], modulus=self.modulus)
180
183
  return NotImplemented
181
184
 
185
+ def __truediv__(self, other) -> "Poly":
186
+ if self._check_type(other):
187
+ return self.__class__([s / other for s in self.coeff], modulus=self.modulus)
188
+ if isinstance(other, self.__class__):
189
+ if not other.modulus:
190
+ raise NotImplementedError("Cannot invert polynomials without modulus.")
191
+ return self * other.inv()
192
+ return NotImplemented
193
+
194
+ def __rtruediv__(self, other) -> "Poly":
195
+ if not self.modulus:
196
+ raise NotImplementedError("Cannot invert polynomials without modulus.")
197
+ return other * self.inv()
198
+
182
199
  def __pow__(self, i: int) -> "Poly":
183
200
  if not isinstance(i, int):
184
201
  return NotImplemented
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.1
2
2
  Name: kryptools
3
- Version: 0.5
3
+ Version: 0.6
4
4
  Summary: Implemenation of same basic algorithms used in cryptography.
5
5
  Author-email: Gerald Teschl <gerald.teschl@univie.ac.at>
6
6
  Project-URL: Homepage, https://github.com/teschlg/kryptools
@@ -1,6 +1,6 @@
1
1
  [project]
2
2
  name = "kryptools"
3
- version = "0.5"
3
+ version = "0.6"
4
4
  authors = [
5
5
  { name="Gerald Teschl", email="gerald.teschl@univie.ac.at" },
6
6
  ]
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes