kryptools 0.9.8__tar.gz → 0.9.9__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 (38) hide show
  1. {kryptools-0.9.8 → kryptools-0.9.9}/PKG-INFO +1 -1
  2. {kryptools-0.9.8 → kryptools-0.9.9}/kryptools/Zmod.py +6 -2
  3. {kryptools-0.9.8 → kryptools-0.9.9}/kryptools/__init__.py +1 -1
  4. {kryptools-0.9.8 → kryptools-0.9.9}/kryptools/ec.py +5 -1
  5. {kryptools-0.9.8 → kryptools-0.9.9}/kryptools/factor.py +1 -1
  6. {kryptools-0.9.8 → kryptools-0.9.9}/kryptools/factor_ecm.py +0 -1
  7. {kryptools-0.9.8 → kryptools-0.9.9}/kryptools/factor_fmt.py +1 -1
  8. {kryptools-0.9.8 → kryptools-0.9.9}/kryptools/factor_pm1.py +1 -1
  9. {kryptools-0.9.8 → kryptools-0.9.9}/kryptools/factor_rho.py +0 -1
  10. {kryptools-0.9.8 → kryptools-0.9.9}/kryptools/la.py +2 -2
  11. {kryptools-0.9.8 → kryptools-0.9.9}/kryptools/nt.py +3 -1
  12. {kryptools-0.9.8 → kryptools-0.9.9}/kryptools/primes.py +3 -3
  13. {kryptools-0.9.8 → kryptools-0.9.9}/kryptools.egg-info/PKG-INFO +1 -1
  14. {kryptools-0.9.8 → kryptools-0.9.9}/kryptools.egg-info/SOURCES.txt +10 -1
  15. {kryptools-0.9.8 → kryptools-0.9.9}/pyproject.toml +1 -1
  16. kryptools-0.9.9/tests/test_Zmod.py +51 -0
  17. kryptools-0.9.9/tests/test_dlog.py +18 -0
  18. kryptools-0.9.9/tests/test_ec.py +25 -0
  19. kryptools-0.9.9/tests/test_factor.py +18 -0
  20. kryptools-0.9.9/tests/test_la.py +15 -0
  21. kryptools-0.9.9/tests/test_lat.py +9 -0
  22. kryptools-0.9.9/tests/test_nt.py +38 -0
  23. kryptools-0.9.9/tests/test_poly.py +15 -0
  24. kryptools-0.9.9/tests/test_primes.py +27 -0
  25. {kryptools-0.9.8 → kryptools-0.9.9}/LICENSE +0 -0
  26. {kryptools-0.9.8 → kryptools-0.9.9}/README.md +0 -0
  27. {kryptools-0.9.8 → kryptools-0.9.9}/kryptools/dlp.py +0 -0
  28. {kryptools-0.9.8 → kryptools-0.9.9}/kryptools/dlp_bsgs.py +0 -0
  29. {kryptools-0.9.8 → kryptools-0.9.9}/kryptools/dlp_ic.py +0 -0
  30. {kryptools-0.9.8 → kryptools-0.9.9}/kryptools/dlp_qs.py +0 -0
  31. {kryptools-0.9.8 → kryptools-0.9.9}/kryptools/dlp_rho.py +0 -0
  32. {kryptools-0.9.8 → kryptools-0.9.9}/kryptools/factor_dix.py +0 -0
  33. {kryptools-0.9.8 → kryptools-0.9.9}/kryptools/factor_qs.py +0 -0
  34. {kryptools-0.9.8 → kryptools-0.9.9}/kryptools/lat.py +0 -0
  35. {kryptools-0.9.8 → kryptools-0.9.9}/kryptools/poly.py +0 -0
  36. {kryptools-0.9.8 → kryptools-0.9.9}/kryptools.egg-info/dependency_links.txt +0 -0
  37. {kryptools-0.9.8 → kryptools-0.9.9}/kryptools.egg-info/top_level.txt +0 -0
  38. {kryptools-0.9.8 → kryptools-0.9.9}/setup.cfg +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.1
2
2
  Name: kryptools
3
- Version: 0.9.8
3
+ Version: 0.9.9
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
@@ -30,7 +30,11 @@ class Zmod:
30
30
  self.group_order = 0
31
31
  self.factors = {} # factoring of the group order
32
32
 
33
- def __call__(self, x: int):
33
+ def __call__(self, x: int|list|tuple):
34
+ if isinstance(x, list):
35
+ return [ZmodPoint(xx, self) for xx in x]
36
+ elif isinstance(x, tuple):
37
+ return (ZmodPoint(xx, self) for xx in x)
34
38
  return ZmodPoint(x, self)
35
39
 
36
40
  def __eq__(self, other):
@@ -76,7 +80,7 @@ class Zmod:
76
80
 
77
81
  def star(self) -> int:
78
82
  """Return a list of all elements of the group Z_n^*."""
79
- elements = [ 1 ]
83
+ elements = [ self(1) ]
80
84
  for a in range(2, self.n):
81
85
  if gcd(a, self.n) > 1:
82
86
  continue
@@ -5,7 +5,7 @@ Implemenation of same basic algorithms used in cryptography.
5
5
  __author__ = "Gerald Teschl"
6
6
  __copyright__ = "Copyright 2024, Gerald Teschl"
7
7
  __license__ = "MIT License"
8
- __version__ = "0.9.8"
8
+ __version__ = "0.9.9"
9
9
  __email__ = "Gerald.Teschl@univie.ac.at"
10
10
 
11
11
  from .nt import egcd, cf, convergents, legendre_symbol, jacobi_symbol, sqrt_mod, euler_phi, carmichael_lambda, moebius_mu, order, crt
@@ -71,6 +71,10 @@ class EC_Weierstrass():
71
71
  return False
72
72
 
73
73
  def __contains__(self, P: "ECPoint") -> bool:
74
+ if not isinstance(P, ECPoint) or P.curve != self:
75
+ return False
76
+ if P.x is None and P.y is None:
77
+ return True
74
78
  return P.y**2 == P.x**3 + self.a * P.x + self.b
75
79
 
76
80
  def info(self):
@@ -268,7 +272,7 @@ class ECPoint:
268
272
  else:
269
273
  y = (curve.p - y1) % curve.p
270
274
  self.y = curve.gf(y)
271
- if not self in curve:
275
+ if self not in curve:
272
276
  raise ValueError("Point not on curve!")
273
277
 
274
278
  def __repr__(self):
@@ -116,7 +116,7 @@ def factorint(n: int, verbose: int = 0, trial_bnd: int = 2500) -> dict:
116
116
  B2 += B2 & 1
117
117
  num_curves *= 2
118
118
  D = isqrt(B2)
119
-
119
+
120
120
  if verbose:
121
121
  print(f"Round {round+1} (B1={B1})")
122
122
 
@@ -177,4 +177,3 @@ def factor_ecm(n: int, B1: int|None = None, B2: int|None = None, curves: int = 1
177
177
 
178
178
  if verbose > 1:
179
179
  print(f"\nNo factor after trying {curves} curves.")
180
-
@@ -2,7 +2,7 @@
2
2
  Integer factorization: Fermat's method
3
3
  """
4
4
 
5
- from math import isqrt, log10, floor, log10
5
+ from math import isqrt, floor, log10
6
6
 
7
7
 
8
8
  def factor_fermat(n: int, maxsteps: int|None = None, verbose: int = 0) -> list:
@@ -59,7 +59,7 @@ def factor_pm1(n: int, B1: int|None = None, B2: int|None = None, x: int = 2, pm1
59
59
  y = pow(x, stage_two_deltas[0], n)
60
60
  D = (y - 1) % n
61
61
  for k, d in enumerate(stage_two_deltas[1:]):
62
- if not d in saved:
62
+ if d not in saved:
63
63
  saved[d] = pow(x, d, n)
64
64
  y = y * saved[d] % n
65
65
  D = D * (y - 1) % n
@@ -55,4 +55,3 @@ def factor_rho(n: int, x: int = 2, maxinit: int = 10, maxiter: int = 1000, brent
55
55
  x = randint(1, n - 1) # new x_0
56
56
  if verbose > 1:
57
57
  print("")
58
-
@@ -187,12 +187,12 @@ class Matrix:
187
187
  def __mul__(self, other) -> "Matrix":
188
188
  if isinstance(other, Matrix):
189
189
  return self.multiply(other)
190
- if isinstance(other, Number) or type(other) == type(self.matrix[0][0]):
190
+ if isinstance(other, Number) or type(other) is type(self.matrix[0][0]):
191
191
  return self.__class__([ [item * other for item in row] for row in self.matrix ])
192
192
  return NotImplemented
193
193
 
194
194
  def __rmul__(self, other) -> "Matrix":
195
- if isinstance(other, Number) or type(other) == type(self.matrix[0][0]):
195
+ if isinstance(other, Number) or type(other) is type(self.matrix[0][0]):
196
196
  return self.__class__([ [item * other for item in row] for row in self.matrix ])
197
197
  return NotImplemented
198
198
 
@@ -143,6 +143,8 @@ def carmichael_lambda(n: int) -> int:
143
143
  """Carmichael's lambda function of `n`."""
144
144
  if not isinstance(n, int) or n < 1:
145
145
  raise ValueError(f"{n} is not a positive integer")
146
+ if n == 1:
147
+ return 1
146
148
  k = factorint(n)
147
149
  lam_all = [] # values corresponding to the prime factors
148
150
  for p in k:
@@ -224,7 +226,7 @@ def crt(a: list[int], m: list[int], coprime = True) -> int:
224
226
  if g == 1: # moduli are coprime, nothing to be done
225
227
  continue
226
228
  if (a[i] - a[j]) % g:
227
- raise ValueError(f"Congruences not solvable!")
229
+ raise ValueError("Congruences not solvable!")
228
230
  for p, k in factorint(g).items():
229
231
  p = p**k # remove this factor from one of the equations
230
232
  if gcd(m[i] // p, p) == 1:
@@ -72,7 +72,7 @@ def miller_rabin_test(n: int, bases: list[int] | int) -> bool:
72
72
  if a == 0:
73
73
  continue
74
74
  b = pow(a, m, n)
75
- if b == 1 or b == n - 1:
75
+ if b in (1, n - 1):
76
76
  continue
77
77
  for _ in range(1, k):
78
78
  b = pow(b, 2, n)
@@ -154,7 +154,7 @@ def lucas_test(n: int) -> bool:
154
154
  return n == 2
155
155
  if perfect_square(n) is not None: # the search for D will not succeed in this case
156
156
  return False
157
-
157
+
158
158
  # write n = k 2^s - 1
159
159
  k = (n + 1) // 2
160
160
  s = 1
@@ -163,7 +163,7 @@ def lucas_test(n: int) -> bool:
163
163
  s += 1
164
164
 
165
165
  # Selfridge method for choosing D
166
-
166
+
167
167
  D = 5
168
168
  while True:
169
169
  g = gcd(abs(D), n)
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.1
2
2
  Name: kryptools
3
- Version: 0.9.8
3
+ Version: 0.9.9
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
@@ -24,4 +24,13 @@ kryptools/primes.py
24
24
  kryptools.egg-info/PKG-INFO
25
25
  kryptools.egg-info/SOURCES.txt
26
26
  kryptools.egg-info/dependency_links.txt
27
- kryptools.egg-info/top_level.txt
27
+ kryptools.egg-info/top_level.txt
28
+ tests/test_Zmod.py
29
+ tests/test_dlog.py
30
+ tests/test_ec.py
31
+ tests/test_factor.py
32
+ tests/test_la.py
33
+ tests/test_lat.py
34
+ tests/test_nt.py
35
+ tests/test_poly.py
36
+ tests/test_primes.py
@@ -1,6 +1,6 @@
1
1
  [project]
2
2
  name = "kryptools"
3
- version = "0.9.8"
3
+ version = "0.9.9"
4
4
  authors = [
5
5
  { name="Gerald Teschl", email="gerald.teschl@univie.ac.at" },
6
6
  ]
@@ -0,0 +1,51 @@
1
+ import pytest
2
+ from math import gcd
3
+ from kryptools import Zmod
4
+
5
+ def test_Zmod():
6
+ for n in [5, 6]:
7
+ Z_n = Zmod(n)
8
+ for a in range(n):
9
+ aa = Z_n(a)
10
+ bool(aa) == bool(a)
11
+ for i in range(4):
12
+ assert aa ** i == Z_n(pow(a, i, n))
13
+ if i == 0 or gcd(a, n) == 1:
14
+ assert aa ** -i == Z_n(pow(a, -i, n))
15
+ else:
16
+ with pytest.raises(ValueError):
17
+ aa ** -i
18
+ if gcd(a, n) == 1:
19
+ assert aa ** aa.order() == Z_n(1)
20
+ else:
21
+ with pytest.raises(ValueError):
22
+ aa.order()
23
+ for b in range(n):
24
+ bb = Z_n(b)
25
+ assert aa + bb == Z_n(a + b)
26
+ assert aa - bb == Z_n(a - b)
27
+ assert aa * bb == Z_n(a * b)
28
+ if gcd(b, n) == 1:
29
+ assert aa / bb == Z_n( a * pow(b, -1, n) )
30
+
31
+ Z_5 = Zmod(5)
32
+ assert Z_5(3).order() == 4
33
+ assert Z_5(1).is_generator() == False
34
+ assert Z_5(3).is_generator() == True
35
+ assert Z_5.generator(all = True) == Z_5([2, 3])
36
+ assert Z_5.star() == Z_5([1, 2, 3, 4])
37
+ assert [Z_5(i).sharp() for i in range(Z_5.n)] == [0, 1, 2, -2, -1]
38
+ assert [abs(Z_5(i)) for i in range(Z_5.n)] == [0, 1, 2, 2, 1]
39
+ assert str(Z_5(3)) == "3"
40
+ Z_5.short = False
41
+ assert str(Z_5(6)) == "1 (mod 5)"
42
+
43
+ Z_6 = Zmod(6)
44
+ assert Z_6(5).order() == 2
45
+ with pytest.raises(ValueError):
46
+ Z_6(3).order()
47
+ assert Z_6(1).is_generator() == False
48
+ assert Z_6(5).is_generator() == True
49
+ assert Z_6.generator(all = True) == Z_6([5])
50
+ assert Z_6.star() == Z_6([1, 5])
51
+ assert str(Z_6(3)) == "3"
@@ -0,0 +1,18 @@
1
+ import pytest
2
+ from random import randint, seed
3
+ from kryptools import dlog
4
+
5
+ seed(0)
6
+
7
+ with pytest.raises(ValueError):
8
+ dlog(1, 3, 10)
9
+
10
+ def test_dlogt():
11
+ for data in (
12
+ [557639, 278819, 2],
13
+ [24570203447, 12285101723, 2],
14
+ [28031135240181527, 14015567620090763, 2] ):
15
+ p, m, a = data # m is the order of a in Z_p
16
+ x = randint(2, m - 1)
17
+ b = pow(a, x, p)
18
+ assert dlog(a, b, p) == x
@@ -0,0 +1,25 @@
1
+ import pytest
2
+ from random import randint, seed
3
+ from kryptools import EC_Weierstrass
4
+ seed(0)
5
+
6
+
7
+ def test_EC():
8
+ ec = EC_Weierstrass(239, 3, 1)
9
+ O = ec(None, None) # point at infinity
10
+ assert O in ec
11
+ P = ec.random()
12
+ assert P in ec
13
+ Q = ec.random()
14
+ assert Q in ec
15
+ assert P + O == P
16
+ assert O + P == P
17
+ R = O
18
+ for i in range(5):
19
+ assert i * P == R
20
+ R += P
21
+ assert P + Q == Q + P
22
+ assert Q.order() * Q == O
23
+ k = randint(1, ec.order())
24
+ R = k * Q
25
+ assert R.dlog(Q) == k
@@ -0,0 +1,18 @@
1
+ import pytest
2
+ from kryptools import factorint, is_prime
3
+
4
+ def myprod(factors: dict) -> int:
5
+ n = 1
6
+ for p in factors:
7
+ assert is_prime(p)
8
+ n *= p**factors[p]
9
+ return n
10
+
11
+
12
+ def test_factorint():
13
+ assert factorint(0) == {0: 1}
14
+ assert factorint(1) == {}
15
+ for n in ( 1489576198567193874913874619387459183543154617315437135656,
16
+ 2**128 - 1,
17
+ 4521089809**7 ):
18
+ assert n == myprod(factorint(n))
@@ -0,0 +1,15 @@
1
+ import pytest
2
+ from fractions import Fraction
3
+ from kryptools import Matrix, Zmod
4
+
5
+
6
+ def test_Matrix():
7
+ M = Matrix([[1, 2, 3], [4, 5, 6], [7, 8, 12]])
8
+ M.map(Fraction)
9
+ Mi = M.inv()
10
+ assert M * Mi == M.eye()
11
+
12
+ Z_11 = Zmod(11)
13
+ M = Matrix([[1, 2, 3], [4, 5, 6], [7, 8, 12]], ring=Z_11)
14
+ Mi = M.inv()
15
+ assert M * Mi == M.eye()
@@ -0,0 +1,9 @@
1
+ import pytest
2
+ from fractions import Fraction
3
+ from kryptools import Matrix, gram_schmidt
4
+
5
+
6
+ def test_gram_schmidt():
7
+ V = Matrix([[5, 8], [0, 1]], ring=Fraction)
8
+ Vs, M = gram_schmidt(V)
9
+ assert V == Vs * M
@@ -0,0 +1,38 @@
1
+ import pytest
2
+ from kryptools import carmichael_lambda, euler_phi, moebius_mu
3
+
4
+ #https://oeis.org/A000010
5
+ OEIS_A000010 = [
6
+ 1, 1, 2, 2, 4, 2, 6, 4, 6, 4, 10, 4, 12, 6, 8, 8, 16, 6, 18, 8, 12, 10, 22, 8, 20,
7
+ 12, 18, 12, 28, 8, 30, 16, 20, 16, 24, 12, 36, 18, 24, 16, 40, 12, 42, 20, 24, 22,
8
+ 46, 16, 42, 20, 32, 24, 52, 18, 40, 24, 36, 28, 58, 16, 60, 30, 36, 32, 48, 20,
9
+ 66, 32, 44 ]
10
+
11
+ def test_euler_phi():
12
+ for n in range(1, len(OEIS_A000010)+1):
13
+ assert euler_phi(n) == OEIS_A000010[n - 1]
14
+
15
+ #https://oeis.org/A002322
16
+ OEIS_A002322 = [
17
+ 1, 1, 2, 2, 4, 2, 6, 2, 6, 4, 10, 2, 12, 6, 4, 4, 16, 6, 18, 4, 6, 10, 22, 2, 20,
18
+ 12, 18, 6, 28, 4, 30, 8, 10, 16, 12, 6, 36, 18, 12, 4, 40, 6, 42, 10, 12, 22, 46,
19
+ 4, 42, 20, 16, 12, 52, 18, 20, 6, 18, 28, 58, 4, 60, 30, 6, 16, 12, 10, 66, 16,
20
+ 22, 12, 70, 6, 72, 36, 20, 18, 30, 12, 78, 4, 54 ]
21
+
22
+ def test_carmichael_lambda():
23
+ for n in range(1, len(OEIS_A002322)+1):
24
+ assert carmichael_lambda(n) == OEIS_A002322[n - 1]
25
+
26
+ #https://oeis.org/A008683
27
+ OEIS_A008683 = [
28
+ 1, -1, -1, 0, -1, 1, -1, 0, 0, 1, -1, 0, -1, 1, 1, 0, -1, 0, -1, 0, 1, 1, -1, 0,
29
+ 0, 1, 0, 0, -1, -1, -1, 0, 1, 1, 1, 0, -1, 1, 1, 0, -1, -1, -1, 0, 0, 1, -1, 0, 0,
30
+ 0, 1, 0, -1, 0, 1, 0, 1, 1, -1, 0, -1, 1, 0, 0, 1, -1, -1, 0, 1, -1, -1, 0, -1, 1,
31
+ 0, 0, 1, -1 ]
32
+
33
+ def test_moebius_mu():
34
+ for n in range(1, len(OEIS_A008683)+1):
35
+ assert moebius_mu(n) == OEIS_A008683[n - 1]
36
+
37
+
38
+
@@ -0,0 +1,15 @@
1
+ import pytest
2
+ from kryptools import Poly, Zmod
3
+
4
+
5
+ def test_Poly():
6
+ p = Poly([2, 0, 2])
7
+ q = Poly([1, 2, 3, 4])
8
+ d, m = q.divmod(p)
9
+ assert d * p + m == q
10
+
11
+ Z_5 = Zmod(5)
12
+ p.map(Z_5)
13
+ q.map(Z_5)
14
+ d, m = q.divmod(p)
15
+ assert d * p + m == q
@@ -0,0 +1,27 @@
1
+ import pytest
2
+ from kryptools import sieve_eratosthenes, prime_pi, next_prime, previous_prime
3
+
4
+
5
+ #https://oeis.org/A000040
6
+ OEIS_A000010 = [ 2, 3, 5, 7, 11, 13, 17, 19, 23, 29, 31, 37, 41, 43, 47, 53, 59, 61, 67,
7
+ 71, 73, 79, 83, 89, 97, 101, 103, 107, 109, 113, 127, 131, 137, 139, 149, 151, 157, 163,
8
+ 167, 173, 179, 181, 191, 193, 197, 199, 211, 223, 227, 229, 233, 239, 241, 251, 257, 263,
9
+ 269, 271 ]
10
+
11
+ def test_sieve_eratosthenes():
12
+ for i, p in enumerate(sieve_eratosthenes(OEIS_A000010[-1])):
13
+ assert p == OEIS_A000010[i]
14
+ if i > 0:
15
+ assert previous_prime(p-1) == OEIS_A000010[i-1]
16
+ if i < len(OEIS_A000010) - 1:
17
+ assert next_prime(p+1) == OEIS_A000010[i+1]
18
+
19
+ #https://oeis.org/A000040
20
+ OEIS_A000720 = [ 0, 1, 2, 2, 3, 3, 4, 4, 4, 4, 5, 5, 6, 6, 6, 6, 7, 7, 8, 8, 8, 8, 9, 9,
21
+ 9, 9, 9, 9, 10, 10, 11, 11, 11, 11, 11, 11, 12, 12, 12, 12, 13, 13, 14, 14, 14, 14,
22
+ 15, 15, 15, 15, 15, 15, 16, 16, 16, 16, 16, 16, 17, 17, 18, 18, 18, 18, 18, 18, 19,
23
+ 19, 19, 19, 20, 20, 21, 21, 21, 21, 21, 21 ]
24
+
25
+ def test_prime_pi():
26
+ for n in range(1, len(OEIS_A000720)+1):
27
+ assert prime_pi(n) == OEIS_A000720[n - 1]
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes