Advertisement
Anavrins

SHA1

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