SHA in 8 lines of perl5

SHA1 (Secure Hash Algorithm 1) is a cryptographic message digest algorithm. It is considered to be more secure than MD5, as it has longer hash size, and because Hans Dobbertin discovered a partial weakness in the MD5 collision function. (There was a SHA0 but it had some security problems which were fixed in SHA1).

SHA1 was designed by NIST and the NSA. SHA1 is specified in NIST Federal Information Processing standard FIPS 180-1.

John Allen <allen@grumman.com> wrote this implementation of SHA optimised for size, in 8 lines of perl5:


#!/usr/bin/perl -iD9T4C`>_-JXF8NMS^$#)4=L/2X?!:@GF9;MGKH8\;O-S*8L'6 @A=unpack"N*",unpack u,$^I;@K=splice@A,5,4;sub M{($x=pop)-($m=1+~0)*int$x/$m}; sub L{$n=pop;($x=pop)<<$n|2**$n-1&$x>>32-$n}@F=(sub{$b&($c^$d)^$d},$S=sub{$b^$c ^$d},sub{($b|$c)&$d|$b&$c},$S);do{$l+=$r=read STDIN,$_,64;$r++,$_.="\x80"if$r< 64&&!$p++;@W=unpack N16,$_."\0"x7;$W[15]=$l*8 if$r<57;for(16..79){push@W,L$W[$_ -3]^$W[$_-8]^$W[$_-14]^$W[$_-16],1}($a,$b,$c,$d,$e)=@A;for(0..79){$t=M&{$F[$_/ 20]}+$e+$W[$_]+$K[$_/20]+L$a,5;$e=$d;$d=$c;$c=L$b,30;$b=$a;$a=$t}$v='a';@A=map{ M$_+${$v++}}@A}while$r>56;printf'%.8x'x5 ."\n",@A

SHA creates a 160 bit hash (five 32 bit ints), which is designed so that it should be computationaly expensive to find a text which matches a given hash. ie if you have a hash for document A, H(A), it is difficult to find a document B which has the same hash, and even more difficult to arrange that document B says what you want it to say.

Example

For example here is how to use John's SHA implementation: % echo -n abc | sha1 a9993e364706816aba3e25717850c26c9cd0d89d output is in hex. (The SHA1 hash of string "abc" is one of the standard test vectors.) As expected the hash of a message differing by only one letter produces an entirely different hash: % echo -n abd | sha cb4cc28df0fdbe0ecf9d9662e294b118092a5735

Hashes are used (amongst other things) in digital signatures, it is common to digitally sign a hash of a message rather than the whole message. This is what the block of text at the bottom of a PGP/GPG clearsigned document is when DSA is used, the SHA1 digest of the message, signed with the authors private DSA key.

John also wrote an MD5 in few lines of perl5.


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