146 lines
4.2 KiB
Python
146 lines
4.2 KiB
Python
import random
|
|
|
|
def extendedEuclidean(x, N):
|
|
A, B = N, x
|
|
U, V = 0, 1
|
|
while True:
|
|
q = A//B
|
|
temp1, temp2 = B, A + (-q * B)
|
|
A, B = temp1, temp2
|
|
temp1, temp2 = V, U + (-q * V)
|
|
U, V = temp1, temp2
|
|
if B == 0:
|
|
break
|
|
d, u = A, U
|
|
v = (d - x * u) // N
|
|
return (u, v, d)
|
|
|
|
print(extendedEuclidean(10,13))
|
|
|
|
# Zadanie 1
|
|
def generateRandomInteger(n, k):
|
|
try:
|
|
assert k > 0, "You need at least one bit to write an integer"
|
|
assert n > 0, "Cannot divide by 0"
|
|
if k == 1:
|
|
minValue = 0
|
|
maxValue = 1
|
|
else:
|
|
assert 2**(k-1) < n, "No numbers to choose from"
|
|
minValue = 2**(k-1)
|
|
maxValue = (2**k)-1
|
|
generator = random.SystemRandom()
|
|
while True:
|
|
randomNumber = generator.randint(minValue, maxValue)
|
|
if randomNumber < n:
|
|
break
|
|
print(randomNumber)
|
|
except AssertionError as error:
|
|
print("Error: {}".format(error))
|
|
main()
|
|
|
|
# Zadanie 2
|
|
def inverseValueInPhi(n, b):
|
|
value = 0
|
|
found = False
|
|
for i in range(1, n):
|
|
value = (i * b) % n
|
|
if value == 1:
|
|
if extendedEuclidean(n, value)[2] == 1:
|
|
found = True
|
|
value = i
|
|
break
|
|
if found:
|
|
print("Result: {}".format(value))
|
|
else:
|
|
print("Result: No inverse number exists")
|
|
|
|
# Zadanie 3
|
|
def exponentialSquaring(n, k, b):
|
|
temp = 1
|
|
while (k > 0):
|
|
if (k % 2 != 0):
|
|
temp = (temp * b) % n
|
|
b = (b * b) % n
|
|
k = k // 2
|
|
return(temp % n)
|
|
|
|
# Zadanie 4
|
|
def quadricResidue(p, b):
|
|
try:
|
|
assert p > 2, "p must be higher than 2"
|
|
if exponentialSquaring(p, (p-1)/2, b) == 1:
|
|
return True
|
|
else:
|
|
return False
|
|
except AssertionError as error:
|
|
print("Error: {}".format(error))
|
|
main()
|
|
|
|
# Zadanie 5
|
|
def squareRoot(p, b):
|
|
try:
|
|
assert p % 4 == 3, "p mod 4 != 3"
|
|
assert quadricResidue(p, b), "b is not a quadric residue in p"
|
|
print("{}" . format(p))
|
|
for i in range(0, p):
|
|
a = exponentialSquaring(p, (p+1)//4, i)
|
|
print("%d %d %d" % (i, a, b, ))
|
|
if a == b:
|
|
return("Result: {}".format(i))
|
|
return False
|
|
except AssertionError as error:
|
|
print("Error: {}".format(error))
|
|
main()
|
|
|
|
# Zadanie 6
|
|
def primalityTest(n):
|
|
if n == 1:
|
|
return False
|
|
if n == 2 or n == 3:
|
|
return True
|
|
generator = random.SystemRandom()
|
|
counter = generator.randint(n//2, n)
|
|
while(counter != 0):
|
|
b = generator.randint(2, n-2)
|
|
if exponentialSquaring(n, n-1, b) != 1:
|
|
return False
|
|
counter = counter - 1
|
|
return True
|
|
|
|
# User interface
|
|
def main():
|
|
while True:
|
|
print("""
|
|
Choose function:
|
|
Type "1 n k" for generateRandomInteger(n,k)
|
|
Type "2 n b" for inverseValueInPhi(n, b)
|
|
Type "3 n k b" for exponentialSquaring(n, k, b)
|
|
Type "4 p b" for quadricResidue(p, b)
|
|
Type "5 p b" for squareRoot(p,b)
|
|
Type "6 n" for primalityTest(n)
|
|
Type "exit" to end program's execution
|
|
""")
|
|
userInput = input("Choose desired action: ")
|
|
if userInput == "exit":
|
|
exit()
|
|
userInput = list(map(int, userInput.split(" ")))
|
|
if userInput[0] == 1:
|
|
for i in range(0, int(input("How many times to run the function?: "))):
|
|
generateRandomInteger(userInput[1], userInput[2])
|
|
elif userInput[0] == 2:
|
|
inverseValueInPhi(userInput[1], userInput[2])
|
|
elif userInput[0] == 3:
|
|
print("Result: {}".format(exponentialSquaring(userInput[1], userInput[2], userInput[3])))
|
|
elif userInput[0] == 4:
|
|
print("Result: {}".format(quadricResidue(userInput[1], userInput[2])))
|
|
elif userInput[0] == 5:
|
|
print(squareRoot(userInput[1], userInput[2]))
|
|
elif userInput[0] == 6:
|
|
print("Result: {}".format(primalityTest(userInput[1])))
|
|
else:
|
|
print("Error: Wrong instruction. Try again")
|
|
|
|
if __name__ == "__main__":
|
|
main()
|