SHARE
TWEET

SHA1

Anavrins Jun 4th, 2016 (edited) 45 Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
  1. -- SHA1 hash function in ComputerCraft
  2. -- By Anavrins
  3. -- For help and details, you can PM me on the CC forums
  4. -- You may use this code in your projects without asking me, as long as credit is given and this header is kept intact
  5. -- http://www.computercraft.info/forums2/index.php?/user/12870-anavrins
  6. -- http://pastebin.com/SfL7vxP3
  7. -- Last update: May 13, 2019
  8.  
  9. local mod32 = 2^32
  10. local band    = bit32 and bit32.band or bit.band
  11. local bor     = bit32 and bit32.bor or bit.bor
  12. local bnot    = bit32 and bit32.bnot or bit.bnot
  13. local bxor    = bit32 and bit32.bxor or bit.bxor
  14. local blshift = bit32 and bit32.lshift or bit.blshift
  15. local upack   = unpack
  16. local brshift = function(n, b)
  17.     local s = n/(2^b)
  18.     return s-s%1
  19. end
  20. local lrotate = function(n, b)
  21.     local s = n/(2^(32-b))
  22.     local f = s%1
  23.     return (s-f) + f*mod32
  24. end
  25.  
  26. local H = {
  27.     0x67452301,
  28.     0xefcdab89,
  29.     0x98badcfe,
  30.     0x10325476,
  31.     0xc3d2e1f0,
  32. }
  33.  
  34. local function counter(incr)
  35.     local t1, t2 = 0, 0
  36.     if 0xFFFFFFFF - t1 < incr then
  37.         t2 = t2 + 1
  38.         t1 = incr - (0xFFFFFFFF - t1) - 1      
  39.     else t1 = t1 + incr
  40.     end
  41.     return t2, t1
  42. end
  43.  
  44. local function BE_toInt(bs, i)
  45.     return blshift((bs[i] or 0), 24) + blshift((bs[i+1] or 0), 16) + blshift((bs[i+2] or 0), 8) + (bs[i+3] or 0)
  46. end
  47.  
  48. local function preprocess(data)
  49.     local len = #data
  50.     local proc = {}
  51.     data[#data+1] = 0x80
  52.     while #data%64~=56 do data[#data+1] = 0 end
  53.     local blocks = math.ceil(#data/64)
  54.     for i = 1, blocks do
  55.         proc[i] = {}
  56.         for j = 1, 16 do
  57.             proc[i][j] = BE_toInt(data, 1+((i-1)*64)+((j-1)*4))
  58.         end
  59.     end
  60.     proc[blocks][15], proc[blocks][16] = counter(len*8)
  61.     return proc
  62. end
  63.  
  64. local function digestblock(w, C)
  65.     for j = 17, 80 do w[j] = lrotate(bxor(bxor(bxor(w[j-3], w[j-8]), w[j-14]), w[j-16]), 1) end
  66.  
  67.     local a, b, c, d, e = upack(C)
  68.  
  69.     for j = 1, 80 do
  70.         local f, k = 0, 0
  71.         if j <= 20 then
  72.             f = bor(band(b, c), band(bnot(b), d))
  73.             k = 0x5a827999
  74.         elseif j <= 40 then
  75.             f = bxor(bxor(b, c), d)
  76.             k = 0x6ed9eba1
  77.         elseif j <= 60 then
  78.             f = bor(bor(band(b, c), band(b, d)), band(c, d))
  79.             k = 0x8f1bbcdc
  80.         elseif j <= 80 then
  81.             f = bxor(bxor(b, c), d)
  82.             k = 0xca62c1d6
  83.         end
  84.         local temp = (lrotate(a, 5) + f + e + k + w[j])%mod32
  85.         a, b, c, d, e = temp, a, lrotate(b, 30), c, d
  86.     end
  87.  
  88.     C[1] = (C[1] + a)%mod32
  89.     C[2] = (C[2] + b)%mod32
  90.     C[3] = (C[3] + c)%mod32
  91.     C[4] = (C[4] + d)%mod32
  92.     C[5] = (C[5] + e)%mod32
  93.  
  94.     return C
  95. end
  96.  
  97. local mt = {
  98.     __tostring = function(a) return string.char(unpack(a)) end,
  99.     __index = {
  100.         toHex = function(self, s) return ("%02x"):rep(#self):format(unpack(self)) end,
  101.         isEqual = function(self, t)
  102.             if type(t) ~= "table" then return false end
  103.             if #self ~= #t then return false end
  104.             local ret = 0
  105.             for i = 1, #self do
  106.                 ret = bit32.bor(ret, bxor(self[i], t[i]))
  107.             end
  108.             return ret == 0
  109.         end
  110.     }
  111. }
  112.  
  113. local function toBytes(t, n)
  114.     local b = {}
  115.     for i = 1, n do
  116.         b[(i-1)*4+1] = band(brshift(t[i], 24), 0xFF)
  117.         b[(i-1)*4+2] = band(brshift(t[i], 16), 0xFF)
  118.         b[(i-1)*4+3] = band(brshift(t[i], 8), 0xFF)
  119.         b[(i-1)*4+4] = band(t[i], 0xFF)
  120.     end
  121.     return setmetatable(b, mt)
  122. end
  123.  
  124. local function digest(data)
  125.     local data = data or ""
  126.     data = type(data) == "table" and {upack(data)} or {tostring(data):byte(1,-1)}
  127.  
  128.     data = preprocess(data)
  129.     local C = {upack(H)}
  130.     for i = 1, #data do C = digestblock(data[i], C) end
  131.     return toBytes(C, 5)
  132. end
  133.  
  134. local function hmac(input, key)
  135.     local input = type(input) == "table" and {upack(input)} or {tostring(input):byte(1,-1)}
  136.     local key = type(key) == "table" and {upack(key)} or {tostring(key):byte(1,-1)}
  137.  
  138.     local blocksize = 64
  139.  
  140.     key = #key > blocksize and digest(key) or key
  141.  
  142.     local ipad = {}
  143.     local opad = {}
  144.     local padded_key = {}
  145.  
  146.     for i = 1, blocksize do
  147.         ipad[i] = bxor(0x36, key[i] or 0)
  148.         opad[i] = bxor(0x5C, key[i] or 0)
  149.     end
  150.  
  151.     for i = 1, #input do
  152.         ipad[blocksize+i] = input[i]
  153.     end
  154.  
  155.     ipad = digest(ipad)
  156.  
  157.     for i = 1, blocksize do
  158.         padded_key[i] = opad[i]
  159.         padded_key[blocksize+i] = ipad[i]
  160.     end
  161.  
  162.     return digest(padded_key)
  163. end
  164.  
  165. return {
  166.     digest = digest,
  167.     hmac   = hmac,
  168. }
RAW Paste Data
We use cookies for various purposes including analytics. By continuing to use Pastebin, you agree to our use of cookies as described in the Cookies Policy. OK, I Understand
Top