-- Copyright (C) 2001, 2004 Ian Lynagh <igloo@earth.li>---- This program is free software; you can redistribute it and/or modify-- it under the terms of the GNU General Public License as published by-- the Free Software Foundation; either version 2, or (at your option)-- any later version.---- This program is distributed in the hope that it will be useful,-- but WITHOUT ANY WARRANTY; without even the implied warranty of-- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the-- GNU General Public License for more details.---- You should have received a copy of the GNU General Public License-- along with this program; see the file COPYING. If not, write to-- the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,-- Boston, MA 02110-1301, USA.-- name shadowing disabled because a,b,c,d,e are shadowed loads in step 4{-# OPTIONS_GHC -fno-warn-name-shadowing #-}{-# LANGUAGE CPP #-}-- |-- Module : SHA1-- Copyright : 2001, 2004 Ian Lynagh <igloo@earth.li>-- License : GPL-- Maintainer : darcs-devel@darcs.net-- Stability : experimental-- Portability : portablemoduleSHA1(sha1PS)whereimportByteStringUtils(unsafeWithInternals)importqualifiedData.ByteStringasB(ByteString,pack,length,concat)importData.Char(intToDigit)importData.Bits(xor,(.&.),(.|.),complement,rotateL,shiftL,shiftR)importData.Word(Word8,Word32)importForeign.Ptr(Ptr,castPtr)importForeign.Marshal.Array(advancePtr)importForeign.Storable(peek,poke)importSystem.IO.Unsafe(unsafePerformIO)dataABCDE=ABCDE!Word32!Word32!Word32!Word32!Word32dataXYZ=XYZ!Word32!Word32!Word32sha1PS::B.ByteString->Stringsha1PSs=s5wheres1_2=sha1Step12PadLengthsabcde=sha1Step3Initabcde'=unsafePerformIO$unsafeWithInternalss1_2(\ptrlen->doletptr'=castPtrptr#ifndef BIGENDIANfiddleEndiannessptr'len#endifsha1Step4Mainabcdeptr'len)s5=sha1Step5Displayabcde'fiddleEndianness::PtrWord32->Int->IO()fiddleEndiannessp0=p`seq`return()fiddleEndiannesspn=dox<-peekppokep$shiftLx24.|.shiftL(x.&.0xff00)8.|.(shiftRx8.&.0xff00).|.shiftRx24fiddleEndianness(p`advancePtr`1)(n-4)-- sha1Step12PadLength assumes the length is at most 2^61.-- This seems reasonable as the Int used to represent it is normally 32bit,-- but obviously could go wrong with large inputs on 64bit machines.-- The B.ByteString library should probably move to Word64s if this is an-- issue, though.sha1Step12PadLength::B.ByteString->B.ByteStringsha1Step12PadLengths=letlen=B.lengthsnum_nuls=(55-len)`mod`64padding=128:replicatenum_nuls0len_w8s=reverse$sizeSplit8(fromIntegrallen*8)inB.concat[s,B.packpadding,B.packlen_w8s]sizeSplit::Int->Integer->[Word8]sizeSplit0_=[]sizeSplitpn=fromIntegrald:sizeSplit(p-1)n'where(n',d)=divModn256sha1Step3Init::ABCDEsha1Step3Init=ABCDE0x674523010xefcdab890x98badcfe0x103254760xc3d2e1f0sha1Step4Main::ABCDE->PtrWord32->Int->IOABCDEsha1Step4Mainabcde_0=return$!abcdesha1Step4Main(ABCDEa0@ab0@bc0@cd0@de0@e)slen=do(e,b)<-doitf10x5a827999(x0)abcde(d,a)<-doitf10x5a827999(x1)eabcd(c,e)<-doitf10x5a827999(x2)deabc(b,d)<-doitf10x5a827999(x3)cdeab(a,c)<-doitf10x5a827999(x4)bcdea(e,b)<-doitf10x5a827999(x5)abcde(d,a)<-doitf10x5a827999(x6)eabcd(c,e)<-doitf10x5a827999(x7)deabc(b,d)<-doitf10x5a827999(x8)cdeab(a,c)<-doitf10x5a827999(x9)bcdea(e,b)<-doitf10x5a827999(x10)abcde(d,a)<-doitf10x5a827999(x11)eabcd(c,e)<-doitf10x5a827999(x12)deabc(b,d)<-doitf10x5a827999(x13)cdeab(a,c)<-doitf10x5a827999(x14)bcdea(e,b)<-doitf10x5a827999(x15)abcde(d,a)<-doitf10x5a827999(m16)eabcd(c,e)<-doitf10x5a827999(m17)deabc(b,d)<-doitf10x5a827999(m18)cdeab(a,c)<-doitf10x5a827999(m19)bcdea(e,b)<-doitf20x6ed9eba1(m20)abcde(d,a)<-doitf20x6ed9eba1(m21)eabcd(c,e)<-doitf20x6ed9eba1(m22)deabc(b,d)<-doitf20x6ed9eba1(m23)cdeab(a,c)<-doitf20x6ed9eba1(m24)bcdea(e,b)<-doitf20x6ed9eba1(m25)abcde(d,a)<-doitf20x6ed9eba1(m26)eabcd(c,e)<-doitf20x6ed9eba1(m27)deabc(b,d)<-doitf20x6ed9eba1(m28)cdeab(a,c)<-doitf20x6ed9eba1(m29)bcdea(e,b)<-doitf20x6ed9eba1(m30)abcde(d,a)<-doitf20x6ed9eba1(m31)eabcd(c,e)<-doitf20x6ed9eba1(m32)deabc(b,d)<-doitf20x6ed9eba1(m33)cdeab(a,c)<-doitf20x6ed9eba1(m34)bcdea(e,b)<-doitf20x6ed9eba1(m35)abcde(d,a)<-doitf20x6ed9eba1(m36)eabcd(c,e)<-doitf20x6ed9eba1(m37)deabc(b,d)<-doitf20x6ed9eba1(m38)cdeab(a,c)<-doitf20x6ed9eba1(m39)bcdea(e,b)<-doitf30x8f1bbcdc(m40)abcde(d,a)<-doitf30x8f1bbcdc(m41)eabcd(c,e)<-doitf30x8f1bbcdc(m42)deabc(b,d)<-doitf30x8f1bbcdc(m43)cdeab(a,c)<-doitf30x8f1bbcdc(m44)bcdea(e,b)<-doitf30x8f1bbcdc(m45)abcde(d,a)<-doitf30x8f1bbcdc(m46)eabcd(c,e)<-doitf30x8f1bbcdc(m47)deabc(b,d)<-doitf30x8f1bbcdc(m48)cdeab(a,c)<-doitf30x8f1bbcdc(m49)bcdea(e,b)<-doitf30x8f1bbcdc(m50)abcde(d,a)<-doitf30x8f1bbcdc(m51)eabcd(c,e)<-doitf30x8f1bbcdc(m52)deabc(b,d)<-doitf30x8f1bbcdc(m53)cdeab(a,c)<-doitf30x8f1bbcdc(m54)bcdea(e,b)<-doitf30x8f1bbcdc(m55)abcde(d,a)<-doitf30x8f1bbcdc(m56)eabcd(c,e)<-doitf30x8f1bbcdc(m57)deabc(b,d)<-doitf30x8f1bbcdc(m58)cdeab(a,c)<-doitf30x8f1bbcdc(m59)bcdea(e,b)<-doitf20xca62c1d6(m60)abcde(d,a)<-doitf20xca62c1d6(m61)eabcd(c,e)<-doitf20xca62c1d6(m62)deabc(b,d)<-doitf20xca62c1d6(m63)cdeab(a,c)<-doitf20xca62c1d6(m64)bcdea(e,b)<-doitf20xca62c1d6(m65)abcde(d,a)<-doitf20xca62c1d6(m66)eabcd(c,e)<-doitf20xca62c1d6(m67)deabc(b,d)<-doitf20xca62c1d6(m68)cdeab(a,c)<-doitf20xca62c1d6(m69)bcdea(e,b)<-doitf20xca62c1d6(m70)abcde(d,a)<-doitf20xca62c1d6(m71)eabcd(c,e)<-doitf20xca62c1d6(m72)deabc(b,d)<-doitf20xca62c1d6(m73)cdeab(a,c)<-doitf20xca62c1d6(m74)bcdea(e,b)<-doitf20xca62c1d6(m75)abcde(d,a)<-doitf20xca62c1d6(m76)eabcd(c,e)<-doitf20xca62c1d6(m77)deabc(b,d)<-doitf20xca62c1d6(m78)cdeab(a,c)<-doitf20xca62c1d6(m79)bcdealetabcde'=ABCDE(a0+a)(b0+b)(c0+c)(d0+d)(e0+e)sha1Step4Mainabcde'(s`advancePtr`16)(len-64)where{-# INLINE f1 #-}f1(XYZxyz)=(x.&.y).|.((complementx).&.z){-# INLINE f2 #-}f2(XYZxyz)=x`xor`y`xor`z{-# INLINE f3 #-}f3(XYZxyz)=(x.&.y).|.(x.&.z).|.(y.&.z){-# INLINE x #-}xn=peek(s`advancePtr`n){-# INLINE m #-}mn=doletbase=s`advancePtr`(n.&.15)x0<-peekbasex1<-peek(s`advancePtr`((n-14).&.15))x2<-peek(s`advancePtr`((n-8).&.15))x3<-peek(s`advancePtr`((n-3).&.15))letres=rotateL(x0`xor`x1`xor`x2`xor`x3)1pokebaseresreturnres{-# INLINE doit #-}doitfkiabcde=a`seq`c`seq`doi'<-ireturn(rotateLa5+f(XYZbcd)+e+i'+k,rotateLb30)sha1Step5Display::ABCDE->Stringsha1Step5Display(ABCDEabcde)=concatMapshowAsHex[a,b,c,d,e]showAsHex::Word32->StringshowAsHexn=showIt8n""whereshowIt::Int->Word32->String->StringshowIt0_r=rshowItixr=casequotRemx16of(y,z)->letc=intToDigit(fromIntegralz)inc`seq`showIt(i-1)y(c:r)