Anavrins

SHA1

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