Reputation: 3
I created a small code for testing RSA, but when I try to decrypt a message with keys that are 6-7 digit long, it takes a while and gives me the wrong result.
from math import sqrt
def isPrime(n):
x = int(sqrt(n)) + 1
if n < 2:
return False`
for i in range(2, x):
if (n / i).is_integer():
return (i, False
return True
def factor(num):
hold = list()
inum = int(sqrt(num) + 1)
hold.append((1, num))
if num % 2 == 0: hold.append((2, int(num / 2)))
for i in range(3, inum, 2):
x = num / i
if x.is_integer():
hold.append((i, int(x)))
return hold
def egcd(a, b):
#Extended Euclidean Algorithm
x,y, u,v = 0,1, 1,0
while a != 0:
q, r = b//a, b%a
m, n = x-u*q, y-v*q
b,a, x,y, u,v = a,r, u,v, m,n
gcd = b
return y
def fastMod(n, e):
if e == 0:
return 1
if e % 2 == 1:
return n * fastMod(n, e - 1)
p = fastMod(n, e / 2)
return p * p
def decrypt(p, q, em):
#Uses CRT for decrypting
mp = em % p; mq = em % q;
dp = d % (p-1); dq = d % (q-1);
xp = fastMod(mp, dp) % p; xq = fastMod(mq, dq) % q
log = egcd(p, q)
cp = (p-log) if log > 0 else (p+log)
cq = cp
m = (((q*cp)*xp) + ((p*cq)*xq)) % n
return m
def encrypt(pm):
return fastMod(pm, e) % n
Is there any way to improve speed or fix any errors? I try to decrypt a few messages I made with a key 9-10 digits long, but it takes too long.
Upvotes: 0
Views: 506
Reputation: 6629
A lot of things need improvement, but most notably:
fastMod( )
should take the modulus as an input parameter, and reduce by the modulus each iteration. I found this code which illustrates the right way to do it.isPrime( )
to determine primality because it runs in exponential time. Instead, you should be doing Miller-Rabin / Strong pseudo prime tests, which can use fastMod( )
as a sub-routine.By the way, you are implementing textbook RSA here, which is hugely insecure. You would need to use padding such as OAEP to have security, but you need to be very careful on how you implement that to prevent various forms of attacks (such as side channel attacks).
As for why you are getting the wrong result, it is hard to tell without seeing all of your code. Maybe you want to include a main
function that generates params and tries to use them for encryption and decryption.
EDIT: I did notice this which looks suspicious: log = egcd(p, q)
. Not sure what you are doing here. I suggest you first compute d
as the inverse of e
mod (p-1)*(q-1)
and verify that you are getting that correct (ie multiply d*e
mod (p-1)*(q-1)
and make sure the result is 1). If so, then do a fastMod( )
with d
to see if it decrypts (it should). Once you get that working, then move on to making CRT work.
Upvotes: 1