kryptools 1.5.3__tar.gz → 1.7__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-1.5.3 → kryptools-1.7}/PKG-INFO +6 -3
- {kryptools-1.5.3 → kryptools-1.7}/README.md +5 -2
- {kryptools-1.5.3 → kryptools-1.7}/kryptools/GF2.py +84 -35
- {kryptools-1.5.3 → kryptools-1.7}/kryptools/Zmod.py +8 -5
- {kryptools-1.5.3 → kryptools-1.7}/kryptools/__init__.py +4 -4
- kryptools-1.7/kryptools/code.py +664 -0
- {kryptools-1.5.3 → kryptools-1.7}/kryptools/factor_qs.py +2 -2
- kryptools-1.7/kryptools/la.py +952 -0
- {kryptools-1.5.3 → kryptools-1.7}/kryptools/poly.py +219 -6
- {kryptools-1.5.3 → kryptools-1.7}/kryptools/primes.py +1 -1
- {kryptools-1.5.3 → kryptools-1.7}/kryptools.egg-info/PKG-INFO +6 -3
- {kryptools-1.5.3 → kryptools-1.7}/pyproject.toml +1 -1
- {kryptools-1.5.3 → kryptools-1.7}/tests/test_GF2.py +26 -1
- {kryptools-1.5.3 → kryptools-1.7}/tests/test_Zmod.py +5 -2
- {kryptools-1.5.3 → kryptools-1.7}/tests/test_code.py +34 -2
- kryptools-1.7/tests/test_la.py +92 -0
- {kryptools-1.5.3 → kryptools-1.7}/tests/test_poly.py +25 -3
- kryptools-1.5.3/kryptools/code.py +0 -327
- kryptools-1.5.3/kryptools/la.py +0 -446
- kryptools-1.5.3/tests/test_la.py +0 -28
- {kryptools-1.5.3 → kryptools-1.7}/LICENSE +0 -0
- {kryptools-1.5.3 → kryptools-1.7}/kryptools/aes.py +0 -0
- {kryptools-1.5.3 → kryptools-1.7}/kryptools/blockcipher.py +0 -0
- {kryptools-1.5.3 → kryptools-1.7}/kryptools/conway_polynomials.py +0 -0
- {kryptools-1.5.3 → kryptools-1.7}/kryptools/des.py +0 -0
- {kryptools-1.5.3 → kryptools-1.7}/kryptools/dlp.py +0 -0
- {kryptools-1.5.3 → kryptools-1.7}/kryptools/dlp_bsgs.py +0 -0
- {kryptools-1.5.3 → kryptools-1.7}/kryptools/dlp_ic.py +0 -0
- {kryptools-1.5.3 → kryptools-1.7}/kryptools/dlp_qs.py +0 -0
- {kryptools-1.5.3 → kryptools-1.7}/kryptools/dlp_rho.py +0 -0
- {kryptools-1.5.3 → kryptools-1.7}/kryptools/ec.py +0 -0
- {kryptools-1.5.3 → kryptools-1.7}/kryptools/factor.py +0 -0
- {kryptools-1.5.3 → kryptools-1.7}/kryptools/factor_dix.py +0 -0
- {kryptools-1.5.3 → kryptools-1.7}/kryptools/factor_ecm.py +0 -0
- {kryptools-1.5.3 → kryptools-1.7}/kryptools/factor_fmt.py +0 -0
- {kryptools-1.5.3 → kryptools-1.7}/kryptools/factor_pm1.py +0 -0
- {kryptools-1.5.3 → kryptools-1.7}/kryptools/factor_rho.py +0 -0
- {kryptools-1.5.3 → kryptools-1.7}/kryptools/intfuncs.py +0 -0
- {kryptools-1.5.3 → kryptools-1.7}/kryptools/keccak.py +0 -0
- {kryptools-1.5.3 → kryptools-1.7}/kryptools/lat.py +0 -0
- {kryptools-1.5.3 → kryptools-1.7}/kryptools/nt.py +0 -0
- {kryptools-1.5.3 → kryptools-1.7}/kryptools/sha1.py +0 -0
- {kryptools-1.5.3 → kryptools-1.7}/kryptools.egg-info/SOURCES.txt +0 -0
- {kryptools-1.5.3 → kryptools-1.7}/kryptools.egg-info/dependency_links.txt +0 -0
- {kryptools-1.5.3 → kryptools-1.7}/kryptools.egg-info/top_level.txt +0 -0
- {kryptools-1.5.3 → kryptools-1.7}/setup.cfg +0 -0
- {kryptools-1.5.3 → kryptools-1.7}/tests/test_aes.py +0 -0
- {kryptools-1.5.3 → kryptools-1.7}/tests/test_des.py +0 -0
- {kryptools-1.5.3 → kryptools-1.7}/tests/test_dlog.py +0 -0
- {kryptools-1.5.3 → kryptools-1.7}/tests/test_ec.py +0 -0
- {kryptools-1.5.3 → kryptools-1.7}/tests/test_factor.py +0 -0
- {kryptools-1.5.3 → kryptools-1.7}/tests/test_factor_fmt.py +0 -0
- {kryptools-1.5.3 → kryptools-1.7}/tests/test_factor_pm1.py +0 -0
- {kryptools-1.5.3 → kryptools-1.7}/tests/test_factor_qs.py +0 -0
- {kryptools-1.5.3 → kryptools-1.7}/tests/test_intfuncs.py +0 -0
- {kryptools-1.5.3 → kryptools-1.7}/tests/test_keccak.py +0 -0
- {kryptools-1.5.3 → kryptools-1.7}/tests/test_lat.py +0 -0
- {kryptools-1.5.3 → kryptools-1.7}/tests/test_nt.py +0 -0
- {kryptools-1.5.3 → kryptools-1.7}/tests/test_primes.py +0 -0
- {kryptools-1.5.3 → kryptools-1.7}/tests/test_sha1.py +0 -0
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: kryptools
|
|
3
|
-
Version: 1.
|
|
3
|
+
Version: 1.7
|
|
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
|
|
@@ -47,13 +47,16 @@ The tools contained are:
|
|
|
47
47
|
* lattices: Hadamard ratio, Babai rounding/nearest plane algorithm, lattice reduction (Lenstra-Lenstra-Lovaz)
|
|
48
48
|
* linear codes: Hamming distance, left standard form, parity check matrix
|
|
49
49
|
|
|
50
|
-
* Matrix: a class for Matrices (inverse, det, reduced echelon form, etc.)
|
|
50
|
+
* Matrix: a class for Matrices (inverse, det, reduced echelon form, kernel, etc.)
|
|
51
|
+
* BinaryMatrix: a class for Matrices with binary entries (for much faster row operations)
|
|
51
52
|
* Poly: a class for polynomials (division, modulo, factoring and irreducibility test over finite fields, Lagrange interpolation)
|
|
52
53
|
* Zmod: a class for the ring of integers modulo an integer
|
|
53
54
|
* GF2: a class for Galois fields GF(2^n)
|
|
54
|
-
*
|
|
55
|
+
* BinaryCode: a class for encoding and decoding binary linear codes
|
|
56
|
+
* GoppaCode: a class for encoding and decoding binary Goppa codes
|
|
55
57
|
* CyclicCode: a class for encoding and decoding cyclic codes
|
|
56
58
|
* ReedSolomonCode: a class for encoding and decoding Reed-Solomon codes
|
|
59
|
+
* BCHCode: a class for encoding and decoding primitive narrow sense BCH codes
|
|
57
60
|
|
|
58
61
|
* BlockCipher: a class implementing the usual modes of operation (ECB, CBC, GCM, etc.)
|
|
59
62
|
* AESCipher: individual AES operations
|
|
@@ -29,13 +29,16 @@ The tools contained are:
|
|
|
29
29
|
* lattices: Hadamard ratio, Babai rounding/nearest plane algorithm, lattice reduction (Lenstra-Lenstra-Lovaz)
|
|
30
30
|
* linear codes: Hamming distance, left standard form, parity check matrix
|
|
31
31
|
|
|
32
|
-
* Matrix: a class for Matrices (inverse, det, reduced echelon form, etc.)
|
|
32
|
+
* Matrix: a class for Matrices (inverse, det, reduced echelon form, kernel, etc.)
|
|
33
|
+
* BinaryMatrix: a class for Matrices with binary entries (for much faster row operations)
|
|
33
34
|
* Poly: a class for polynomials (division, modulo, factoring and irreducibility test over finite fields, Lagrange interpolation)
|
|
34
35
|
* Zmod: a class for the ring of integers modulo an integer
|
|
35
36
|
* GF2: a class for Galois fields GF(2^n)
|
|
36
|
-
*
|
|
37
|
+
* BinaryCode: a class for encoding and decoding binary linear codes
|
|
38
|
+
* GoppaCode: a class for encoding and decoding binary Goppa codes
|
|
37
39
|
* CyclicCode: a class for encoding and decoding cyclic codes
|
|
38
40
|
* ReedSolomonCode: a class for encoding and decoding Reed-Solomon codes
|
|
41
|
+
* BCHCode: a class for encoding and decoding primitive narrow sense BCH codes
|
|
39
42
|
|
|
40
43
|
* BlockCipher: a class implementing the usual modes of operation (ECB, CBC, GCM, etc.)
|
|
41
44
|
* AESCipher: individual AES operations
|
|
@@ -35,7 +35,7 @@ class GF2:
|
|
|
35
35
|
f6
|
|
36
36
|
|
|
37
37
|
"""
|
|
38
|
-
def __init__(self, n: int, modulus: int | None = None):
|
|
38
|
+
def __init__(self, n: int, modulus: int | None = None, cached = False):
|
|
39
39
|
if not isinstance(n, int) or n < 1:
|
|
40
40
|
raise ValueError(f"{n} is not a positive integer.")
|
|
41
41
|
if not modulus:
|
|
@@ -55,14 +55,23 @@ class GF2:
|
|
|
55
55
|
self.byteorder: str = "big" # big|little
|
|
56
56
|
self.mult_order = self.order - 1
|
|
57
57
|
self.factors = {} # factoring of the group order
|
|
58
|
+
self.cached = False # use precomputed log/exp tables to speed up multiplication
|
|
59
|
+
self.log = None # precomputed log table
|
|
60
|
+
self.exp = None # precomputed exp table
|
|
61
|
+
if cached:
|
|
62
|
+
self.cache()
|
|
58
63
|
|
|
59
64
|
def __repr__(self):
|
|
60
65
|
return f"GF(2^{self.degree})"
|
|
61
66
|
|
|
62
67
|
def __call__(self, x: int | list | tuple | range | map):
|
|
63
68
|
if isinstance(x, list|tuple|range|map):
|
|
64
|
-
|
|
65
|
-
|
|
69
|
+
if isinstance(x, bytes | bytearray):
|
|
70
|
+
return [ GF2nPoint(int.from_bytes(x, byteorder=self.byteorder), self) for xx in x]
|
|
71
|
+
return [GF2nPoint(int(xx) % self.order, self) for xx in x]
|
|
72
|
+
if isinstance(x, bytes | bytearray):
|
|
73
|
+
return GF2nPoint(int.from_bytes(x, byteorder=self.byteorder), self)
|
|
74
|
+
return GF2nPoint(int(x) % self.order, self)
|
|
66
75
|
|
|
67
76
|
def __len__(self):
|
|
68
77
|
return self.order
|
|
@@ -80,26 +89,26 @@ class GF2:
|
|
|
80
89
|
return isinstance(other, GF2nPoint) and self == other.field
|
|
81
90
|
|
|
82
91
|
def _factors(self) -> dict:
|
|
83
|
-
"Return the factroization
|
|
92
|
+
"Return the factroization of the group order of GF(2^n)^*."
|
|
84
93
|
if not self.factors:
|
|
85
94
|
self.factors = factorint(self.mult_order)
|
|
86
95
|
return self.factors
|
|
87
96
|
|
|
88
97
|
def zero(self) -> bool:
|
|
89
98
|
"Return zero."
|
|
90
|
-
return
|
|
99
|
+
return GF2nPoint(0, self)
|
|
91
100
|
|
|
92
101
|
def one(self) -> bool:
|
|
93
102
|
"Return one."
|
|
94
103
|
if self.bitreversed:
|
|
95
|
-
return
|
|
96
|
-
return
|
|
104
|
+
return GF2nPoint(self.order >> 1, self)
|
|
105
|
+
return GF2nPoint(1, self)
|
|
97
106
|
|
|
98
107
|
def random(self, num: int = 0) -> "GF2nPoint":
|
|
99
108
|
"Return a single random point or a list of random points."
|
|
100
109
|
if num:
|
|
101
|
-
return([
|
|
102
|
-
return
|
|
110
|
+
return([GF2nPoint(randint(0,self.order-1), self) for _ in range(num)])
|
|
111
|
+
return GF2nPoint(randint(0,self.order-1), self)
|
|
103
112
|
|
|
104
113
|
def is_cyclic(self) -> bool:
|
|
105
114
|
"GF(2^n)^* is cyclic."
|
|
@@ -111,10 +120,12 @@ class GF2:
|
|
|
111
120
|
|
|
112
121
|
def generator(self) -> int | None:
|
|
113
122
|
"Return a generator of the group GF(2^n)^*."
|
|
123
|
+
if self.cached:
|
|
124
|
+
return self.exp[1]
|
|
114
125
|
if self.degree == 1:
|
|
115
|
-
return self(
|
|
126
|
+
return self.one()
|
|
116
127
|
for a in range(2, self.order):
|
|
117
|
-
a =
|
|
128
|
+
a = GF2nPoint(a, self)
|
|
118
129
|
if a.is_generator():
|
|
119
130
|
return a
|
|
120
131
|
|
|
@@ -129,16 +140,35 @@ class GF2:
|
|
|
129
140
|
def star(self) -> list:
|
|
130
141
|
"Return a generator for all elements of the group GF(2^n)n^*."
|
|
131
142
|
for x in range(1, self.order):
|
|
132
|
-
yield
|
|
143
|
+
yield GF2nPoint(x, self)
|
|
144
|
+
|
|
145
|
+
def poly(self) -> Poly:
|
|
146
|
+
"Return the associated irreducible polynomial."
|
|
147
|
+
coeff = [int(d) for d in str(
|
|
148
|
+
format(self.modulus, "b"))]
|
|
149
|
+
if self.bitreversed:
|
|
150
|
+
return Poly(coeff + [1])
|
|
151
|
+
return Poly(list(reversed(coeff)))
|
|
152
|
+
|
|
153
|
+
def cache(self) -> None:
|
|
154
|
+
"Create a exp/log table to speed up multiplication."
|
|
155
|
+
if not self.cached:
|
|
156
|
+
self.exp = [ 0 ] * self.mult_order
|
|
157
|
+
self.log = [ 0 ] * self.order
|
|
158
|
+
g = self.generator()
|
|
159
|
+
gj = self.one()
|
|
160
|
+
for j in range(self.mult_order):
|
|
161
|
+
self.exp[j] = gj
|
|
162
|
+
self.log[gj.x] = j
|
|
163
|
+
gj *= g
|
|
164
|
+
self.cached = True
|
|
133
165
|
|
|
134
166
|
|
|
135
167
|
class GF2nPoint:
|
|
136
168
|
"Represents a point in the Galois field GF(2^n)."
|
|
137
169
|
|
|
138
170
|
def __init__(self, x: int, field: "GF2"):
|
|
139
|
-
|
|
140
|
-
x = int.from_bytes(x, byteorder=field.byteorder)
|
|
141
|
-
self.x = int(x) % field.order
|
|
171
|
+
self.x = x
|
|
142
172
|
self.field = field
|
|
143
173
|
|
|
144
174
|
def __repr__(self):
|
|
@@ -162,13 +192,11 @@ class GF2nPoint:
|
|
|
162
192
|
|
|
163
193
|
def bits(self) -> list:
|
|
164
194
|
"Convert to a list of bits."
|
|
195
|
+
coeff = [int(d) for d in str(
|
|
196
|
+
format(self.x, "0" + str(self.field.degree) + "b"))]
|
|
165
197
|
if self.field.bitreversed:
|
|
166
|
-
coeff
|
|
167
|
-
|
|
168
|
-
else:
|
|
169
|
-
coeff = reversed([int(d) for d in str(
|
|
170
|
-
format(self.x, "0" + str(self.field.degree) + "b"))])
|
|
171
|
-
return list(coeff)
|
|
198
|
+
coeff.reverse()
|
|
199
|
+
return coeff
|
|
172
200
|
|
|
173
201
|
def poly(self) -> "Poly":
|
|
174
202
|
"Convert to a polynomial."
|
|
@@ -193,7 +221,7 @@ class GF2nPoint:
|
|
|
193
221
|
return NotImplemented
|
|
194
222
|
if self.field != other.field:
|
|
195
223
|
raise NotImplementedError("Cannot add elements from different fields.")
|
|
196
|
-
return self.
|
|
224
|
+
return self.__class__(self.x ^ other.x, self.field)
|
|
197
225
|
|
|
198
226
|
__sub__ = __add__
|
|
199
227
|
|
|
@@ -206,11 +234,15 @@ class GF2nPoint:
|
|
|
206
234
|
if isinstance(other, int):
|
|
207
235
|
if other % 2:
|
|
208
236
|
return self
|
|
209
|
-
return self.
|
|
237
|
+
return self.__class__(0, self.field)
|
|
210
238
|
if not isinstance(other, self.__class__):
|
|
211
239
|
return NotImplemented
|
|
212
240
|
if self.field != other.field:
|
|
213
|
-
raise NotImplementedError("Cannot
|
|
241
|
+
raise NotImplementedError("Cannot multiply elements from different fields.")
|
|
242
|
+
if self.field.cached:
|
|
243
|
+
if self.x and other.x:
|
|
244
|
+
return self.field.exp[(self.field.log[self.x] + self.field.log[other.x]) % self.field.mult_order]
|
|
245
|
+
return self.field.zero()
|
|
214
246
|
z = 0
|
|
215
247
|
y = other.x
|
|
216
248
|
if self.field.bitreversed:
|
|
@@ -232,13 +264,13 @@ class GF2nPoint:
|
|
|
232
264
|
y <<= 1
|
|
233
265
|
if y & bitmap1:
|
|
234
266
|
y ^= self.field.modulus
|
|
235
|
-
return self.
|
|
267
|
+
return self.__class__(z, self.field)
|
|
236
268
|
|
|
237
269
|
def __rmul__(self, scalar: int) -> "GF2nPoint":
|
|
238
270
|
if isinstance(scalar, int):
|
|
239
271
|
if scalar % 2:
|
|
240
272
|
return self
|
|
241
|
-
return self.
|
|
273
|
+
return self.__class__(0, self.field)
|
|
242
274
|
return NotImplemented
|
|
243
275
|
|
|
244
276
|
def __truediv__(self, other: "GF2nPoint") -> "GF2nPoint":
|
|
@@ -253,16 +285,22 @@ class GF2nPoint:
|
|
|
253
285
|
def __pow__(self, j: int) -> "GF2nPoint":
|
|
254
286
|
if not isinstance(j, int):
|
|
255
287
|
return NotImplemented
|
|
256
|
-
if
|
|
257
|
-
|
|
288
|
+
if self.x == 0:
|
|
289
|
+
if j < 0:
|
|
290
|
+
raise ValueError("Division by zero.")
|
|
291
|
+
if j:
|
|
292
|
+
return self
|
|
293
|
+
return self.field.one()
|
|
294
|
+
j %= self.field.mult_order
|
|
295
|
+
if self.field.cached:
|
|
296
|
+
return self.field.exp[j * self.field.log[self.x] % self.field.mult_order]
|
|
258
297
|
if self.field.order == 2:
|
|
259
298
|
return self
|
|
260
299
|
if self.field.bitreversed:
|
|
261
|
-
res = self.
|
|
300
|
+
res = self.__class__(self.field.order >> 1, self.field)
|
|
262
301
|
else:
|
|
263
|
-
res = self.
|
|
264
|
-
x = self.
|
|
265
|
-
j %= self.field.order - 1
|
|
302
|
+
res = self.__class__(1, self.field)
|
|
303
|
+
x = self.__class__(self.x, self.field)
|
|
266
304
|
while j > 0:
|
|
267
305
|
# If j is odd, multiply with x
|
|
268
306
|
if j & 1:
|
|
@@ -276,13 +314,13 @@ class GF2nPoint:
|
|
|
276
314
|
"Cyclic rotation to the left."
|
|
277
315
|
x = self.x << j
|
|
278
316
|
x = (x % self.field.order) + (x // self.field.order)
|
|
279
|
-
return self.
|
|
317
|
+
return self.__class__(self.x, self.field)
|
|
280
318
|
|
|
281
319
|
def __rshift__(self, j: int) -> "GF2nPoint":
|
|
282
320
|
"Cyclic rotation to the right."
|
|
283
321
|
x = self.x >> j
|
|
284
322
|
x += (self.field.order >> j) * (self.x % 2**j)
|
|
285
|
-
return self.
|
|
323
|
+
return self.__class__(self.x, self.field)
|
|
286
324
|
|
|
287
325
|
def sqrt(self) -> "GF2nPoint":
|
|
288
326
|
"Compute the square root."
|
|
@@ -308,6 +346,17 @@ class GF2nPoint:
|
|
|
308
346
|
"Test if the point is a generator of the group GF(2^n)^*."
|
|
309
347
|
return self.field.mult_order == self.order()
|
|
310
348
|
|
|
349
|
+
def minpoly(self) -> Poly:
|
|
350
|
+
"Return the minimal polynomial of an element."
|
|
351
|
+
aj = self
|
|
352
|
+
mpoly = Poly([aj, self.field.one()])
|
|
353
|
+
for _ in range(1, self.field.degree):
|
|
354
|
+
aj = aj**2 # Frobenius
|
|
355
|
+
if aj == self:
|
|
356
|
+
break
|
|
357
|
+
mpoly *= Poly([aj, self.field.one()])
|
|
358
|
+
return mpoly
|
|
359
|
+
|
|
311
360
|
def sbox(self, inv: bool = False) -> "GF2nPoint":
|
|
312
361
|
"Apply the AES sbox."
|
|
313
362
|
if self.field.degree == 8 and self.field.modulus == 0b100011011: # AES
|
|
@@ -321,7 +370,7 @@ class GF2nPoint:
|
|
|
321
370
|
raise ValueError("sbox is only availaible for AES/MiniAES field.")
|
|
322
371
|
|
|
323
372
|
# sbox for AES
|
|
324
|
-
GF2_aes = GF2(8, 0b100011011) # x^8 + x^4 + x^3 + x + 1 = AES
|
|
373
|
+
GF2_aes = GF2(8, 0b100011011, cached = True) # x^8 + x^4 + x^3 + x + 1 = AES
|
|
325
374
|
|
|
326
375
|
aes_sbox = [99, 124, 119, 123, 242, 107, 111, 197, 48, 1, 103, 43, 254, 215, 171, 118,
|
|
327
376
|
202, 130, 201, 125, 250, 89, 71, 240, 173, 212, 162, 175, 156, 164, 114, 192,
|
|
@@ -43,8 +43,8 @@ class Zmod:
|
|
|
43
43
|
|
|
44
44
|
def __call__(self, x: int | list | tuple | range | map):
|
|
45
45
|
if isinstance(x, list|tuple|range|map):
|
|
46
|
-
return [ZmodPoint(xx, self) for xx in x]
|
|
47
|
-
return ZmodPoint(x, self)
|
|
46
|
+
return [ZmodPoint(int(xx), self) for xx in x]
|
|
47
|
+
return ZmodPoint(int(x), self)
|
|
48
48
|
|
|
49
49
|
def __iter__(self):
|
|
50
50
|
for x in range(self.n):
|
|
@@ -157,7 +157,7 @@ class ZmodPoint:
|
|
|
157
157
|
"Represents a point in the ring Zmod."
|
|
158
158
|
|
|
159
159
|
def __init__(self, x: int, ring: "Zmod"):
|
|
160
|
-
self.x =
|
|
160
|
+
self.x = x % ring.n
|
|
161
161
|
self.ring = ring
|
|
162
162
|
|
|
163
163
|
def __repr__(self):
|
|
@@ -247,8 +247,11 @@ class ZmodPoint:
|
|
|
247
247
|
|
|
248
248
|
def sharp(self):
|
|
249
249
|
"Returns a symmetric (w.r.t. 0) representative."
|
|
250
|
-
|
|
251
|
-
|
|
250
|
+
if self.x <= self.ring.n // 2:
|
|
251
|
+
return self.x
|
|
252
|
+
return self.x - self.ring.n
|
|
253
|
+
|
|
254
|
+
mods = sharp
|
|
252
255
|
|
|
253
256
|
def order(self) -> int:
|
|
254
257
|
"Compute the order of the point in the group Z_n^*."
|
|
@@ -5,7 +5,7 @@ Implemenation of same basic algorithms used in cryptography.
|
|
|
5
5
|
__author__ = "Gerald Teschl"
|
|
6
6
|
__copyright__ = "Copyright 2024-2025, Gerald Teschl"
|
|
7
7
|
__license__ = "MIT License"
|
|
8
|
-
__version__ = "1.
|
|
8
|
+
__version__ = "1.7"
|
|
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, is_carmichael_number, order, crt
|
|
@@ -14,12 +14,12 @@ from .intfuncs import iroot, ilog, perfect_square, perfect_power, prime_power
|
|
|
14
14
|
from .factor import factorint, divisors
|
|
15
15
|
from .dlp import dlog
|
|
16
16
|
from .ec import EC_Weierstrass
|
|
17
|
-
from .la import Matrix, zeros, eye
|
|
17
|
+
from .la import Matrix, zeros, eye, circulant, BinaryMatrix
|
|
18
18
|
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
|
|
19
|
-
from .poly import Poly, lagrange_interpolation
|
|
19
|
+
from .poly import Poly, PolyBinMult, lagrange_interpolation
|
|
20
20
|
from .Zmod import Zmod
|
|
21
21
|
from .GF2 import GF2, GF2_aes, GF2_miniaes, GF2_ghash
|
|
22
|
-
from .code import
|
|
22
|
+
from .code import gen2pchk, hamming_dist, BinaryCode, GolayCode, HammingCode, ReedMullerCode, GoppaCode, CyclicCode, ReedSolomonCode, BCHCode
|
|
23
23
|
from .blockcipher import BlockCipher, bytexor
|
|
24
24
|
from .aes import AESKeySchedule, AESCipher, AESBlockCipher
|
|
25
25
|
from .des import list2int, int2list, permute, invert_permutation, rotate_left, SDESKeySchedule, SDESCipher, DESKeySchedule, DESCipher, DESBlockCipher
|