Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- local uint32_lrot=_G'bit'.lrot
- local byte_xor=_G'bit'.bxor8
- local uint32_xor_3=_G'bit'.bxor
- local uint32_xor_4=_G'bit'.bxor
- local uint32_ternary=_G'bit'.ternary
- local uint32_majority=_G'bit'.majority
- local common={}
- -- Merges four bytes into a uint32 number.
- function common.bytes_to_uint32(a,b,c,d)
- return a*0x1000000+b*0x10000+c*0x100+d
- end
- -- Splits a uint32 number into four bytes.
- function common.uint32_to_bytes(a)
- local a4=a%256
- a=(a-a4)/256
- local a3=a%256
- a=(a-a3)/256
- local a2=a%256
- local a1=(a-a2)/256
- return a1,a2,a3,a4
- end
- local bytes_to_uint32=common.bytes_to_uint32
- local uint32_to_bytes=common.uint32_to_bytes
- local sbyte=string.byte
- local schar=string.char
- local sformat=string.format
- local srep=string.rep
- local function hex_to_binary(hex)
- return(hex:gsub('..',function(hexval)
- return schar(tonumber(hexval,16))
- end))
- end
- local sha1={}
- -- Calculates SHA1 for a string, returns it encoded as 40 hexadecimal digits.
- function sha1.sha1(str)
- -- Input preprocessing.
- -- First, append a `1` bit and seven `0` bits.
- local first_append=schar(0x80)
- -- Next, append some zero bytes to make the length of the final message a multiple of 64.
- -- Eight more bytes will be added next.
- local non_zero_message_bytes=#str+1+8
- local second_append=srep(schar(0),-non_zero_message_bytes%64)
- -- Finally, append the length of the original message in bits as a 64-bit number.
- -- Assume that it fits into the lower 32 bits.
- local third_append=schar(0,0,0,0,uint32_to_bytes(#str*8))
- str=str..first_append..second_append..third_append
- assert(#str%64==0)
- -- Initialize hash value.
- local h0=0x67452301
- local h1=0xefcdab89
- local h2=0x98badcfe
- local h3=0x10325476
- local h4=0xc3d2e1f0
- local w={}
- -- Process the input in successive 64-byte chunks.
- for chunk_start=1,#str,64 do
- -- Load the chunk into W[0..15] as uint32 numbers.
- local uint32_start=chunk_start
- for i=0,15 do
- w[i]=bytes_to_uint32(sbyte(str,uint32_start,uint32_start+3))
- uint32_start=uint32_start+4
- end
- -- Extend the input vector.
- for i=16,79 do
- -- For i = 16 to 79 let Wt = S1(Wt-3 XOR Wt-8 XOR Wt-14 XOR Wt-16).
- w[i]=uint32_lrot(uint32_xor_4(w[i-3],w[i-8],w[i-14],w[i-16]),1)
- end
- -- Initialize hash value for this chunk.
- local a=h0
- local b=h1
- local c=h2
- local d=h3
- local e=h4
- -- Main loop.
- for i=0,79 do
- local f
- local k
- if i<=19 then
- f=uint32_ternary(b,c,d)
- k=0x5a827999
- elseif i<=39 then
- f=uint32_xor_3(b,c,d)
- k=0x6ed9eba1
- elseif i<=59 then
- f=uint32_majority(b,c,d)
- k=0x8f1bbcdc
- else
- f=uint32_xor_3(b,c,d)
- k=0xca62c1d6
- end
- local temp=(uint32_lrot(a,5)+f+e+k+w[i])%0x100000000
- e=d
- d=c
- c=uint32_lrot(b,30)
- b=a
- a=temp
- end
- -- Add this chunk's hash to result so far.
- h0=(h0+a)%0x100000000
- h1=(h1+b)%0x100000000
- h2=(h2+c)%0x100000000
- h3=(h3+d)%0x100000000
- h4=(h4+e)%0x100000000
- end
- return sformat('%08x%08x%08x%08x%08x',h0,h1,h2,h3,h4)
- end
- sha1.new=sha1.sha1
- function sha1.binary(str)
- return hex_to_binary(sha1.sha1(str))
- end
- -- Precalculate replacement tables.
- local xor_with_0x5c={}
- local xor_with_0x36={}
- for i=0,0xff do
- xor_with_0x5c[schar(i)]=schar(byte_xor(0x5c,i))
- xor_with_0x36[schar(i)]=schar(byte_xor(0x36,i))
- end
- -- 512 bits.
- local BLOCK_SIZE=64
- function sha1.hmac(key,text)
- if#key>BLOCK_SIZE then
- key=sha1.binary(key)
- end
- local key_xord_with_0x36=key:gsub('.',xor_with_0x36)..srep(schar(0x36),BLOCK_SIZE-#key)
- local key_xord_with_0x5c=key:gsub('.',xor_with_0x5c)..srep(schar(0x5c),BLOCK_SIZE-#key)
- return sha1.sha1(key_xord_with_0x5c..sha1.binary(key_xord_with_0x36..text))
- end
- function sha1.hmac_binary(key,text)
- return hex_to_binary(sha1.hmac(key,text))
- end
- return sha1
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement