Question: Please explain what each line in the following program does : import random import math import argparse import re KEY_INT = 100 # define the
Please explain what each line in the following program does :
import random
import math
import argparse
import re
KEY_INT = 100 # define the near max value
def main():
parser = argparse.ArgumentParser(__file__, description="RSA Encryption in Python")
parser.add_argument("--generate", '-g', help = 'Generate a Public and private Key', action='store_true')
parser.add_argument("--encode", '-e', help = 'Encode message', action='store', dest='public_key')
parser.add_argument("--decode", '-d', help = 'Decode message', action='store', dest='private_key')
parser.add_argument("--message", '-m', help = 'Encoded or decoded message', action='store', dest='message')
args=parser.parse_args()
#print if no argument is parsed
if not any([args.generate, args.public_key, args.private_key]):
parser.print_usage()
quit()
#check if g is in argument
elif args.generate and not any(([args.public_key, args.private_key, args.message])):
print_keys()
quit()
# check if encode message is correct
elif all([args.public_key, args.message]) and not args.generate:
print (" Encrypted message ")
#split the string to get n and e
n, e = re.findall(r'\d+', args.public_key)
print(encrypt(args.message,(n,e)))
print (" === Output written to file ===")
quit()
# check if decode message is correct
elif all([args.private_key, args.message]) and not args.generate:
print (" Decrypted message ")
#split the string to get n and d regexp
n, d = re.findall(r'\d+', args.private_key)
try:
print(decrypt(args.message,(n,d)))
except:
print("Decoding error!, check key")
print (" === Output written to file ===")
quit()
else:
parser.print_help()
quit()
# display the key(private and public)
print_keys()
# get input from user
print (encrypt(65,(1457, 719)))
print (decrypt(486,(1457, 119)))'''
def miller_rabin_prime(n):
num_trials = 5
assert n >= 2
if n == 2:
return True
if n % 2 == 0:
return False
s = 0
d = n-1
while True:
quotient, remainder = divmod(d, 2)
if remainder == 1:
break
s += 1
d = quotient
assert(2**s * d == n-1) # make sure 2**s*d = n-1
# test whether it is a witness for the compositeness of n
def try_composite(a):
if pow(a, d, n) == 1: # defined as pow(x, y) % z = 1
return False
for i in range(s):
if pow(a, 2**i * d, n) == n-1:
return False
return True # definitely composite n
for i in range(num_trials):
a = random.randrange(2, n)
if try_composite(a):
return False
return True
def compute_pqnt():
# generate primes p and q
try:
p = findAPrime(2, KEY_INT)
while True:
q = findAPrime(2, KEY_INT)
if q != p:
break
except:
raise ValueError
#compute for n
n = p * q
# get the totient
t = (p-1) * (q-1)
#print (t)
# return p, q, n and the totient
return(p, q, n, t)
def findAPrime(a, b):
x = random.randint(a, b)
for i in range(0, int(10 * math.log(x) + 3)):
if miller_rabin_prime(x):
return x
else:
x += 1
raise ValueError
def coprime(a):
while True:
co_p = findAPrime(1, a) # find a prime number
# make surethe gcd is 1
g, x, y = extended_gcd(co_p, a)
# g is the remainder (last)
if co_p < a and g == 1:
break
return co_p
def compute_e(t):
e = coprime(t)
return e
def compute_d(e, t):
d = modinv(e, t)
return d
def extended_gcd(aa, bb):
lastremainder, remainder = abs(aa), abs(bb)
x, lastx, y, lasty = 0, 1, 1, 0
while remainder:
lastremainder, (quotient, remainder) = remainder, divmod(lastremainder, remainder) # get the remainder and quotient
x, lastx = lastx - quotient*x, x
y, lasty = lasty - quotient*y, y
return lastremainder, lastx * (-1 if aa < 0 else 1), lasty * (-1 if bb < 0 else 1)
def modinv(a, m):
g, x, y = extended_gcd(a, m)
if g != 1:
raise ValueError
return x % m
def print_keys():
print (" Public Key (n, e)")
p, q, n, t = compute_pqnt()
e = compute_e(t)
#public key is printed
print ((n,e))
print (" Private Key (n, d)")
d = compute_d(e, t)
# private key is printed
print ((n,d))
def encrypt(msg, public_key):
n, e = public_key
n = int(n)
e = int(e)
encrypted = ''
for i in range(len(msg)):
# pick each char and convert to ascii
int_msg = ord(msg[i])
encrypted += str(pow(int_msg,e) % n)+ " "
# Encoded message written in file
f = open('encoded.txt','w')
f.write(encrypted)
f.close()
return encrypted
def decrypt(msg, private_key):
n, d = private_key
n = int(n)
d = int(d)
decrypted = ''
# split each number with space
asc_msg = msg.split(" ")
for num in asc_msg:
# convert to integer
num = int(num)
try:
# decode back to ascii
decrypted += str(chr(pow(num,d) % n))
except:
# cannot decode this
decrypted += str("?")
# Decoded message written in file
f = open('decoded.txt','w')
f.write(decrypted)
f.close()
return decrypted
if __name__ == '__main__':
main()
Step by Step Solution
There are 3 Steps involved in it
Get step-by-step solutions from verified subject matter experts
