Advertisement
Anavrins

SHA256/HMAC/PBKDF2 - Legacy

Jun 25th, 2022 (edited)
856
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
  1. -- SHA-256, HMAC and PBKDF2 functions in ComputerCraft
  2. -- By Anavrins
  3. -- MIT License
  4. -- Pastebin: https://pastebin.com/Qk31PubV
  5. -- Usage: https://pastebin.com/q2SQ7eRg
  6. -- Last updated: June 25 2022
  7.  
  8. local mod32 = 2^32
  9. local band    = bit32 and bit32.band or bit.band
  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.  
  15. local function rrotate(n, b)
  16.     local s = n/(2^b)
  17.     local f = s%1
  18.     return (s-f) + f*mod32
  19. end
  20. local function brshift(int, by)
  21.     local s = int / (2^by)
  22.     return s - s%1
  23. end
  24.  
  25. local H = { -- First 32 bits of the fractional parts of the square roots of the first 8 primes 2..19
  26.     0x6a09e667, 0xbb67ae85, 0x3c6ef372, 0xa54ff53a,
  27.     0x510e527f, 0x9b05688c, 0x1f83d9ab, 0x5be0cd19,
  28. }
  29.  
  30. local K = { -- First 32 bits of the fractional parts of the cube roots of the first 64 primes 2..311
  31.     0x428a2f98, 0x71374491, 0xb5c0fbcf, 0xe9b5dba5, 0x3956c25b, 0x59f111f1, 0x923f82a4, 0xab1c5ed5,
  32.     0xd807aa98, 0x12835b01, 0x243185be, 0x550c7dc3, 0x72be5d74, 0x80deb1fe, 0x9bdc06a7, 0xc19bf174,
  33.     0xe49b69c1, 0xefbe4786, 0x0fc19dc6, 0x240ca1cc, 0x2de92c6f, 0x4a7484aa, 0x5cb0a9dc, 0x76f988da,
  34.     0x983e5152, 0xa831c66d, 0xb00327c8, 0xbf597fc7, 0xc6e00bf3, 0xd5a79147, 0x06ca6351, 0x14292967,
  35.     0x27b70a85, 0x2e1b2138, 0x4d2c6dfc, 0x53380d13, 0x650a7354, 0x766a0abb, 0x81c2c92e, 0x92722c85,
  36.     0xa2bfe8a1, 0xa81a664b, 0xc24b8b70, 0xc76c51a3, 0xd192e819, 0xd6990624, 0xf40e3585, 0x106aa070,
  37.     0x19a4c116, 0x1e376c08, 0x2748774c, 0x34b0bcb5, 0x391c0cb3, 0x4ed8aa4a, 0x5b9cca4f, 0x682e6ff3,
  38.     0x748f82ee, 0x78a5636f, 0x84c87814, 0x8cc70208, 0x90befffa, 0xa4506ceb, 0xbef9a3f7, 0xc67178f2,
  39. }
  40.  
  41. local function counter(incr)
  42.     local t1, t2 = 0, 0
  43.     if 0xFFFFFFFF - t1 < incr then
  44.         t2 = t2 + 1
  45.         t1 = incr - (0xFFFFFFFF - t1) - 1      
  46.     else t1 = t1 + incr
  47.     end
  48.     return t2, t1
  49. end
  50.  
  51. local function BE_toInt(bs, i)
  52.     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)
  53. end
  54.  
  55. local function preprocess(data)
  56.     local len = #data
  57.     local proc = {}
  58.     data[#data+1] = 0x80
  59.     while #data%64~=56 do data[#data+1] = 0 end
  60.     local blocks = math.ceil(#data/64)
  61.     for i = 1, blocks do
  62.         proc[i] = {}
  63.         for j = 1, 16 do
  64.             proc[i][j] = BE_toInt(data, 1+((i-1)*64)+((j-1)*4))
  65.         end
  66.     end
  67.     proc[blocks][15], proc[blocks][16] = counter(len*8)
  68.     return proc
  69. end
  70.  
  71. local function digestblock(w, C)
  72.     for j = 17, 64 do
  73.         local v = w[j-15]
  74.         local s0 = bxor(rrotate(w[j-15], 7), rrotate(w[j-15], 18), brshift(w[j-15], 3))
  75.         local s1 = bxor(rrotate(w[j-2], 17), rrotate(w[j-2], 19),brshift(w[j-2], 10))
  76.         w[j] = (w[j-16] + s0 + w[j-7] + s1)%mod32
  77.     end
  78.     local a, b, c, d, e, f, g, h = upack(C)
  79.     for j = 1, 64 do
  80.         local S1 = bxor(rrotate(e, 6), rrotate(e, 11), rrotate(e, 25))
  81.         local ch = bxor(band(e, f), band(bnot(e), g))
  82.         local temp1 = (h + S1 + ch + K[j] + w[j])%mod32
  83.         local S0 = bxor(rrotate(a, 2), rrotate(a, 13), rrotate(a, 22))
  84.         local maj = bxor(bxor(band(a, b), band(a, c)), band(b, c))
  85.         local temp2 = (S0 + maj)%mod32
  86.         h, g, f, e, d, c, b, a = g, f, e, (d+temp1)%mod32, c, b, a, (temp1+temp2)%mod32
  87.     end
  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.     C[6] = (C[6] + f)%mod32
  94.     C[7] = (C[7] + g)%mod32
  95.     C[8] = (C[8] + h)%mod32
  96.     return C
  97. end
  98.  
  99. local mt = {
  100.     __tostring = function(a) return string.char(unpack(a)) end,
  101.     __index = {
  102.         toHex = function(self, s) return ("%02x"):rep(#self):format(unpack(self)) end,
  103.         isEqual = function(self, t)
  104.             if type(t) ~= "table" then return false end
  105.             if #self ~= #t then return false end
  106.             local ret = 0
  107.             for i = 1, #self do
  108.                 ret = bit32.bor(ret, bxor(self[i], t[i]))
  109.             end
  110.             return ret == 0
  111.         end,
  112.         sub = function(self, a, b)
  113.             local len = #self+1
  114.             local start = a%len
  115.             local stop = (b or len-1)%len
  116.             local ret = {}
  117.             local i = 1
  118.             for j = start, stop, start<stop and 1 or -1 do
  119.                 ret[i] = self[j]
  120.                 i = i+1
  121.             end
  122.             return setmetatable(ret, byteArray_mt)
  123.         end,
  124.     }
  125. }
  126.  
  127. local function toBytes(t, n)
  128.     local b = {}
  129.     for i = 1, n do
  130.         b[(i-1)*4+1] = band(brshift(t[i], 24), 0xFF)
  131.         b[(i-1)*4+2] = band(brshift(t[i], 16), 0xFF)
  132.         b[(i-1)*4+3] = band(brshift(t[i], 8), 0xFF)
  133.         b[(i-1)*4+4] = band(t[i], 0xFF)
  134.     end
  135.     return setmetatable(b, mt)
  136. end
  137.  
  138. function digest(data)
  139.     local data = data or ""
  140.     data = type(data) == "table" and {upack(data)} or {tostring(data):byte(1,-1)}
  141.  
  142.     data = preprocess(data)
  143.     local C = {upack(H)}
  144.     for i = 1, #data do C = digestblock(data[i], C) end
  145.     return toBytes(C, 8)
  146. end
  147.  
  148. function hmac(data, key)
  149.     local data = type(data) == "table" and {upack(data)} or {tostring(data):byte(1,-1)}
  150.     local key = type(key) == "table" and {upack(key)} or {tostring(key):byte(1,-1)}
  151.  
  152.     local blocksize = 64
  153.  
  154.     key = #key > blocksize and digest(key) or key
  155.  
  156.     local ipad = {}
  157.     local opad = {}
  158.     local padded_key = {}
  159.  
  160.     for i = 1, blocksize do
  161.         ipad[i] = bxor(0x36, key[i] or 0)
  162.         opad[i] = bxor(0x5C, key[i] or 0)
  163.     end
  164.  
  165.     for i = 1, #data do
  166.         ipad[blocksize+i] = data[i]
  167.     end
  168.  
  169.     ipad = digest(ipad)
  170.  
  171.     for i = 1, blocksize do
  172.         padded_key[i] = opad[i]
  173.         padded_key[blocksize+i] = ipad[i]
  174.     end
  175.  
  176.     return digest(padded_key)
  177. end
  178.  
  179. function pbkdf2(pass, salt, iter, dklen)
  180.     local salt = type(salt) == "table" and salt or {tostring(salt):byte(1,-1)}
  181.     local hashlen = 32
  182.     local dklen = dklen or 32
  183.     local block = 1
  184.     local out = {}
  185.  
  186.     while dklen > 0 do
  187.         local ikey = {}
  188.         local isalt = {upack(salt)}
  189.         local clen = dklen > hashlen and hashlen or dklen
  190.  
  191.         isalt[#isalt+1] = band(brshift(block, 24), 0xFF)
  192.         isalt[#isalt+1] = band(brshift(block, 16), 0xFF)
  193.         isalt[#isalt+1] = band(brshift(block, 8), 0xFF)
  194.         isalt[#isalt+1] = band(block, 0xFF)
  195.  
  196.         for j = 1, iter do
  197.             isalt = hmac(isalt, pass)
  198.             for k = 1, clen do ikey[k] = bxor(isalt[k], ikey[k] or 0) end
  199.             if j % 200 == 0 then os.queueEvent("PBKDF2", j) coroutine.yield("PBKDF2") end
  200.         end
  201.         dklen = dklen - clen
  202.         block = block+1
  203.         for k = 1, clen do out[#out+1] = ikey[k] end
  204.     end
  205.  
  206.     return setmetatable(out, mt)
  207. end
Advertisement
RAW Paste Data Copied
Advertisement