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

1 Expert Approved Answer
Step: 1 Unlock blur-text-image
Question Has Been Solved by an Expert!

Get step-by-step solutions from verified subject matter experts

Step: 2 Unlock
Step: 3 Unlock

Students Have Also Explored These Related Databases Questions!