From 8b4ce090ca968080101a4c2e1f44c14ffc9984b2 Mon Sep 17 00:00:00 2001 From: vis4rd Date: Tue, 16 Jan 2024 17:30:21 +0100 Subject: [PATCH] Add lab13 --- lab13/zad1.py | 55 +++++++++++++++++++++++++++++++++++++++++++++++++++ lab13/zad2.py | 52 ++++++++++++++++++++++++++++++++++++++++++++++++ lab13/zad3.py | 51 +++++++++++++++++++++++++++++++++++++++++++++++ 3 files changed, 158 insertions(+) create mode 100644 lab13/zad1.py create mode 100644 lab13/zad2.py create mode 100644 lab13/zad3.py diff --git a/lab13/zad1.py b/lab13/zad1.py new file mode 100644 index 0000000..df93715 --- /dev/null +++ b/lab13/zad1.py @@ -0,0 +1,55 @@ +# Aleksander Kluczka + +import random + +# wynik: +# 561 - z +# 1729 - z +# 6601 - z +# 881 - p +# 9677 - p +# 17371 - p +# 37579 - p + + +def witness(a, n): + t, u = 0, n - 1 + while u % 2 == 0: + t += 1 + u //= 2 + assert t >= 1 + assert u % 2 == 1 + assert n - 1 == pow(2, t) * u + x_0 = pow(a, u, n) + x_i1 = x_0 + for _ in range(t): + x_i = pow(x_i1, 2, n) + if (x_i == -1) and (x_i1 != 1) and (x_i1 != (n - 1)): + return True + x_i1 = x_i + + if x_i != 1: + return True + return False + + +def miller_rabin(n, s): + for j in range(s): + a = random.randint(1, n - 1) + if witness(a, n): + return False + return True + + +def zad1(): + input = [561, 1729, 6601, 881, 9677, 17321, 37579] + for number in input: + print(f"{number} - {'p' if miller_rabin(number, 50) else 'z'}") + + +def main(): + zad1() + + +if __name__ == "__main__": + main() diff --git a/lab13/zad2.py b/lab13/zad2.py new file mode 100644 index 0000000..4710b49 --- /dev/null +++ b/lab13/zad2.py @@ -0,0 +1,52 @@ +# Aleksander Kluczka + + +def nwd_expanded(j, k): + if j == 0: + return k, 0, 1 + r = k % j + d, xp, yp = nwd_expanded(r, j) + x = yp - (k // j) * xp + y = xp + return d, x, y + + +def pollard_p_minus_1(n: int, b: int) -> int | None: + a: int = 2 + for j in range(2, b + 1): + a = pow(a, j, n) + d: int = nwd_expanded(a - 1, n)[0] + if 1 < d < n: + return d + else: + return None + + +def pollard_p_minus_1_with_search(n: int) -> tuple[int, int]: + b = 2 + result = None + while True: + result = pollard_p_minus_1(n, b) + if result is not None: + break + b += 1 + return result, b + + +def zad2(): + number_1 = 262063 + number_2 = 9420457 + + result_1, b_1 = pollard_p_minus_1_with_search(number_1) + print(f"pollard_p1({number_1}) = {result_1}, minimum b = {b_1}") + + result_2, b_2 = pollard_p_minus_1_with_search(number_2) + print(f"pollard_p1({number_2}) = {result_2}, minimum b = {b_2}") + + +def main(): + zad2() + + +if __name__ == "__main__": + main() diff --git a/lab13/zad3.py b/lab13/zad3.py new file mode 100644 index 0000000..0f979ba --- /dev/null +++ b/lab13/zad3.py @@ -0,0 +1,51 @@ +# Aleksander Kluczka + +from typing import Callable + + +def nwd_expanded(j: int, k: int) -> tuple[int, int, int]: + if j == 0: + return k, 0, 1 + r: int = k % j + d, xp, yp = nwd_expanded(r, j) + x: int = yp - (k // j) * xp + y: int = xp + return d, x, y + + +def pollard_rho(n: int, x1: int, f_x: Callable) -> tuple[int | None, int]: + x: int = x1 + xp: int = f_x(x) % n + p: int = nwd_expanded(abs(x - xp), n)[0] + iter: int = 0 + while p == 1: + iter += 1 + x = f_x(x) % n + xp = f_x(xp) % n + xp = f_x(xp) % n + p = nwd_expanded(abs(x - xp), n)[0] + print(f"pollard_rho({n}, {x1}) = {p} * {n // p}, iter = {iter}") + print(f" x_{iter} = {x}, x_{iter *2} = {xp}") + if p == n: + return None, iter + else: + return p, iter + + +def zad3(): + number_1 = 262063 + number_2 = 9420457 + number_3 = 181937053 + func = lambda x: x**2 + 1 + + pollard_rho(number_1, 1, func) + pollard_rho(number_2, 1, func) + pollard_rho(number_3, 1, func) + + +def main(): + zad3() + + +if __name__ == "__main__": + main()