-export-a-crypto-system-sig -RSA-3-lines-PERL
#!/bin/perl -sp0777i msg.rsa
% rsa -d -k=ac363601 -n=1967cb529 < msg.rsa
it will generate keys up to 1024 bits. to send encrypted email with it,
try this:
% rsa -k=[e] -n=[n] | uuencode "filename" | mail -s "subject" email_addy
ex.
rsa -k=13
-n=b487306fc179f3bd5e55a9e7c5737722dc97ec4326838b67de814638214988cd
90416ff55fee783c32aacc55f2b90c073c69344f5a4d9a6fb3f90770ffe6a78084bbae3f2c
77fe14b70e0db894b063e01f91e169591ec2b5da7bf2a0427b7bd77bfa97129e9cfe10768b
919f05728e7484949bf29de83b6a9fe7f36ea2de58b5 |
uuencode "perl-rsa-mail" | mail -s "rsa mail" jkwilli2@unity.ncsu.edu
and finally, here is the commented version:
#!/usr/local/bin/perl -s-- -export-a-crypto-system-sig
-RSA-in-3-lines-PERL
#
# -d (decrypt)
# or -e (encrypt) [this is now optional ie rsa k n < in > out will
# assume -e]
#
# $k is exponent, $n is modulus; $k and $n in hex
#
# use of -s (and $w-=$d*2; below) was contributed by Jeff Friedl
# a cool perl hacker
#
# Things have got a bit more obfuscated in that last re-write
# couldn't be helped tho' we wanted the usage string and 3 lines
#
# Ken Pizzini contributed the excellent redundancy of -e, the way it works
# is that you can still use -e if you want, it is just redundant.
#
# $v is the digits of output per block (or it would be if I hadn't
# eliminated it to save another couple of bytes), $w is the hex digits
# per input block.
#
# If encrypting need to reduce $w so input is guaranteed to be less than
# modulus; for decrypting reduce $v to match.
#
# Adam Roach contributed a rearrangement of the $v and $w calculation
# which shaves off 4 bytes! Its been juggled around a bit by Ken Pizzini
# (for precedence prob) but no-ones managed to shorten it yet.
#
# $v=2-4*$d+($w=2*$d-1+length$n&~1);
#
# also, now its been split up into parts for the $v elimination you should
# recognize it in 2 halves scattered around in obfuscated places for
# optimal byte count reduction. (part of it has now even moved into the
# dc
# string to save another couple of bytes, +2 for Ken)
# Encryption/decryption loop. Data to encrypt/decrypt in $m
#
# The whole of the next lot is inside a loop, the while appears at the end
# of 4 comma separated cmds like this:
#
# cmd1,cmd2,cmd3,cmd4 while expr;
#
# which is perfectly legal in perl.
#
# This saves 4 chars over the more conventional while(expr){cmd1;...cmd6;}
#
#
# Travis Kuhn came up with the idea that the arg decoding (used to say
# ($k,$n)=@ARGV;) could be left out entirely, if you used this syntax
# for calling the program:
#
# rsa [-d] -k=123 -n=567
#
# This works because, when you do -d perl sets the variable $d, and
# apparently (cool news to me), when you do: -x=exp perl sets the variable
# $x to equal expression exp.
#
# saves a whole 14 bytes!
#
#
# Turn data into equivalent hex digits in $m
#
# The ."\0"x$w is the bug fix, (it adds way too many ascii(0)s but the
# surplus don't matter as H.$w just takes as many as required, saves space
# to not bother working out how many.
#
# This fixes a bug which manifested itself in the last block of the
# plain text if the file to encrypt was not a whole multiple of $w.
# Also it was not generally noticed as it just put ascii(0)s on the wrong
# end of the block and most shells eat ascii(0)s silently.
#
$m=unpack(H.$w,$m."\0"x$w),
#
# Did have Ken Pizzini's awesome:
#
# $_=`echo 16i2o\U$k\Ep|dc`,s/\W//g,
#
# which shaved of a cool 16 chars in one swoop, and enabled
# the move to 3 lines (by chucking the usage string on bad args)
#
# Also I used to have:
#
# s/1/d*ln%lM*ln%/g,
# s/0/d*ln%/g,
#
# a cool contribution from Hal Finney shortened this by 4 chars to:
#
# s/1/0lM*ln%/g,
# s/0/d*ln%/g,
#
# this was improved on even more by Chris Barker with the fiendishly
# clever:
#
# s/./d*lM$&^*ln%/g,
#
# However, I've re-written a big chunk in dc, so Ken's, Hal's, and Chris's
# improvements have been replaced, the work of doing the binary conversion
# has been re-written in dc and incorporated into this single dc command
# which does the binary conversion, and the modular exponentiation in one
# swoop.
#
# Since the re-write Ken, and Chris have found more shortcuts (Ken's
# solution
# was adopted in the final twist as the additional 7 bytes I found
# couldn't be
# applied as well to Chris's initially winning variation)
#
# There was some very clever juggling (the strange looking 16i1Io and the
# first ") by Ken which finally got the last 4 bytes working.
#
# The lastest dc command:
# "16do$w
# 2+4Oi0$d*-^1[d2%Sa2/d0