In the process, I learned a new simple Python fact: the
pow
function (which is now a built-in), can take a modulus as a third argument. And, it works where this doesn't seem to: (x**y) % z
(I discovered this by digging into the rsa module source).
python -m timeit -s "import rsa; \ f = open('id_rsa'); data = f.read(); f.close(); k = rsa.PrivateKey.load_pkcs1(data)"\ "41330915578951772302369**k.e % k.n" 10000 loops, best of 3: 79.4 usec per loop python -m timeit -s "import rsa; \ f = open('id_rsa'); data = f.read(); f.close(); k = rsa.PrivateKey.load_pkcs1(data)"\ "pow(41330915578951772302369, k.e, k.n)" 10000 loops, best of 3: 70.2 usec per loop |
In the example here, both work and have about the same timing. But in the code below, the first version hangs when doing decryption (with a large base). Here's the output, followed by the script.
> python encode.py m: Hello, secret world! p: .xyz.Hello, secret world!.xyz. a: 413309155789517723023698766343791993289928631329 c: 11434905702482726455415220687715293368262190253795 .. i: 413309155789517723023698766343791993289928631329 r: Hello, secret world! |
encode.py
import rsa with open('id_rsa') as f: data = f.read() k = rsa.PrivateKey.load_pkcs1(data) n = k.n e = k.e d = k.d def my_atoi(s): L = [ord(c) for c in s] k = 256 iL = L[:] iL.reverse() x = iL[0] for i in iL[1:]: x += i*k k *= 256 return x def my_itoa(i): rL = list() while i: rL.append(i%256) i = i/256 rL.reverse() return ''.join([chr(n) for n in rL]) def encrypt(m): return m**e % n def decrypt(c): # note: c**d % n fails return pow(c,d,n) if __name__ == '__main__': m = 'Hello, secret world!' pad = '.xyz.' p = pad + m + pad a = my_atoi(m) c = encrypt(a) i = decrypt(c) r = my_itoa(i) r = r.replace(pad,'') L = zip('mpacir',[m,p,a,c,i,r]) N = 50 for varname, var in L: s = str(var) print varname + ': ', s[:N], if len(s) > N: print '..' else: print |