-
Notifications
You must be signed in to change notification settings - Fork 0
/
run_RSA.py
145 lines (110 loc) · 5.66 KB
/
run_RSA.py
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
#
# File: run_RSA.py
# Author: Alexander Craig
# Project: An Analysis of the Security of RSA & Elliptic Curve Cryptography
# Supervisor: Maximilien Gadouleau
# Version: 2.2
# Date: 06/04/19
#
# Functionality: utilises other programs to generate and subsequently break RSA
# keys using a variety of algorithms, while collecting diagnostics
# to compare and check the results of each of these algorithms
#
# Instructions: used to run all other files to be run from the command line:
#
# CLI: python3 run_RSA.py -h (to see possible flags)
#
############ IMPORTS #########
# needed for pydocs to correctly find everything
import sys
sys.path.append('Programming/')
import argparse
from RSA import *
############ FUNCTIONS #########
def runSolver(keys, solver, name, verbose):
""" runs a check on the solver, given the correct keys """
if verbose:
print("="*10, name, "="*10)
solver.solve() # factor n
if verbose:
if solver.d == keys.d: # check for correctness
print("Success!")
else:
print("Fail!")
return {"res": (solver.d == keys.d), # return result as dict
"time": solver.time,
"count": solver.count}
############ MASTER PROGRAM #########
def run(k = 10, brute = True, ferm = True, pRho = True, knj = True, pMinus = True, quad = True, verbose = True):
""" creates a k-bit RSA key, cracks it with several algorithms, and generates
statistics to compare their performance """
############ KEY GENERATION #########
if verbose:
print("\n" + "="*10, "GENERATING", "="*10)
keys = generate_RSA.KeyGen(k, verbose) # create new instance
sanity = keys.generateKeys() # get key and primes
if not sanity:
if verbose:
print ("Please fix input and try again")
return False
############ BRUTE FORCE ATTACK #########
bf_res = {}
if brute:
bf = brute_force.BFSolver(keys.n, keys.e, verbose) # create new instance with public key info
bf_res = runSolver(keys, bf, "BRUTE FORCE", verbose) # check solver
############ FERMAT'S FACTORISATION METHOD #########
fer_res = {}
if ferm:
fer = fermats.FFSolver(keys.n, keys.e, verbose) # create new instance with public key info
fer_res = runSolver(keys, fer, "FERMAT'S METHOD", verbose) # check solver
############ POLLARD'S RHO ATTACK #########
rho_res = {}
if pRho:
rho = pollard_rho.RhoSolver(keys.n, keys.e, verbose) # create new instance with public key info
rho_res = runSolver(keys, rho, "POLLARD'S RHO", verbose) # check solver
############ KNJ FACTORISATION #########
knj_res = {}
if knj:
knjSol = knj_factorisation.KNJSolver(keys.n, keys.e, verbose) # create new instance with public key info
knj_res = runSolver(keys, knjSol, "KNJ FACTORISATION", verbose) # check solver
############ POLLARD'S P - 1 ATTACK #########
minus_res = {}
if pMinus:
polMin = pollard_p_minus_1.PSolver(keys.n, keys.e, verbose) # create new instance with public key info
minus_res = runSolver(keys, polMin, "POLLARD'S P-1", verbose) # check solver
############ QUADRATIC SIEVE METHOD #########
quad_sieve = {}
if quad:
quadS = quadratic_sieve.QSolver(keys.n, keys.e, verbose) # create new instance with public key info
quad_sieve = runSolver(keys, quadS, "QUADRATIC SIEVE", verbose) # check solver
return bf_res, fer_res, rho_res, knj_res, minus_res, quad_sieve
def test(k = 50):
""" tries to find failure point """
res = {}
res['res'] = True
# loop till fail
while res['res']:
res = run(k, False, False, False, False, False, True, verbose = True)[-1]
############ COMMAND LINE INTERFACE #########
if __name__ == '__main__':
parser = argparse.ArgumentParser()
parser.add_argument("-v", "--verbose", help="turns output off", action="store_true")
parser.add_argument("-k", "--bitsize", help="bitlength of public key", action="store", type=int, default=10)
parser.add_argument("-bf", "--bruteforce", help="turns bruteforce decryption on", action="store_true")
parser.add_argument("-ff", "--fermats", help="turns fermats decryption on", action="store_true")
parser.add_argument("-pr", "--pollard_rho", help="turns pollard_rho decryption on", action="store_true")
parser.add_argument("-knj", "--KNJ_factorisation", help="turns KNJ_factorisation decryption on", action="store_true")
parser.add_argument("-pp", "--pollard_p_minus_1", help="turns pollard_p_minus_1 decryption on", action="store_true")
parser.add_argument("-qs", "--quadratic_sieve", help="turns quadratic_sieve decryption on", action="store_true")
parser.add_argument("-a", "--all", help="turns all on", action="store_true")
parser.add_argument("-t", "--test", help="runs failure test", action="store_true")
args = parser.parse_args()
if args.test:
test(args.bitsize)
elif len(sys.argv) == 1:
# default run
run()
elif args.all:
run(args.bitsize, True, True, True, True, True, True, not args.verbose)
else:
run(args.bitsize, args.bruteforce, args.fermats, args.pollard_rho, args.KNJ_factorisation, args.pollard_p_minus_1, args.quadratic_sieve, not args.verbose)