Skip to content

Removed redundant greatest_common_divisor code #9358

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 12 commits into from
Oct 9, 2023
Merged
32 changes: 4 additions & 28 deletions blockchain/diophantine_equation.py
Original file line number Diff line number Diff line change
@@ -1,11 +1,13 @@
from __future__ import annotations

from maths.greatest_common_divisor import greatest_common_divisor


def diophantine(a: int, b: int, c: int) -> tuple[float, float]:
"""
Diophantine Equation : Given integers a,b,c ( at least one of a and b != 0), the
diophantine equation a*x + b*y = c has a solution (where x and y are integers)
iff gcd(a,b) divides c.
iff greatest_common_divisor(a,b) divides c.

GCD ( Greatest Common Divisor ) or HCF ( Highest Common Factor )

Expand All @@ -22,7 +24,7 @@ def diophantine(a: int, b: int, c: int) -> tuple[float, float]:

assert (
c % greatest_common_divisor(a, b) == 0
) # greatest_common_divisor(a,b) function implemented below
) # greatest_common_divisor(a,b) is in maths directory
(d, x, y) = extended_gcd(a, b) # extended_gcd(a,b) function implemented below
r = c / d
return (r * x, r * y)
Expand Down Expand Up @@ -69,32 +71,6 @@ def diophantine_all_soln(a: int, b: int, c: int, n: int = 2) -> None:
print(x, y)


def greatest_common_divisor(a: int, b: int) -> int:
"""
Euclid's Lemma : d divides a and b, if and only if d divides a-b and b

Euclid's Algorithm

>>> greatest_common_divisor(7,5)
1

Note : In number theory, two integers a and b are said to be relatively prime,
mutually prime, or co-prime if the only positive integer (factor) that
divides both of them is 1 i.e., gcd(a,b) = 1.

>>> greatest_common_divisor(121, 11)
11

"""
if a < b:
a, b = b, a

while a % b != 0:
a, b = b, a % b

return b


def extended_gcd(a: int, b: int) -> tuple[int, int, int]:
"""
Extended Euclid's Algorithm : If d divides a and b and d = a*x + b*y for integers
Expand Down
154 changes: 0 additions & 154 deletions blockchain/modular_division.py

This file was deleted.

6 changes: 4 additions & 2 deletions ciphers/affine_cipher.py
Original file line number Diff line number Diff line change
@@ -1,6 +1,8 @@
import random
import sys

from maths.greatest_common_divisor import gcd_by_iterative

from . import cryptomath_module as cryptomath

SYMBOLS = (
Expand All @@ -26,7 +28,7 @@ def check_keys(key_a: int, key_b: int, mode: str) -> None:
"Key A must be greater than 0 and key B must "
f"be between 0 and {len(SYMBOLS) - 1}."
)
if cryptomath.gcd(key_a, len(SYMBOLS)) != 1:
if gcd_by_iterative(key_a, len(SYMBOLS)) != 1:
sys.exit(
f"Key A {key_a} and the symbol set size {len(SYMBOLS)} "
"are not relatively prime. Choose a different key."
Expand Down Expand Up @@ -76,7 +78,7 @@ def get_random_key() -> int:
while True:
key_b = random.randint(2, len(SYMBOLS))
key_b = random.randint(2, len(SYMBOLS))
if cryptomath.gcd(key_b, len(SYMBOLS)) == 1 and key_b % len(SYMBOLS) != 0:
if gcd_by_iterative(key_b, len(SYMBOLS)) == 1 and key_b % len(SYMBOLS) != 0:
return key_b * len(SYMBOLS) + key_b


Expand Down
7 changes: 2 additions & 5 deletions ciphers/cryptomath_module.py
Original file line number Diff line number Diff line change
@@ -1,11 +1,8 @@
def gcd(a: int, b: int) -> int:
while a != 0:
a, b = b % a, a
return b
from maths.greatest_common_divisor import gcd_by_iterative


def find_mod_inverse(a: int, m: int) -> int:
if gcd(a, m) != 1:
if gcd_by_iterative(a, m) != 1:
msg = f"mod inverse of {a!r} and {m!r} does not exist"
raise ValueError(msg)
u1, u2, u3 = 1, 0, a
Expand Down
14 changes: 1 addition & 13 deletions ciphers/hill_cipher.py
Original file line number Diff line number Diff line change
Expand Up @@ -39,19 +39,7 @@

import numpy


def greatest_common_divisor(a: int, b: int) -> int:
"""
>>> greatest_common_divisor(4, 8)
4
>>> greatest_common_divisor(8, 4)
4
>>> greatest_common_divisor(4, 7)
1
>>> greatest_common_divisor(0, 10)
10
"""
return b if a == 0 else greatest_common_divisor(b % a, a)
from maths.greatest_common_divisor import greatest_common_divisor


class HillCipher:
Expand Down
4 changes: 3 additions & 1 deletion ciphers/rsa_key_generator.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,8 @@
import random
import sys

from maths.greatest_common_divisor import gcd_by_iterative

from . import cryptomath_module, rabin_miller


Expand All @@ -27,7 +29,7 @@ def generate_key(key_size: int) -> tuple[tuple[int, int], tuple[int, int]]:
# Generate e that is relatively prime to (p - 1) * (q - 1)
while True:
e = random.randrange(2 ** (key_size - 1), 2 ** (key_size))
if cryptomath_module.gcd(e, (p - 1) * (q - 1)) == 1:
if gcd_by_iterative(e, (p - 1) * (q - 1)) == 1:
break

# Calculate d that is mod inverse of e
Expand Down
11 changes: 2 additions & 9 deletions maths/carmichael_number.py
Original file line number Diff line number Diff line change
Expand Up @@ -10,14 +10,7 @@
Examples of Carmichael Numbers: 561, 1105, ...
https://en.wikipedia.org/wiki/Carmichael_number
"""


def gcd(a: int, b: int) -> int:
if a < b:
return gcd(b, a)
if a % b == 0:
return b
return gcd(b, a % b)
from maths.greatest_common_divisor import greatest_common_divisor


def power(x: int, y: int, mod: int) -> int:
Expand All @@ -33,7 +26,7 @@ def power(x: int, y: int, mod: int) -> int:
def is_carmichael_number(n: int) -> bool:
b = 2
while b < n:
if gcd(b, n) == 1 and power(b, n - 1, n) != 1:
if greatest_common_divisor(b, n) == 1 and power(b, n - 1, n) != 1:
return False
b += 1
return True
Expand Down
22 changes: 2 additions & 20 deletions maths/least_common_multiple.py
Original file line number Diff line number Diff line change
@@ -1,6 +1,8 @@
import unittest
from timeit import timeit

from maths.greatest_common_divisor import greatest_common_divisor


def least_common_multiple_slow(first_num: int, second_num: int) -> int:
"""
Expand All @@ -20,26 +22,6 @@ def least_common_multiple_slow(first_num: int, second_num: int) -> int:
return common_mult


def greatest_common_divisor(a: int, b: int) -> int:
"""
Calculate Greatest Common Divisor (GCD).
see greatest_common_divisor.py
>>> greatest_common_divisor(24, 40)
8
>>> greatest_common_divisor(1, 1)
1
>>> greatest_common_divisor(1, 800)
1
>>> greatest_common_divisor(11, 37)
1
>>> greatest_common_divisor(3, 5)
1
>>> greatest_common_divisor(16, 4)
4
"""
return b if a == 0 else greatest_common_divisor(b % a, a)


def least_common_multiple_fast(first_num: int, second_num: int) -> int:
"""
Find the least common multiple of two numbers.
Expand Down
Loading