#!/usr/local/bin/perl -s-- #export-a-crypto-system sig, RSA in 4 lines PERL: # # -d (decrypt) # or -e (encrypt) # # $k is exponent, $n is modulus; $k and $n in hex # # use of -s was contributed by Jeff Friedl, a cool perl hacker # # the $e-$d (grok that? awesome hack by Jeff also) checks for -d or -e: # # when perl -s sets $x for -x so that means $d is set for -d, $e for -e # if they are both set 1-1 = 0 so it fails if neither are set it fails # and if either one is set we're ok! This is to get around using | , # as | has higher precedence than & things group wrongly. # $e-$d&(($k,$n)=@ARGV)==2||die"$0 -d|-e key mod out\n"; # # $v will be the digits of output per block, $w the digits of input per block. # If encrypting need to reduce $w so input is guaranteed to be less than # modulus; for decrypting reduce $v to match. # # blocks are based on modulus size in hex digits rounded up to nearest even # length (~1&1+length$n) so that things will unpack properly # $v=$w=1+length$n&~1; $v-=$d*2:$w-=$e*2; # # Make $_ be the exponent $k as a binary bit string # # Add a leading 0 to make length of $k be even so that it will fill # Bytes when packed as 2 digits per byte # $_=unpack('B*',pack('H*',1&length$k?"0$k":$k)); # # strip leading 0's from $_ # s/^0+//; # # Turn every 0 into "d*ln%", every 1 into "d*ln%lm*ln%". These are dc codes # which construct an exponentiation algorithm for that exponent. # "d*ln%" is duplicate, square, load n, modulus; e.g. square the number # on the stack, mod n. "d*ln%lm*ln%" does this then, load m, multiply, # load n, modulus; e.g. then multiply by m mod n. This is the square and # multiply algorithm for modular exponentiation. # # (Kudos to Hal for shortened this one by 4 chars) # s/1/0lM*ln%/g; s/0/d*ln%/g; # # Encryption/decryption loop. Read $w/2 bytes of data to $m. # while(read(STDIN,$m,$w/2)){ # # Turn data into equivalent hex digits in $m # $m=unpack("H$w",$m); # # Run dc: 16 bit radix for input and output; $m into dc register "M"; # $n into dc register "n"; execute $_, the exponentiation program above. # "\U...\E" forces upper case on the hex digits as dc requires. # Put the result in $e. # $a=`echo 16oOi\U$m SM$n\Esn1$_ p|dc`; # # Pad the result with leading 0's to $v digits, pack to raw data and output. # print pack("H$v",'0'x($v+1-length$a).$a); }