85 lines
2.4 KiB
Python
85 lines
2.4 KiB
Python
#!/usr/bin/env python3
|
|
|
|
def gcd(a, b):
|
|
"""
|
|
This function calculate the GCD (Greatest Common Divisor of the number a of b
|
|
Args:
|
|
a (Integer): the number a
|
|
b (integer): the number b
|
|
|
|
Return:
|
|
the GCD
|
|
"""
|
|
|
|
if b == 0:
|
|
return a
|
|
return gcd(b, a%b)
|
|
|
|
def egcd(a, b):
|
|
"""
|
|
This function compute the Extended Euclidean algorithm
|
|
https://user.eng.umd.edu/~danadach/Cryptography_20/ExtEuclAlg.pdf
|
|
https://en.wikipedia.org/wiki/Extended_Euclidean_algorithm
|
|
|
|
Args:
|
|
a (Integer): the number a
|
|
b (Integer): the number b
|
|
"""
|
|
if a == 0:
|
|
return b, 0, 1
|
|
gcd, x1, y1 = egcd(b % a, a)
|
|
x = y1 - (b // a) * x1
|
|
y = x1
|
|
return gcd, x, y
|
|
|
|
def bin_expo(n, e) -> int:
|
|
"""
|
|
This function perform an binary exponentiation, also known as Exponentiation squaring.
|
|
A binary exponentiation is the process for computing an integer power of a number, such as a ** n.
|
|
For doing that, the first step is to convert the exponent into a binary representation
|
|
And for each 1 bit, we compute the exponent.
|
|
|
|
Args:
|
|
n (Integer): it's the base
|
|
e (Integer): it's the exponent
|
|
|
|
Returns:
|
|
Return the result of the exponentation of n ** e
|
|
|
|
"""
|
|
binary = bin(e)[2:] # Remove the prefix 0b
|
|
|
|
r = 1
|
|
exp = 1
|
|
# We need to reverse, and to start from the right to left
|
|
# Otherwise, we do on left to the right
|
|
# It's dirty, maybe we can find another way to do that
|
|
for b in binary[::-1]:
|
|
if b == '1':
|
|
r *= n ** exp
|
|
print(n ** exp, exp)
|
|
exp *= 2
|
|
return r
|
|
|
|
def exponent_squaring(n, e):
|
|
"""
|
|
This function perform an exponentiation squaring, which compute an integer power of a number based on the following algorithm:
|
|
n ** e = {
|
|
1 # if n is 0
|
|
(n ** (e / 2)) ** 2 # if n is even
|
|
((n ** (e - 1 / 2)) ** 2) * n # if n is odd
|
|
}
|
|
|
|
Args:
|
|
n (Integer): n is the base of n ** e
|
|
e (Integer): e is the exponent
|
|
"""
|
|
if e < 0:
|
|
return exponent_squaring(1 / n, -e)
|
|
elif e == 0:
|
|
return 1
|
|
elif e % 2 == 1: # n is odd
|
|
return exponent_squaring(n * n, (e - 1) / 2) * n
|
|
elif e % 2 == 0: # n is even
|
|
return exponent_squaring(n * n, e / 2)
|