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>