kryptools 0.9.15__tar.gz → 1.0__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 (51) hide show
  1. {kryptools-0.9.15 → kryptools-1.0}/PKG-INFO +2 -2
  2. {kryptools-0.9.15 → kryptools-1.0}/kryptools/factor_pm1.py +17 -16
  3. {kryptools-0.9.15 → kryptools-1.0}/kryptools/factor_qs.py +7 -7
  4. {kryptools-0.9.15 → kryptools-1.0}/kryptools/factor_rho.py +3 -3
  5. {kryptools-0.9.15 → kryptools-1.0}/kryptools/nt.py +13 -2
  6. {kryptools-0.9.15 → kryptools-1.0}/kryptools.egg-info/PKG-INFO +2 -2
  7. {kryptools-0.9.15 → kryptools-1.0}/kryptools.egg-info/SOURCES.txt +1 -0
  8. {kryptools-0.9.15 → kryptools-1.0}/pyproject.toml +1 -1
  9. kryptools-1.0/tests/test_factor_pm1.py +8 -0
  10. {kryptools-0.9.15 → kryptools-1.0}/tests/test_factor_qs.py +0 -1
  11. {kryptools-0.9.15 → kryptools-1.0}/tests/test_nt.py +4 -3
  12. {kryptools-0.9.15 → kryptools-1.0}/LICENSE +0 -0
  13. {kryptools-0.9.15 → kryptools-1.0}/README.md +0 -0
  14. {kryptools-0.9.15 → kryptools-1.0}/kryptools/GF2.py +0 -0
  15. {kryptools-0.9.15 → kryptools-1.0}/kryptools/Zmod.py +0 -0
  16. {kryptools-0.9.15 → kryptools-1.0}/kryptools/__init__.py +0 -0
  17. {kryptools-0.9.15 → kryptools-1.0}/kryptools/aes.py +0 -0
  18. {kryptools-0.9.15 → kryptools-1.0}/kryptools/blockcipher.py +0 -0
  19. {kryptools-0.9.15 → kryptools-1.0}/kryptools/conway_polynomials.py +0 -0
  20. {kryptools-0.9.15 → kryptools-1.0}/kryptools/des.py +0 -0
  21. {kryptools-0.9.15 → kryptools-1.0}/kryptools/dlp.py +0 -0
  22. {kryptools-0.9.15 → kryptools-1.0}/kryptools/dlp_bsgs.py +0 -0
  23. {kryptools-0.9.15 → kryptools-1.0}/kryptools/dlp_ic.py +0 -0
  24. {kryptools-0.9.15 → kryptools-1.0}/kryptools/dlp_qs.py +0 -0
  25. {kryptools-0.9.15 → kryptools-1.0}/kryptools/dlp_rho.py +0 -0
  26. {kryptools-0.9.15 → kryptools-1.0}/kryptools/ec.py +0 -0
  27. {kryptools-0.9.15 → kryptools-1.0}/kryptools/factor.py +0 -0
  28. {kryptools-0.9.15 → kryptools-1.0}/kryptools/factor_dix.py +0 -0
  29. {kryptools-0.9.15 → kryptools-1.0}/kryptools/factor_ecm.py +0 -0
  30. {kryptools-0.9.15 → kryptools-1.0}/kryptools/factor_fmt.py +0 -0
  31. {kryptools-0.9.15 → kryptools-1.0}/kryptools/intfuncs.py +0 -0
  32. {kryptools-0.9.15 → kryptools-1.0}/kryptools/la.py +0 -0
  33. {kryptools-0.9.15 → kryptools-1.0}/kryptools/lat.py +0 -0
  34. {kryptools-0.9.15 → kryptools-1.0}/kryptools/poly.py +0 -0
  35. {kryptools-0.9.15 → kryptools-1.0}/kryptools/primes.py +0 -0
  36. {kryptools-0.9.15 → kryptools-1.0}/kryptools.egg-info/dependency_links.txt +0 -0
  37. {kryptools-0.9.15 → kryptools-1.0}/kryptools.egg-info/top_level.txt +0 -0
  38. {kryptools-0.9.15 → kryptools-1.0}/setup.cfg +0 -0
  39. {kryptools-0.9.15 → kryptools-1.0}/tests/test_GF2.py +0 -0
  40. {kryptools-0.9.15 → kryptools-1.0}/tests/test_Zmod.py +0 -0
  41. {kryptools-0.9.15 → kryptools-1.0}/tests/test_aes.py +0 -0
  42. {kryptools-0.9.15 → kryptools-1.0}/tests/test_des.py +0 -0
  43. {kryptools-0.9.15 → kryptools-1.0}/tests/test_dlog.py +0 -0
  44. {kryptools-0.9.15 → kryptools-1.0}/tests/test_ec.py +0 -0
  45. {kryptools-0.9.15 → kryptools-1.0}/tests/test_factor.py +0 -0
  46. {kryptools-0.9.15 → kryptools-1.0}/tests/test_factor_fmt.py +0 -0
  47. {kryptools-0.9.15 → kryptools-1.0}/tests/test_intfuncs.py +0 -0
  48. {kryptools-0.9.15 → kryptools-1.0}/tests/test_la.py +0 -0
  49. {kryptools-0.9.15 → kryptools-1.0}/tests/test_lat.py +0 -0
  50. {kryptools-0.9.15 → kryptools-1.0}/tests/test_poly.py +0 -0
  51. {kryptools-0.9.15 → kryptools-1.0}/tests/test_primes.py +0 -0
@@ -1,6 +1,6 @@
1
- Metadata-Version: 2.1
1
+ Metadata-Version: 2.2
2
2
  Name: kryptools
3
- Version: 0.9.15
3
+ Version: 1.0
4
4
  Summary: Implemenation of same basic algorithms used in cryptography.
5
5
  Author-email: Gerald Teschl <gerald.teschl@univie.ac.at>
6
6
  License: MIT
@@ -6,10 +6,8 @@ from math import gcd, log, isqrt, floor, log10
6
6
  from .primes import sieve_eratosthenes
7
7
 
8
8
 
9
- def _pm1_parameters(B1: int, B2: int | None = None, primes: tuple = None) -> tuple:
9
+ def _pm1_parameters(B1: int, B2: int, primes: tuple = None) -> tuple:
10
10
  "Precompute parameters for the p-1 method."
11
- if not B2:
12
- B2 = 100 * B1
13
11
  if not primes:
14
12
  primes = sieve_eratosthenes(B2)
15
13
 
@@ -34,28 +32,31 @@ def factor_pm1(n: int, B1: int | None = None, B2: int | None = None, x: int = 2,
34
32
  B1, B2, stage_one, stage_two_deltas = pm1_parameters
35
33
  else:
36
34
  if not B1:
37
- B1 = min(1000_000, isqrt(n)//50 + 2)
35
+ B1 = min(1000_000, isqrt(isqrt(n)) + 2)
36
+ if not B2 or B2 < B1:
37
+ B2 = 100 * B1
38
38
  stage_one, stage_two_deltas = _pm1_parameters(B1, B2)
39
39
 
40
40
  if verbose:
41
- print(f"Factoring (Pollard p-1, B1={B1}, B2={B2}): {n} ({floor(log10(n)) + 1} digits)")
41
+ print(f"Factoring (Pollard p-1, B1={B1}, B2={B2}): {n} ({floor(log10(n)) + 1} digits)", end ="")
42
42
 
43
43
  # stage one
44
44
  if verbose > 1:
45
- print("Working 1", end="")
45
+ print("\nWorking 1", end="")
46
46
  x = pow(x, stage_one, n)
47
47
  g = gcd(x - 1, n)
48
- if g == n:
49
- if verbose > 1:
50
- print("")
48
+ if g == n: # we hit a multiple of n
49
+ if verbose:
50
+ print("\nFailed after stage one.")
51
51
  return None
52
52
  if 1 < g:
53
53
  if verbose > 1:
54
- print("\nFactor found.")
54
+ print("\nFactor found in stage one.")
55
55
  return g
56
56
 
57
+ # stage two
57
58
  if verbose > 1:
58
- print("2", end="")
59
+ print(",2", end="")
59
60
  saved = {}
60
61
  y = pow(x, stage_two_deltas[0], n)
61
62
  D = (y - 1) % n
@@ -68,17 +69,17 @@ def factor_pm1(n: int, B1: int | None = None, B2: int | None = None, x: int = 2,
68
69
  g = gcd(D, n)
69
70
  if g == n:
70
71
  if verbose > 1:
71
- print("")
72
+ print("\nFailed during stage two.")
72
73
  return None
73
74
  if 1 < g:
74
75
  if verbose > 1:
75
- print("\nFactor found.")
76
+ print("\nFactor found in stage two.")
76
77
  return g
77
78
  g = gcd(D, n)
78
79
  if 1 < g < n:
79
80
  if verbose > 1:
80
- print("\nFactor found.")
81
+ print("\nFactor found in stage two.")
81
82
  return g
82
- if verbose > 1:
83
- print("")
83
+ if verbose:
84
+ print("\nFailed after stage two.")
84
85
  return None
@@ -29,7 +29,7 @@ def factor_qs(n: int, verbose: int = 0) -> int | None:
29
29
  """Find factors of n using the quadratic sieve."""
30
30
  # first determine the bound B for the factorbase: Choosing B=p^(1/u) Canfield-Erdös-Pomerance gives us
31
31
  # the expected running time |B|^2 u^u = u^(u+2) p^(2/u)/log(n). There is no explicit expression for the optimum, hence
32
- # we use Newton
32
+ # we use Newton's method
33
33
  u = 2 * sqrt(log(n) / log(log(n))) # asymptotic value
34
34
  for _ in range(3):
35
35
  u = (2 * log(n) + u * u * (2 + log(u))) / (
@@ -47,11 +47,9 @@ def factor_qs(n: int, verbose: int = 0) -> int | None:
47
47
  ls = legendre_symbol(n, p)
48
48
  if ls == 0: # we already found a factor;-)
49
49
  if verbose > 1:
50
- print("\nFound a small prime factor.")
51
- if n == p:
52
- return n
50
+ print("\nFactor base contains a factor.")
53
51
  return p
54
- if ls == 1: # we only take primes such that n is quadratic residue
52
+ if ls == 1: # we only take primes such that n is a quadratic residue
55
53
  factorbase.append(p)
56
54
  lf = len(factorbase) # length of the factorbase (including -1)
57
55
  lfb = ceil((lf+1) / 8) # the number of bytes we need to store a relation
@@ -67,11 +65,13 @@ def factor_qs(n: int, verbose: int = 0) -> int | None:
67
65
  if r1 == r2:
68
66
  factorbase_root[i] = [r1]
69
67
  else:
70
- factorbase_root[i] = [r1, -r1 % p] # pylint: disable=E1130
68
+ factorbase_root[i] = [r1, r2]
71
69
 
72
70
  m = isqrt(n - 1) + 1
73
71
  d = m**2 - n
74
- if d == 0: # Our number is a square
72
+ if d == 0: # our number is a square
73
+ if verbose > 1:
74
+ print("\nThe number is a complete square.")
75
75
  return m
76
76
  m2 = 2 * m
77
77
 
@@ -15,10 +15,10 @@ def factor_rho(n: int, x: int = 2, maxinit: int = 10, maxiter: int = 1000, brent
15
15
  return (pow(x, 2, n) + 2) % n
16
16
 
17
17
  if verbose:
18
- print(f"Factoring (Pollard rho, maxinit={maxinit}, maxiter={maxiter}): {n} ({floor(log10(n)) + 1} digits)")
18
+ print(f"Factoring (Pollard rho, maxinit={maxinit}, maxiter={maxiter}): {n} ({floor(log10(n)) + 1} digits)", end="")
19
19
 
20
20
  if verbose > 1:
21
- print("Working ", end="")
21
+ print("\nWorking ", end="")
22
22
  for _ in range(maxinit):
23
23
  if verbose > 1:
24
24
  print("X", end="")
@@ -54,4 +54,4 @@ def factor_rho(n: int, x: int = 2, maxinit: int = 10, maxiter: int = 1000, brent
54
54
  return tmp
55
55
  x = randint(1, n - 1) # new x_0
56
56
  if verbose > 1:
57
- print("")
57
+ print("\nFailed.")
@@ -21,8 +21,19 @@ from fractions import Fraction
21
21
 
22
22
  def egcd(a: int, b: int) -> (int, int, int):
23
23
  """Perform the extended Euclidean agorithm. Returns `gcd`, `x`, `y` such that `a x + b y = gcd`."""
24
- r0, r1 = a, b
25
- x0, x1, y0, y1 = 1, 0, 0, 1
24
+ if a == 0:
25
+ if b < 0:
26
+ return -b, 0, -1
27
+ return b, 0, 1
28
+ if a < 0:
29
+ r0, r1 = -a, b
30
+ x0, x1, y0, y1 = -1, 0, 0, 1
31
+ else:
32
+ r0, r1 = a, b
33
+ x0, x1, y0, y1 = 1, 0, 0, 1
34
+ if b < 0:
35
+ r1 *= -1
36
+ y1 = -1
26
37
  while r1 != 0:
27
38
  q, r = divmod(r0, r1)
28
39
  r0, r1 = r1, r
@@ -1,6 +1,6 @@
1
- Metadata-Version: 2.1
1
+ Metadata-Version: 2.2
2
2
  Name: kryptools
3
- Version: 0.9.15
3
+ Version: 1.0
4
4
  Summary: Implemenation of same basic algorithms used in cryptography.
5
5
  Author-email: Gerald Teschl <gerald.teschl@univie.ac.at>
6
6
  License: MIT
@@ -39,6 +39,7 @@ tests/test_dlog.py
39
39
  tests/test_ec.py
40
40
  tests/test_factor.py
41
41
  tests/test_factor_fmt.py
42
+ tests/test_factor_pm1.py
42
43
  tests/test_factor_qs.py
43
44
  tests/test_intfuncs.py
44
45
  tests/test_la.py
@@ -1,6 +1,6 @@
1
1
  [project]
2
2
  name = "kryptools"
3
- version = "0.9.15"
3
+ version = "1.0"
4
4
  authors = [
5
5
  { name="Gerald Teschl", email="gerald.teschl@univie.ac.at" },
6
6
  ]
@@ -0,0 +1,8 @@
1
+ import pytest
2
+ from kryptools.factor_pm1 import factor_pm1
3
+
4
+
5
+ def test_pm1():
6
+ for n in [5421331, 10361963, 406525876951, 558847218052163]:
7
+ m = factor_pm1(n)
8
+ assert n % m == 0 and 1 < m < n
@@ -1,5 +1,4 @@
1
1
  import pytest
2
- from kryptools import is_prime
3
2
  from kryptools.factor_qs import factor_qs
4
3
 
5
4
 
@@ -1,6 +1,6 @@
1
1
  import pytest
2
2
  from random import randint, seed
3
- from math import prod, lcm
3
+ from math import gcd, prod, lcm
4
4
  from fractions import Fraction
5
5
  from kryptools import sieve_eratosthenes, is_prime
6
6
  from kryptools import egcd, crt, cf, convergents, legendre_symbol, jacobi_symbol, sqrt_mod, carmichael_lambda, euler_phi, moebius_mu, is_carmichael_number
@@ -9,9 +9,10 @@ seed(0)
9
9
 
10
10
  def test_egcd():
11
11
  maxsize = 100
12
- for a in range(maxsize):
13
- for b in range(maxsize):
12
+ for a in range(-maxsize, maxsize):
13
+ for b in range(-maxsize, maxsize):
14
14
  g, x, y = egcd(a, b)
15
+ assert g == gcd(a, b)
15
16
  assert x * a + y * b == g
16
17
 
17
18
 
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
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