SHARE
TWEET

SHA256/HMAC/PBKDF2

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