kryptools 0.9.2__tar.gz → 0.9.4__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.9.2 → kryptools-0.9.4}/PKG-INFO +1 -1
  2. {kryptools-0.9.2 → kryptools-0.9.4}/kryptools/Zmod.py +20 -0
  3. {kryptools-0.9.2 → kryptools-0.9.4}/kryptools/__init__.py +1 -1
  4. {kryptools-0.9.2 → kryptools-0.9.4}/kryptools/primes.py +93 -61
  5. {kryptools-0.9.2 → kryptools-0.9.4}/kryptools.egg-info/PKG-INFO +1 -1
  6. {kryptools-0.9.2 → kryptools-0.9.4}/pyproject.toml +1 -1
  7. {kryptools-0.9.2 → kryptools-0.9.4}/LICENSE +0 -0
  8. {kryptools-0.9.2 → kryptools-0.9.4}/README.md +0 -0
  9. {kryptools-0.9.2 → kryptools-0.9.4}/kryptools/dlp.py +0 -0
  10. {kryptools-0.9.2 → kryptools-0.9.4}/kryptools/dlp_bsgs.py +0 -0
  11. {kryptools-0.9.2 → kryptools-0.9.4}/kryptools/dlp_ic.py +0 -0
  12. {kryptools-0.9.2 → kryptools-0.9.4}/kryptools/dlp_qs.py +0 -0
  13. {kryptools-0.9.2 → kryptools-0.9.4}/kryptools/dlp_rho.py +0 -0
  14. {kryptools-0.9.2 → kryptools-0.9.4}/kryptools/ec.py +0 -0
  15. {kryptools-0.9.2 → kryptools-0.9.4}/kryptools/factor.py +0 -0
  16. {kryptools-0.9.2 → kryptools-0.9.4}/kryptools/factor_dix.py +0 -0
  17. {kryptools-0.9.2 → kryptools-0.9.4}/kryptools/factor_ecm.py +0 -0
  18. {kryptools-0.9.2 → kryptools-0.9.4}/kryptools/factor_fmt.py +0 -0
  19. {kryptools-0.9.2 → kryptools-0.9.4}/kryptools/factor_pm1.py +0 -0
  20. {kryptools-0.9.2 → kryptools-0.9.4}/kryptools/factor_qs.py +0 -0
  21. {kryptools-0.9.2 → kryptools-0.9.4}/kryptools/la.py +0 -0
  22. {kryptools-0.9.2 → kryptools-0.9.4}/kryptools/lat.py +0 -0
  23. {kryptools-0.9.2 → kryptools-0.9.4}/kryptools/nt.py +0 -0
  24. {kryptools-0.9.2 → kryptools-0.9.4}/kryptools/poly.py +0 -0
  25. {kryptools-0.9.2 → kryptools-0.9.4}/kryptools.egg-info/SOURCES.txt +0 -0
  26. {kryptools-0.9.2 → kryptools-0.9.4}/kryptools.egg-info/dependency_links.txt +0 -0
  27. {kryptools-0.9.2 → kryptools-0.9.4}/kryptools.egg-info/top_level.txt +0 -0
  28. {kryptools-0.9.2 → kryptools-0.9.4}/setup.cfg +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.1
2
2
  Name: kryptools
3
- Version: 0.9.2
3
+ Version: 0.9.4
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
@@ -62,6 +62,26 @@ class Zmod:
62
62
  self.group_order *= p**k
63
63
  return self.group_order
64
64
 
65
+ def generator(self, all = False) -> int:
66
+ """Return a generator of the group Z_n^*."""
67
+ for a in range(2, self.n):
68
+ if gcd(a, self.n) > 1:
69
+ continue
70
+ a = self(a)
71
+ if a.is_generator():
72
+ if all:
73
+ self.order()
74
+ return list( a**j for j in range(1, self.group_order) if gcd(j,self.group_order) == 1 )
75
+ return a
76
+
77
+ def star(self) -> int:
78
+ """Return a list of all elements of the group Z_n^*."""
79
+ elements = [ 1 ]
80
+ for a in range(2, self.n):
81
+ if gcd(a, self.n) > 1:
82
+ continue
83
+ elements.append(self(a))
84
+ return elements
65
85
 
66
86
  class ZmodPoint:
67
87
  "Represents a point in the ring Zmod."
@@ -3,7 +3,7 @@ Implemenation of same basic algorithms used in cryptography.
3
3
  """
4
4
 
5
5
  from .nt import egcd, cf, convergents, legendre_symbol, jacobi_symbol, sqrt_mod, euler_phi, carmichael_lambda, moebius_mu, order, crt
6
- from .primes import sieve_eratosthenes, is_prime, next_prime, previous_prime, random_prime, random_strongprime, is_safeprime, random_safeprime
6
+ from .primes import sieve_eratosthenes, prime_pi, is_prime, next_prime, previous_prime, random_prime, random_strongprime, is_safeprime, random_safeprime, is_blumprime, random_blumprime, miller_rabin_test, lucas_test
7
7
  from .factor import factorint, divisors
8
8
  from .dlp import dlog
9
9
  from .ec import EC_Weierstrass
@@ -1,16 +1,20 @@
1
1
  """
2
2
  Tools for prime numbers:
3
3
  sieve_eratosthenes(B) a tuple of all primes up to including B
4
+ prime_pi(n) number of primes below or equal n
4
5
  is_prime(n) test if n is probably prime
5
6
  next_prime(n) find the next prime larger or equal n
6
7
  previous_prime(n) find the previous prime smaller or equal n
7
8
  random_prime(l) find a pseudorandom prime with bit length at least l
8
9
  random_strongprime(l) find a pseudorandom strong prime with bit length at least l
9
10
  is_safeprime(n) test if n is a safe prime
10
- random_safeprime(n) find a pseudorandom safe prime with bit length at least l and ord(2)=(p-1)/2
11
+ random_safeprime(l) find a pseudorandom safe prime with bit length at least l and ord(2)=(p-1)/2
12
+ is_blumprime(n) test if n is a Blum prime
13
+ random_blumprime(l) find a pseudorandom Blum prime with bit length at least l
11
14
  miller_rabin_test(n, b) Miller-Rabin primality test with base b
15
+ lucas_test(n) strong Lucas test
12
16
  """
13
- from math import isqrt, gcd
17
+ from math import isqrt, gcd, floor, ceil
14
18
  from random import randint
15
19
  from .nt import jacobi_symbol
16
20
 
@@ -18,6 +22,11 @@ from .nt import jacobi_symbol
18
22
 
19
23
  def sieve_eratosthenes(B: int) -> tuple:
20
24
  """Returns a tuple of all primes up to (including) `B`."""
25
+ if B < 2:
26
+ return ()
27
+ if B < 3:
28
+ return [2]
29
+ B= floor(B)
21
30
  B1 = (isqrt(B) - 1)//2
22
31
  B = (B - 1)//2
23
32
  isprime = [True] * (B + 1) # to begin with, all odd numbers are potentially prime
@@ -30,6 +39,11 @@ def sieve_eratosthenes(B: int) -> tuple:
30
39
 
31
40
  return tuple([2] + [2 * q + 1 for q in range(1, B + 1) if isprime[q]])
32
41
 
42
+ def prime_pi(x: float) -> int:
43
+ """Prime-counting function pi(x). Returns the number of primes below or equal `x`."""
44
+ return len(sieve_eratosthenes(x))
45
+
46
+
33
47
  # Primality testing
34
48
 
35
49
 
@@ -58,63 +72,6 @@ def miller_rabin_test(n: int, bases: list[int] | int) -> bool:
58
72
  return True
59
73
  return False
60
74
 
61
- def is_prime(n: int) -> bool:
62
- """Test if an integer `n` if probable prime."""
63
- if n < 18446744073709551616: # https://miller-rabin.appspot.com
64
- return miller_rabin_test(n, [2, 325, 9375, 28178, 450775, 9780504, 1795265022])
65
- if n < 3317044064679887385961981:
66
- return miller_rabin_test(n, [2, 3, 5, 7, 11, 13, 17, 19, 23, 29, 31, 37, 41])
67
- return miller_rabin_test(n, [2]) and _is_strong_lucas_prp(n) # Baillie–PSW primality test
68
-
69
- def next_prime(n: int) -> int:
70
- """Find the next prime larger or equal `n`."""
71
- if n < 3:
72
- return 2
73
- n |= 1 # make sure n is odd
74
- while not is_prime(n):
75
- n += 2
76
- return n
77
-
78
- def previous_prime(n: int) -> int:
79
- """Find the previous prime smaller or equal `n`."""
80
- if n < 3:
81
- return 2
82
- n += (n & 1) - 1 # make sure n is odd
83
- while not is_prime(n):
84
- n -= 2
85
- return n
86
-
87
- def random_prime(l: int) -> int:
88
- """Find a pseudorandom prime with bit length at least `l`."""
89
- return next_prime(randint(2 ** (l - 1), 2**l - 1))
90
-
91
- def random_strongprime(l: int) -> int:
92
- """Find a pseudorandom strong prime with bit length at least `l` using Gordon's algorithm."""
93
- t = random_prime(l)
94
- s = random_prime(l)
95
- u = 2 * t
96
- uu = u * randint(1, 100)
97
- while not is_prime(uu + 1):
98
- uu += u
99
- r = uu + 1
100
- u = 2 * r * s
101
- uu = u * randint(1, 100) + 2 * s * pow(s, r - 2, r) - 1
102
- while not is_prime(uu):
103
- uu += u
104
- return t, s, r, uu
105
-
106
- def is_safeprime(p: int) -> bool:
107
- """Tests if a number is a safe prime."""
108
- return is_prime(p) and is_prime((p - 1) // 2)
109
-
110
- def random_safeprime(l: int) -> int:
111
- """Find a pseudorandom safe prime with bit length at least `l` and `ord(2)=(p-1)/2`."""
112
- p = randint(2 ** (l - 1), 2**l - 1)
113
- p = p - (p % 24) + 23
114
- while not is_safeprime(p):
115
- p += 24
116
- return p
117
-
118
75
  def _lucas_sequence(n, D, k):
119
76
  """Evaluate a Lucas sequence."""
120
77
  # P = 1
@@ -140,8 +97,8 @@ def _lucas_sequence(n, D, k):
140
97
  return U % n, V % n, Qk
141
98
 
142
99
 
143
- def _is_strong_lucas_prp(n: int) -> bool:
144
- """Strong Lucas primality test."""
100
+ def lucas_test(n: int) -> bool:
101
+ """Run a strong Lucas primality test on `n`."""
145
102
 
146
103
  # remove powers of 2 from n+1 (= k * 2**s)
147
104
  k = (n + 1) // 2
@@ -175,3 +132,78 @@ def _is_strong_lucas_prp(n: int) -> bool:
175
132
  return True
176
133
  Qk = pow(Qk, 2, n)
177
134
  return False
135
+
136
+ def is_prime(n: int) -> bool:
137
+ """Test if an integer `n` if probable prime."""
138
+ if n < 18446744073709551616: # https://miller-rabin.appspot.com
139
+ return miller_rabin_test(n, [2, 325, 9375, 28178, 450775, 9780504, 1795265022])
140
+ if n < 3317044064679887385961981:
141
+ return miller_rabin_test(n, [2, 3, 5, 7, 11, 13, 17, 19, 23, 29, 31, 37, 41])
142
+ return miller_rabin_test(n, [2]) and lucas_test(n) # Baillie–PSW primality test
143
+
144
+ def is_safeprime(p: int) -> bool:
145
+ """Tests if a number is a safe prime."""
146
+ return is_prime(p) and is_prime((p - 1) // 2)
147
+
148
+ def is_blumprime(p: int) -> bool:
149
+ """Tests if a number is a Blum prime."""
150
+ return p % 4 == 3 and is_prime(p)
151
+
152
+
153
+ # Generation of primes
154
+
155
+
156
+ def next_prime(n: int) -> int:
157
+ """Find the next prime larger or equal `n`."""
158
+ if n < 3:
159
+ return 2
160
+ n = ceil(n)
161
+ n |= 1 # make sure n is odd
162
+ while not is_prime(n):
163
+ n += 2
164
+ return n
165
+
166
+ def previous_prime(n: int) -> int:
167
+ """Find the previous prime smaller or equal `n`."""
168
+ if n < 3:
169
+ return 2
170
+ n = floor(n)
171
+ n += (n & 1) - 1 # make sure n is odd
172
+ while not is_prime(n):
173
+ n -= 2
174
+ return n
175
+
176
+ def random_prime(l: int) -> int:
177
+ """Find a pseudorandom prime with bit length at least `l`."""
178
+ return next_prime(randint(2 ** (l - 1), 2**l - 1))
179
+
180
+ def random_strongprime(l: int) -> int:
181
+ """Find a pseudorandom strong prime with bit length at least `l` using Gordon's algorithm."""
182
+ t = random_prime(l)
183
+ s = random_prime(l)
184
+ u = 2 * t
185
+ uu = u * randint(1, 100)
186
+ while not is_prime(uu + 1):
187
+ uu += u
188
+ r = uu + 1
189
+ u = 2 * r * s
190
+ uu = u * randint(1, 100) + 2 * s * pow(s, r - 2, r) - 1
191
+ while not is_prime(uu):
192
+ uu += u
193
+ return t, s, r, uu
194
+
195
+ def random_safeprime(l: int) -> int:
196
+ """Find a pseudorandom safe prime with bit length at least `l` and `ord(2)=(p-1)/2`."""
197
+ p = randint(2 ** (l - 1), 2**l - 1)
198
+ p = p - (p % 24) + 23 # make sure p % 24 = 23
199
+ while not is_safeprime(p):
200
+ p += 24
201
+ return p
202
+
203
+ def random_blumprime(l: int) -> int:
204
+ """Find a pseudorandom Blum prime with bit length at least `l`."""
205
+ p = randint(2 ** (l - 1), 2**l - 1)
206
+ p = p - (p % 4) + 3 # make sure p % 4 = 3
207
+ while not is_prime(p):
208
+ p += 4
209
+ return p
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.1
2
2
  Name: kryptools
3
- Version: 0.9.2
3
+ Version: 0.9.4
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.9.2"
3
+ version = "0.9.4"
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