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.
- {kryptools-0.9.2 → kryptools-0.9.4}/PKG-INFO +1 -1
- {kryptools-0.9.2 → kryptools-0.9.4}/kryptools/Zmod.py +20 -0
- {kryptools-0.9.2 → kryptools-0.9.4}/kryptools/__init__.py +1 -1
- {kryptools-0.9.2 → kryptools-0.9.4}/kryptools/primes.py +93 -61
- {kryptools-0.9.2 → kryptools-0.9.4}/kryptools.egg-info/PKG-INFO +1 -1
- {kryptools-0.9.2 → kryptools-0.9.4}/pyproject.toml +1 -1
- {kryptools-0.9.2 → kryptools-0.9.4}/LICENSE +0 -0
- {kryptools-0.9.2 → kryptools-0.9.4}/README.md +0 -0
- {kryptools-0.9.2 → kryptools-0.9.4}/kryptools/dlp.py +0 -0
- {kryptools-0.9.2 → kryptools-0.9.4}/kryptools/dlp_bsgs.py +0 -0
- {kryptools-0.9.2 → kryptools-0.9.4}/kryptools/dlp_ic.py +0 -0
- {kryptools-0.9.2 → kryptools-0.9.4}/kryptools/dlp_qs.py +0 -0
- {kryptools-0.9.2 → kryptools-0.9.4}/kryptools/dlp_rho.py +0 -0
- {kryptools-0.9.2 → kryptools-0.9.4}/kryptools/ec.py +0 -0
- {kryptools-0.9.2 → kryptools-0.9.4}/kryptools/factor.py +0 -0
- {kryptools-0.9.2 → kryptools-0.9.4}/kryptools/factor_dix.py +0 -0
- {kryptools-0.9.2 → kryptools-0.9.4}/kryptools/factor_ecm.py +0 -0
- {kryptools-0.9.2 → kryptools-0.9.4}/kryptools/factor_fmt.py +0 -0
- {kryptools-0.9.2 → kryptools-0.9.4}/kryptools/factor_pm1.py +0 -0
- {kryptools-0.9.2 → kryptools-0.9.4}/kryptools/factor_qs.py +0 -0
- {kryptools-0.9.2 → kryptools-0.9.4}/kryptools/la.py +0 -0
- {kryptools-0.9.2 → kryptools-0.9.4}/kryptools/lat.py +0 -0
- {kryptools-0.9.2 → kryptools-0.9.4}/kryptools/nt.py +0 -0
- {kryptools-0.9.2 → kryptools-0.9.4}/kryptools/poly.py +0 -0
- {kryptools-0.9.2 → kryptools-0.9.4}/kryptools.egg-info/SOURCES.txt +0 -0
- {kryptools-0.9.2 → kryptools-0.9.4}/kryptools.egg-info/dependency_links.txt +0 -0
- {kryptools-0.9.2 → kryptools-0.9.4}/kryptools.egg-info/top_level.txt +0 -0
- {kryptools-0.9.2 → kryptools-0.9.4}/setup.cfg +0 -0
|
@@ -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(
|
|
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
|
|
144
|
-
"""
|
|
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
|
|
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
|