The quest for the most diminutive munitions program

There have been a number of revisions of the RSA in perl hack as people have contributed ways to shorten it. Here are the interesting ones, the smallest and most recent first:

Current best, perl5 and dc

Currently there is no explanation for this one, but is similar to the 3 line version in the way that it works, see below.
print pack"C*",split/\D+/,`echo "16iII*o\U@{$/=$z;[(pop,pop,unpack"H*",<> )]}\EsMsKsN0[lN*1lK[d2%Sa2/d0<X+d*lMLa^*lN%0]dsXx++lMlN/dsM0<J]dsJxp"|dc`

Previous best, works with perl4 and dc

There is an explanation of how this works in detail.
#!/bin/perl -sp0777i<X+d*lMLa^*lN%0]dsXx++lMlN/dsM0<j]dsj $/=unpack('H*',$_);$_=`echo 16dio\U$k"SK$/SM$n\EsN0p[lN*1 lK[d2%Sa2/d0$^Ixp"|dc`;s/\W//g;$_=pack('H*',/((..)*)$/)

Prior to that

(this one is the one on many T-shirts, and the one in the tattoo):
#!/bin/perl -s-- -export-a-crypto-system-sig -RSA-3-lines-PERL $m=unpack(H.$w,$m."\0"x$w),$_=`echo "16do$w 2+4Oi0$d*-^1[d2%Sa 2/d0<X+d*La1=z\U$n%0]SX$k"[$m*]\EszlXx++p|dc`,s/^.|\W//g,print pack('H*',$_)while read(STDIN,$m,($w=2*$d-1+length$n&~1)/2)

Original version which started the trend

9 March 1995 The original version which started this trend of perl crypto hacks.

An explanation of how this one works was posted to the cypherpunks list by Hal Finney shortly after I posted it.


#!/usr/local/bin/perl -- export-a-crypto-system sig, RSA in 5 lines of PERL: ($s,$k,$n)=@ARGV;$w=length$n;$k="0$k"if length($k)&1;$n="0$n",$w++if$w&1;die "$0 -d|-e key mod <in >out\n"if$s!~/^-[de]$/||$#ARGV<2;$v=$w;$s=~/d/?$v-=2: $w-=2;$_=unpack('B*',pack('H*',$k));s/^0*//g;s/0/d*ln%/g;s/1/d*ln%lm*ln%/g; $c="1${_}p";while(read(STDIN,$m,$w/2)){$m=unpack("H$w",$m);chop($a= `echo 16o16i\U$m\Esm\U$n\Esn$c|dc`);print pack('H*','0'x($v-length$a).$a);}

Pure perl version

Pure perl version by Clifford Adams in 5 lines of perl.
#!/usr/local/bin/perl -s do 'bigint.pl';($_,$n)=@ARGV;s/^.(..)*$/0$&/;($k=unpack('B*',pack('H*',$_)))=~ s/^0*//;$x=0;$z=$n=~s/./$x=&badd(&bmul($x,16),hex$&)/ge;while(read(STDIN,$_,$w =((2*$d-1+$z)&~1)/2)){$r=1;$_=substr($_."\0"x$w,$c=0,$w);s/.|\n/$c=&badd(&bmul ($c,256),ord$&)/ge;$_=$k;s/./$r=&bmod(&bmul($r,$r),$x),$&?$r=&bmod(&bmul($r,$c ),$x):0,""/ge;($r,$t)=&bdiv($r,256),$_=pack(C,$t).$_ while$w--+1-2*$d;print}
Comments, html bugs to me (Adam Back) at <adam@cypherspace.org>