Python export-a-crypto-system

Andrew Kuchling <amk@magnet.com> wrote Python versions of the perl export-a-crypto-system sig. Python (in case you don't know) is another interpreted scripting language. An advantage of python is that it has built-in bigints :-)

On more serious applications, Andrew also wrote a Python Cryptography Toolkit. See his home page for docs, and source for PCT

Here is the README file from the curiosa directory of the crypto toolkit, it contains his python export-a-crypto-system code also, plus an explanation.

Here is Andrew's second post to comp.lang.python of his python codes, with a few optimisations (of the size kind by others) added, also I put in his newer rc4.py, the original post expected an ascii key, this one expects a hex key:


From: fnord@maggie.cs.mcgill.ca (Andrew KUCHLING) Newsgroups: comp.lang.python Subject: Re: Obfuscated Python Date: 6 Jul 1995 14:20:13 GMT Following modifications from Richard Jones and Guido van Rossum, we've now achieved a 4-line RSA script. (Shouldn't we all be doing some *real* work, I wonder? :) ) I've added a 2-line one-time pad program, which simply XORs the contents of the two files whose names are provided on the command line. Generation of random data (and securely exchanging it with your correspondent) is left as an exercise for the reader. So, the Python export-a-crypto-system-sigs are: Try: echo 'This is a test.' | rsa.py 10001 1967cb529 #!/usr/local/bin/python -- -export-a-crypto-system-sig -RSA-in-4-lines-Python from sys import*;from string import*;a=argv;[s,p,q]=filter(lambda x:x[:1]!= '-',a);d='-d'in a;e,n=atol(p,16),atol(q,16);l=(len(q)+1)/2;o,inb=l-d,l-1+d while s:s=stdin.read(inb);s and map(stdout.write,map(lambda i,b=pow(reduce( lambda x,y:(x<<8L)+y,map(ord,s)),e,n):chr(b>>8*i&255),range(o-1,-1,-1))) Try: echo 'This is a test.' | rc4.py messagekey #!/usr/local/bin/python -- -export-a-crypto-system-sig -RC4-in-5-lines-Python from sys import*;from string import *;t,x,y,j,s,a=range(256),0,0,0,1,argv[1] k=(map(lambda b:atoi(a[b:b+2],16), range(0,len(a),2))*256)[:256] for i in t[:]:j=(k[i]+t[i]+j)%256;t[i],t[j]=t[j],t[i] while(s):s=stdin.read(1);l,x=len(s),(x+1)%256;y,c=(y+t[x])%256,l and ord(s);( t[x],t[y])=t[y],t[x];stdout.write(chr(c^t[(t[x]+t[y])%256])[:l]) Try: otp.py message pad >ciphertext #!/usr/local/bin/python -- -export-a-crypto-system-sig -OTP-in-2-lines-Python from sys import*;t=p=1;s,i,j=stdout,open(argv[1], 'r'),open(argv[2], 'r') while(t and p):t,p=i.read(1),j.read(1);t and p and s.write(chr(ord(t)^ord(p))) Andrew Kuchling andrewk@cst.ca fnord@cs.mcgill.ca (http://www.cs.mcgill.ca/~fnord)

They are compatible with the perl versions, and can be mixed like this:

% echo squeamish ossifrage | rsa.py 3 7537d365 | rsa.pl -d 4e243e33 7537d365

Both cope with arbitrary sized RSA keys, and the Python code is considerably faster than the perl code due to the built-in bigints in python being faster than dc which is shelled in the perl version.

In fact from a purist point of view, the perl code is in fact perl and dc code as dc is called as a separate utility, and although dc is shipped with most unix systems, it is kind of a hack. Andrew's Python version doesn't suffer from this short-coming as it uses the builtin in python bigint, and pow() function.


Comments, html bugs to me (Adam Back) at <adam@cypherspace.org>