Skip to content

Commit a12afb5

Browse files
committed
use gmpy for all calcs, speed up RSA private key op
ensure that gmpy is used for all calculations in RSA, it speeds up private key operations by about 5%
1 parent 9fe875c commit a12afb5

File tree

1 file changed

+35
-16
lines changed

1 file changed

+35
-16
lines changed

tlslite/utils/python_rsakey.py

Lines changed: 35 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,8 @@
77
from .rsakey import *
88
from .pem import *
99
from .deprecations import deprecated_params
10+
if gmpyLoaded:
11+
from gmpy import mpz
1012

1113
class Python_RSAKey(RSAKey):
1214
def __init__(self, n=0, e=0, d=0, p=0, q=0, dP=0, dQ=0, qInv=0,
@@ -16,6 +18,15 @@ def __init__(self, n=0, e=0, d=0, p=0, q=0, dP=0, dQ=0, qInv=0,
1618
see also generate() and parsePEM()."""
1719
if (n and not e) or (e and not n):
1820
raise AssertionError()
21+
if gmpyLoaded:
22+
n = mpz(n)
23+
e = mpz(e)
24+
d = mpz(d)
25+
p = mpz(p)
26+
q = mpz(q)
27+
dP = mpz(dP)
28+
dQ = mpz(dQ)
29+
qInv = mpz(qInv)
1930
self.n = n
2031
self.e = e
2132
if p and not q or not p and q:
@@ -48,44 +59,46 @@ def hasPrivateKey(self):
4859
return self.d != 0
4960

5061
def _rawPrivateKeyOp(self, message):
62+
n = self.n
5163
with self._lock:
5264
# Create blinding values, on the first pass:
5365
if not self.blinder:
54-
self.unblinder = getRandomNumber(2, self.n)
55-
self.blinder = powMod(invMod(self.unblinder, self.n), self.e,
56-
self.n)
66+
self.unblinder = getRandomNumber(2, n)
67+
self.blinder = powMod(invMod(self.unblinder, n), self.e,
68+
n)
5769
unblinder = self.unblinder
5870
blinder = self.blinder
5971

6072
# Update blinding values
61-
self.blinder = (self.blinder * self.blinder) % self.n
62-
self.unblinder = (self.unblinder * self.unblinder) % self.n
73+
self.blinder = (blinder * blinder) % n
74+
self.unblinder = (unblinder * unblinder) % n
6375

6476
# Blind the input
65-
message = (message * blinder) % self.n
77+
message = (message * blinder) % n
6678

6779
# Perform the RSA operation
6880
cipher = self._rawPrivateKeyOpHelper(message)
6981

7082
# Unblind the output
71-
cipher = (cipher * unblinder) % self.n
83+
cipher = (cipher * unblinder) % n
7284

7385
# Return the output
7486
return cipher
7587

7688
def _rawPrivateKeyOpHelper(self, m):
7789
#Non-CRT version
78-
#c = powMod(m, self.d, self.n)
79-
80-
#CRT version (~3x faster)
81-
s1 = powMod(m, self.dP, self.p)
82-
s2 = powMod(m, self.dQ, self.q)
83-
h = ((s1 - s2) * self.qInv) % self.p
84-
c = s2 + self.q * h
90+
#c = pow(m, self.d, self.n)
91+
92+
#CRT version (~3x faster).
93+
p, q = self.p, self.q
94+
s1 = pow(m, self.dP, p)
95+
s2 = pow(m, self.dQ, q)
96+
h = ((s1 - s2) * self.qInv) % p
97+
c = s2 + q * h
8598
return c
8699

87100
def _rawPublicKeyOp(self, ciphertext):
88-
msg = powMod(ciphertext, self.e, self.n)
101+
msg = pow(ciphertext, self.e, self.n)
89102
return msg
90103

91104
def acceptsPassword(self):
@@ -101,9 +114,15 @@ def generate(bits, key_type="rsa"):
101114
key = Python_RSAKey()
102115
p = getRandomPrime(bits//2, False)
103116
q = getRandomPrime(bits//2, False)
117+
if gmpyLoaded:
118+
p = mpz(p)
119+
q = mpz(q)
104120
t = lcm(p-1, q-1)
105121
key.n = p * q
106-
key.e = 65537
122+
if gmpyLoaded:
123+
key.e = mpz(65537)
124+
else:
125+
key.e = 65537
107126
key.d = invMod(key.e, t)
108127
key.p = p
109128
key.q = q

0 commit comments

Comments
 (0)