kryptools 1.9__tar.gz → 1.9.2__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 (58) hide show
  1. {kryptools-1.9 → kryptools-1.9.2}/PKG-INFO +3 -3
  2. {kryptools-1.9 → kryptools-1.9.2}/README.md +2 -2
  3. {kryptools-1.9 → kryptools-1.9.2}/kryptools/__init__.py +3 -3
  4. {kryptools-1.9 → kryptools-1.9.2}/kryptools/factor.py +2 -3
  5. {kryptools-1.9 → kryptools-1.9.2}/kryptools/la.py +1 -1
  6. {kryptools-1.9 → kryptools-1.9.2}/kryptools/lat.py +12 -4
  7. {kryptools-1.9 → kryptools-1.9.2}/kryptools/lat2.py +1 -11
  8. {kryptools-1.9 → kryptools-1.9.2}/kryptools/poly.py +11 -5
  9. {kryptools-1.9 → kryptools-1.9.2}/kryptools.egg-info/PKG-INFO +3 -3
  10. {kryptools-1.9 → kryptools-1.9.2}/pyproject.toml +1 -1
  11. {kryptools-1.9 → kryptools-1.9.2}/tests/test_poly.py +14 -7
  12. {kryptools-1.9 → kryptools-1.9.2}/LICENSE +0 -0
  13. {kryptools-1.9 → kryptools-1.9.2}/kryptools/GF2.py +0 -0
  14. {kryptools-1.9 → kryptools-1.9.2}/kryptools/Zmod.py +0 -0
  15. {kryptools-1.9 → kryptools-1.9.2}/kryptools/aes.py +0 -0
  16. {kryptools-1.9 → kryptools-1.9.2}/kryptools/blockcipher.py +0 -0
  17. {kryptools-1.9 → kryptools-1.9.2}/kryptools/code.py +0 -0
  18. {kryptools-1.9 → kryptools-1.9.2}/kryptools/conway_polynomials.py +0 -0
  19. {kryptools-1.9 → kryptools-1.9.2}/kryptools/des.py +0 -0
  20. {kryptools-1.9 → kryptools-1.9.2}/kryptools/dlp.py +0 -0
  21. {kryptools-1.9 → kryptools-1.9.2}/kryptools/dlp_bsgs.py +0 -0
  22. {kryptools-1.9 → kryptools-1.9.2}/kryptools/dlp_ic.py +0 -0
  23. {kryptools-1.9 → kryptools-1.9.2}/kryptools/dlp_qs.py +0 -0
  24. {kryptools-1.9 → kryptools-1.9.2}/kryptools/dlp_rho.py +0 -0
  25. {kryptools-1.9 → kryptools-1.9.2}/kryptools/ec.py +0 -0
  26. {kryptools-1.9 → kryptools-1.9.2}/kryptools/factor_dix.py +0 -0
  27. {kryptools-1.9 → kryptools-1.9.2}/kryptools/factor_ecm.py +0 -0
  28. {kryptools-1.9 → kryptools-1.9.2}/kryptools/factor_fmt.py +0 -0
  29. {kryptools-1.9 → kryptools-1.9.2}/kryptools/factor_pm1.py +0 -0
  30. {kryptools-1.9 → kryptools-1.9.2}/kryptools/factor_qs.py +0 -0
  31. {kryptools-1.9 → kryptools-1.9.2}/kryptools/factor_rho.py +0 -0
  32. {kryptools-1.9 → kryptools-1.9.2}/kryptools/intfuncs.py +0 -0
  33. {kryptools-1.9 → kryptools-1.9.2}/kryptools/keccak.py +0 -0
  34. {kryptools-1.9 → kryptools-1.9.2}/kryptools/nt.py +0 -0
  35. {kryptools-1.9 → kryptools-1.9.2}/kryptools/primes.py +0 -0
  36. {kryptools-1.9 → kryptools-1.9.2}/kryptools/sha1.py +0 -0
  37. {kryptools-1.9 → kryptools-1.9.2}/kryptools.egg-info/SOURCES.txt +0 -0
  38. {kryptools-1.9 → kryptools-1.9.2}/kryptools.egg-info/dependency_links.txt +0 -0
  39. {kryptools-1.9 → kryptools-1.9.2}/kryptools.egg-info/top_level.txt +0 -0
  40. {kryptools-1.9 → kryptools-1.9.2}/setup.cfg +0 -0
  41. {kryptools-1.9 → kryptools-1.9.2}/tests/test_GF2.py +0 -0
  42. {kryptools-1.9 → kryptools-1.9.2}/tests/test_Zmod.py +0 -0
  43. {kryptools-1.9 → kryptools-1.9.2}/tests/test_aes.py +0 -0
  44. {kryptools-1.9 → kryptools-1.9.2}/tests/test_code.py +0 -0
  45. {kryptools-1.9 → kryptools-1.9.2}/tests/test_des.py +0 -0
  46. {kryptools-1.9 → kryptools-1.9.2}/tests/test_dlog.py +0 -0
  47. {kryptools-1.9 → kryptools-1.9.2}/tests/test_ec.py +0 -0
  48. {kryptools-1.9 → kryptools-1.9.2}/tests/test_factor.py +0 -0
  49. {kryptools-1.9 → kryptools-1.9.2}/tests/test_factor_fmt.py +0 -0
  50. {kryptools-1.9 → kryptools-1.9.2}/tests/test_factor_pm1.py +0 -0
  51. {kryptools-1.9 → kryptools-1.9.2}/tests/test_factor_qs.py +0 -0
  52. {kryptools-1.9 → kryptools-1.9.2}/tests/test_intfuncs.py +0 -0
  53. {kryptools-1.9 → kryptools-1.9.2}/tests/test_keccak.py +0 -0
  54. {kryptools-1.9 → kryptools-1.9.2}/tests/test_la.py +0 -0
  55. {kryptools-1.9 → kryptools-1.9.2}/tests/test_lat.py +0 -0
  56. {kryptools-1.9 → kryptools-1.9.2}/tests/test_nt.py +0 -0
  57. {kryptools-1.9 → kryptools-1.9.2}/tests/test_primes.py +0 -0
  58. {kryptools-1.9 → kryptools-1.9.2}/tests/test_sha1.py +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: kryptools
3
- Version: 1.9
3
+ Version: 1.9.2
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
@@ -44,12 +44,12 @@ The tools contained are:
44
44
  * integer factorization (Fermat, Pollard p-1, Pollard rho, Lenstra's ECM, Dixon, basic quadratic sieve)
45
45
  * elliptic curves (Weierstrass form), group operations, order, discrete logarithms
46
46
  * linear algebra: Hermite normal form, Smith normal form, Gram-Schmidt
47
- * lattices: Hadamard ratio, Babai rounding/nearest plane algorithm, lattice reduction (Hermite, Lenstra-Lenstra-Lovaz, BKZ), SIS, ISIS, LWE
47
+ * lattices: Hadamard ratio, Babai rounding/nearest plane algorithm, lattice reduction (Hermite, Lenstra-Lenstra-Lovasz, BKZ), SIS, ISIS, LWE
48
48
  * linear codes: Hamming distance, left standard form, parity check matrix
49
49
 
50
50
  * Matrix: a class for Matrices (inverse, det, reduced echelon form, kernel, solving linear systems, etc.)
51
51
  * BinaryMatrix: a class for Matrices with binary entries (for much faster row operations)
52
- * Lattice: a class for lattices (SVP, CPV, LLL, BKZ, HKZ)
52
+ * Lattice: a class for lattices (SVP, CVP, LLL, BKZ, HKZ)
53
53
  * Poly: a class for polynomials (division, modulo, factoring and irreducibility test over finite fields, Lagrange interpolation)
54
54
  * Zmod: a class for the ring of integers modulo an integer
55
55
  * GF2: a class for Galois fields GF(2^n)
@@ -26,12 +26,12 @@ The tools contained are:
26
26
  * integer factorization (Fermat, Pollard p-1, Pollard rho, Lenstra's ECM, Dixon, basic quadratic sieve)
27
27
  * elliptic curves (Weierstrass form), group operations, order, discrete logarithms
28
28
  * linear algebra: Hermite normal form, Smith normal form, Gram-Schmidt
29
- * lattices: Hadamard ratio, Babai rounding/nearest plane algorithm, lattice reduction (Hermite, Lenstra-Lenstra-Lovaz, BKZ), SIS, ISIS, LWE
29
+ * lattices: Hadamard ratio, Babai rounding/nearest plane algorithm, lattice reduction (Hermite, Lenstra-Lenstra-Lovasz, BKZ), SIS, ISIS, LWE
30
30
  * linear codes: Hamming distance, left standard form, parity check matrix
31
31
 
32
32
  * Matrix: a class for Matrices (inverse, det, reduced echelon form, kernel, solving linear systems, etc.)
33
33
  * BinaryMatrix: a class for Matrices with binary entries (for much faster row operations)
34
- * Lattice: a class for lattices (SVP, CPV, LLL, BKZ, HKZ)
34
+ * Lattice: a class for lattices (SVP, CVP, LLL, BKZ, HKZ)
35
35
  * Poly: a class for polynomials (division, modulo, factoring and irreducibility test over finite fields, Lagrange interpolation)
36
36
  * Zmod: a class for the ring of integers modulo an integer
37
37
  * GF2: a class for Galois fields GF(2^n)
@@ -3,9 +3,9 @@ Implemenation of same basic algorithms used in cryptography.
3
3
  """
4
4
 
5
5
  __author__ = "Gerald Teschl"
6
- __copyright__ = "Copyright 2024-2025, Gerald Teschl"
6
+ __copyright__ = "Copyright 2024-2026, Gerald Teschl"
7
7
  __license__ = "MIT License"
8
- __version__ = "1.9"
8
+ __version__ = "1.9.2"
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
@@ -16,7 +16,7 @@ from .dlp import dlog
16
16
  from .ec import EC_Weierstrass
17
17
  from .la import Matrix, zeros, eye, circulant, BinaryMatrix
18
18
  from .lat import Lattice, random_unimodular_matrix
19
- from .lat2 import q_ary_lattice, gram_det, hadamard_ratio, hermite_nf, gram_schmidt, babai_round_cvp, babai_round_bnd, babai_plane_cvp, babai_plane_bnd, lll, svp, cvp, sis, isis, sis_search, isis_search
19
+ from .lat2 import q_ary_lattice, gram_det, hadamard_ratio, hermite_nf, gram_schmidt, babai_round_cvp, babai_plane_cvp, babai_plane_bnd, lll, svp, cvp, sis, isis, sis_search, isis_search
20
20
  from .poly import Poly, PolyBinMult, lagrange_interpolation
21
21
  from .Zmod import Zmod
22
22
  from .GF2 import GF2, GF2_aes, GF2_miniaes, GF2_ghash
@@ -209,8 +209,7 @@ def divisors(n:int, proper:bool = False) -> int:
209
209
  i = 0
210
210
  d = prod(primes[i] ** exponents[i] for i in range(nprimes))
211
211
  if d == n:
212
- if proper:
213
- return divisor_list
214
- divisor_list.append(n)
212
+ if not proper:
213
+ divisor_list.append(n)
215
214
  return divisor_list
216
215
  divisor_list.append(d)
@@ -1079,7 +1079,7 @@ class BinaryMatrix:
1079
1079
  n = 0
1080
1080
  for bit in b:
1081
1081
  n <<= 1
1082
- n += bit
1082
+ n += int(bit)
1083
1083
  return n
1084
1084
 
1085
1085
  def bitmatrix(self) -> list[list]:
@@ -205,7 +205,7 @@ class Lattice():
205
205
  print(f"Total number of steps: {steps}")
206
206
 
207
207
  def hnf(self) -> None:
208
- "Transform the basis into Hermite normal form.."
208
+ "Transform the basis into Hermite normal form."
209
209
  if self.Uhnf is None:
210
210
  self.Uhnf = self.basis().hnf().matrix
211
211
  self.Us = None
@@ -237,7 +237,7 @@ class Lattice():
237
237
  self.N[j] = Fraction(self.N[j])
238
238
  self.Us_end = end + 1
239
239
 
240
- def size_reduce(self, j: int) -> bool:
240
+ def size_reduce_one(self, j: int) -> bool:
241
241
  "Size reduction at index `j`."
242
242
  self.gsd(j)
243
243
  reduced = False
@@ -251,6 +251,14 @@ class Lattice():
251
251
  self.M[j][k] -= r * self.M[i][k]
252
252
  return reduced
253
253
 
254
+ def size_reduce(self) -> bool:
255
+ "Size reduction at all indices."
256
+ reduced = False
257
+ for j in range(self.len):
258
+ if self.size_reduce_one(j):
259
+ reduced = True
260
+ return reduced
261
+
254
262
  def swap(self, j:int, newN1 = None) -> None:
255
263
  "Swap columns j and j-1 and update the Gram-Schmidt decomposition."
256
264
  self.U[j - 1], self.U[j] = self.U[j], self.U[j - 1]
@@ -296,7 +304,7 @@ class Lattice():
296
304
  steps = 0
297
305
  while j < self.len:
298
306
  steps += 1
299
- if self.size_reduce(j) and verbose:
307
+ if self.size_reduce_one(j) and verbose:
300
308
  print(f"Reduced basis vector {j}")
301
309
  if all(self.U[j][l] == 0 for l in range(self.dim)):
302
310
  if verbose:
@@ -372,7 +380,7 @@ class Lattice():
372
380
  c = lat.svp_enum(coordinates = True, reduce = False)
373
381
  uu = lat.basis() * c
374
382
  if uu.norm2() == lat.norm2(lat.U[0]):
375
- if self.size_reduce(start):
383
+ if self.size_reduce_one(start):
376
384
  changed = True
377
385
  continue
378
386
  # the new vector is shorter
@@ -2,7 +2,7 @@
2
2
  Lattice tools 2
3
3
  """
4
4
 
5
- from math import prod, floor, inf
5
+ from math import prod, inf
6
6
  from itertools import product
7
7
  from .la import Matrix, eye
8
8
  from .lat import Lattice
@@ -12,7 +12,6 @@ def hermite_nf(M: Matrix) -> Matrix:
12
12
  "Compute the Hermite normal form of a matrix M."
13
13
  return M.hnf()
14
14
 
15
-
16
15
  def gram_schmidt(U: Matrix, drop_dependent: bool = True) -> (Matrix, Matrix):
17
16
  "Compute the Gram-Schmidt orthogonalization of the column vectors of a matrix M."
18
17
  M = U.eye(U.cols)
@@ -36,30 +35,22 @@ def gram_schmidt(U: Matrix, drop_dependent: bool = True) -> (Matrix, Matrix):
36
35
  M = M[:-jj,:-jj]
37
36
  return Us, M
38
37
 
39
-
40
38
  def gram_det(U: Matrix) -> float:
41
39
  "Compute the Gram determinant of a matrix."
42
40
  Us = gram_schmidt(U, drop_dependent = False)[0]
43
41
  return prod([Us[:, i].norm() for i in range(U.rows)])
44
42
 
45
-
46
43
  def hadamard_ratio(M: Matrix) -> float:
47
44
  "Compute the Hadamard ratio of a matrix."
48
45
  m = M.rows
49
46
  return (gram_det(M) / prod([M[:, i].norm() for i in range(m)])) ** (1 / m)
50
47
 
51
-
52
48
  def babai_round_cvp(x: Matrix, U: Matrix) -> Matrix:
53
49
  "Babai's rounding algorithm for approximately solving the CVP."
54
50
  s = U.inv() * x
55
51
  k = s.applyfunc(round)
56
52
  return U * k
57
53
 
58
- def babai_round_bnd(U: Matrix) -> float:
59
- "Bound for Babai's rounding algorithm for solving the CVPwith respect to the sup norm."
60
- return floor(1 / (2 * max(U.inv()[i, :].norm(1) for i in range(U.rows))))
61
-
62
-
63
54
  def babai_plane_cvp(x: Matrix, U: Matrix) -> Matrix:
64
55
  "Babai's closest plane algorithm for approximately solving the CVP."
65
56
  Us = gram_schmidt(U)[0]
@@ -68,7 +59,6 @@ def babai_plane_cvp(x: Matrix, U: Matrix) -> Matrix:
68
59
  y = y - round(y.dot(Us[:, k]) / Us[:, k].norm2()) * U[:, k]
69
60
  return (x - y).applyfunc(round)
70
61
 
71
-
72
62
  def babai_plane_bnd(U: Matrix, p=2) -> float:
73
63
  "Bound for Babai's closest plane algorithm for solving the CVP with respect to the Euclidean norm (p=2) or sup norm (p=inf)."
74
64
  Us = gram_schmidt(U)[0]
@@ -142,6 +142,8 @@ class Poly:
142
142
  except: # pylint: disable=W0702
143
143
  pass
144
144
  try:
145
+ if hasattr(s, "ring") and hasattr(s.ring, "sharp") and s.ring.sharp:
146
+ s = s.sharp()
145
147
  if plus and s < 0:
146
148
  tmp += " - " + str(-s)
147
149
  if i != 0:
@@ -225,9 +227,11 @@ class Poly:
225
227
  return self.__class__(list(map(func, self.coeff)), modulus = self.modulus, cyclic = self.cyclic)
226
228
 
227
229
  def _check_type(self, other):
230
+ "Check if self and other can be added/multiplied."
228
231
  return isinstance(other, int) or (isinstance(other, Number) and isinstance(self.coeff[0], Number)) or type(other) == type(self.coeff[0]) # pylint: disable=C0123
229
232
 
230
233
  def _guess_ring(self):
234
+ "Try to guess from which the ring the coefficients are."
231
235
  zero = 0 * self.coeff[0]
232
236
  one = zero**0
233
237
  if hasattr(zero, "ring"):
@@ -241,6 +245,7 @@ class Poly:
241
245
  return zero, one, ring
242
246
 
243
247
  def _guess_field(self):
248
+ "Try to guess from which field the coefficients are."
244
249
  zero, one, field = self._guess_ring()
245
250
  if not field:
246
251
  raise ValueError(
@@ -251,7 +256,7 @@ class Poly:
251
256
  if not field.is_field():
252
257
  raise ValueError(
253
258
  "The polynomial does not seem to be over a finite field.")
254
- else: # G2 or galois
259
+ else: # GF2 or galois
255
260
  p = field.characteristic
256
261
  q = field.order
257
262
  return field, zero, one, q, p
@@ -293,13 +298,13 @@ class Poly:
293
298
  return (- self) + other
294
299
 
295
300
  def __mul__(self, other: "Poly") -> "Poly":
301
+ zero = 0 * self.coeff[0]
296
302
  if not isinstance(other, self.__class__):
297
303
  if self._check_type(other):
298
304
  if not other:
299
- return self.__class__([other], modulus = self.modulus, cyclic = self.cyclic, check = False)
305
+ return self.__class__([zero], modulus = self.modulus, cyclic = self.cyclic, check = False)
300
306
  return self.__class__([other * s for s in self.coeff], modulus = self.modulus, cyclic = self.cyclic, check = False)
301
307
  return NotImplemented
302
- zero = 0 * self.coeff[0]
303
308
  ls, lo = len(self.coeff), len(other.coeff)
304
309
  if self.cyclic or other.cyclic:
305
310
  if self.cyclic:
@@ -319,8 +324,8 @@ class Poly:
319
324
  if cyclic > 0:
320
325
  coeff = [ sum( (selfc[j] * otherc[(k-j) % n] for j in range(ls)), start = zero) for k in range(n)]
321
326
  else:
322
- coeff = [ sum( (selfc[j] * otherc[(k-j) % n] for j in range(min(k,ls))), start = zero) -
323
- sum( (selfc[j] * otherc[(k-j) % n] for j in range(k,ls)), start = zero) for k in range(n)]
327
+ coeff = [ sum( (selfc[j] * otherc[k - j] for j in range(min(k+1,ls))), start = zero) -
328
+ sum( (selfc[j] * otherc[n + k - j] for j in range(k+1,ls)), start = zero) for k in range(n)]
324
329
  ret = self.__class__(coeff, modulus = modulus, cyclic = cyclic, check = False)
325
330
  ret.strip()
326
331
  return ret
@@ -521,6 +526,7 @@ class Poly:
521
526
  if r0.degree() != 0:
522
527
  raise ValueError(f"{self} is not invertible mod {other}.")
523
528
  y0.modulus = self.modulus
529
+ y0.cyclic = self.cyclic
524
530
  if r0.coeff[0] == one:
525
531
  return y0
526
532
  return y0 / r0.coeff[0]
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: kryptools
3
- Version: 1.9
3
+ Version: 1.9.2
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
@@ -44,12 +44,12 @@ The tools contained are:
44
44
  * integer factorization (Fermat, Pollard p-1, Pollard rho, Lenstra's ECM, Dixon, basic quadratic sieve)
45
45
  * elliptic curves (Weierstrass form), group operations, order, discrete logarithms
46
46
  * linear algebra: Hermite normal form, Smith normal form, Gram-Schmidt
47
- * lattices: Hadamard ratio, Babai rounding/nearest plane algorithm, lattice reduction (Hermite, Lenstra-Lenstra-Lovaz, BKZ), SIS, ISIS, LWE
47
+ * lattices: Hadamard ratio, Babai rounding/nearest plane algorithm, lattice reduction (Hermite, Lenstra-Lenstra-Lovasz, BKZ), SIS, ISIS, LWE
48
48
  * linear codes: Hamming distance, left standard form, parity check matrix
49
49
 
50
50
  * Matrix: a class for Matrices (inverse, det, reduced echelon form, kernel, solving linear systems, etc.)
51
51
  * BinaryMatrix: a class for Matrices with binary entries (for much faster row operations)
52
- * Lattice: a class for lattices (SVP, CPV, LLL, BKZ, HKZ)
52
+ * Lattice: a class for lattices (SVP, CVP, LLL, BKZ, HKZ)
53
53
  * Poly: a class for polynomials (division, modulo, factoring and irreducibility test over finite fields, Lagrange interpolation)
54
54
  * Zmod: a class for the ring of integers modulo an integer
55
55
  * GF2: a class for Galois fields GF(2^n)
@@ -1,6 +1,6 @@
1
1
  [project]
2
2
  name = "kryptools"
3
- version = "1.9"
3
+ version = "1.9.2"
4
4
  authors = [
5
5
  { name="Gerald Teschl", email="gerald.teschl@univie.ac.at" },
6
6
  ]
@@ -21,17 +21,24 @@ def test_Poly():
21
21
  assert q * p == p.gcd(q) * p.lcm(q)
22
22
  assert d * p + m == q
23
23
  for _ in range(num_tests):
24
- p = Poly([randint(0,100) for _ in range(10)])
25
- q = Poly([randint(0,100) for _ in range(12)])
26
- x = randint(0,100)
24
+ p = Poly([randint(-100,100) for _ in range(10)])
25
+ q = Poly([randint(-100,100) for _ in range(12)])
26
+ x = randint(-100,100)
27
27
  assert p(x) == sum((c * x**j for j, c in enumerate(p.coeff)), start=0)
28
28
  assert (p + q)(x) == p(x) + q(x)
29
29
  assert (p - q)(x) == p(x) - q(x)
30
30
  assert (p*q)(x) == p(x) * q(x)
31
- modulus = [-1] + 7 * [0] + [1]
32
- p = [ randint(0,9) for _ in range(8) ]
33
- q = [ randint(0,9) for _ in range(8) ]
34
- assert list(circulant(p) * Matrix(q)) == (Poly(p, modulus = modulus) * Poly(q, modulus = modulus)).coeff
31
+ n = 8
32
+ modulus = [-1] + (n-1) * [0] + [1]
33
+ for _ in range(num_tests):
34
+ p = [ randint(-9,9) for _ in range(n) ]
35
+ q = [ randint(-9,9) for _ in range(n) ]
36
+ assert list(circulant(p) * Matrix(q)) == (Poly(p, modulus = modulus) * Poly(q, modulus = modulus)).coeff
37
+ modulus = [1] + (n-1) * [0] + [1]
38
+ for _ in range(num_tests):
39
+ p = [ randint(-9,9) for _ in range(n) ]
40
+ q = [ randint(-9,9) for _ in range(n) ]
41
+ assert Poly(p) * Poly(q) % Poly(modulus) == (Poly(p, modulus = modulus) * Poly(q, modulus = modulus))
35
42
  gf = Zmod(5)
36
43
  p = Poly([2, 0, 2], ring = gf)
37
44
  q = Poly([1, 2, 3, 4], ring = gf)
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
File without changes
File without changes
File without changes
File without changes