Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- -- BLAKE-256 hash function in ComputerCraft
- -- By Anavrins
- -- For help and details, you can DM me on Discord (Anavrins#4600)
- -- MIT License
- -- http://pastebin.com/XRy3LMBG
- -- Last update: May 13, 2019
- local mod = 2^32
- local bor = bit32.bor
- local band = bit32.band
- local bxor = bit32.bxor
- local blshift = bit32.lshift
- local brshift = bit32.arshift
- local function rrotate(n, b)
- local s = n/(2^b)
- local f = s%1
- return (s-f) + f*mod
- end
- local const = {[0]=
- 0x243F6A88, 0x85A308D3, 0x13198A2E, 0x03707344,
- 0xA4093822, 0x299F31D0, 0x082EFA98, 0xEC4E6C89,
- 0x452821E6, 0x38D01377, 0xBE5466CF, 0x34E90C6C,
- 0xC0AC29B7, 0xC97C50DD, 0x3F84D5B5, 0xB5470917
- }
- local iv = {[0]=
- 0x6A09E667, 0xBB67AE85, 0x3C6EF372, 0xA54FF53A,
- 0x510E527F, 0x9B05688C, 0x1F83D9AB, 0x5BE0CD19,
- }
- local sigma = {[0]=
- {[0]= 0, 1, 2, 3, 4, 5, 6, 7, 8, 9,10,11,12,13,14,15},
- {[0]=14,10, 4, 8, 9,15,13, 6, 1,12, 0, 2,11, 7, 5, 3},
- {[0]=11, 8,12, 0, 5, 2,15,13,10,14, 3, 6, 7, 1, 9, 4},
- {[0]= 7, 9, 3, 1,13,12,11,14, 2, 6, 5,10, 4, 0,15, 8},
- {[0]= 9, 0, 5, 7, 2, 4,10,15,14, 1,11,12, 6, 8, 3,13},
- {[0]= 2,12, 6,10, 0,11, 8, 3, 4,13, 7, 5,15,14, 1, 9},
- {[0]=12, 5, 1,15,14,13, 4,10, 0, 7, 6, 3, 9, 2, 8,11},
- {[0]=13,11, 7,14,12, 1, 3, 9, 5, 0,15, 4, 8, 6, 2,10},
- {[0]= 6,15,14, 9,11, 3, 0, 8,12, 2,13, 7, 1, 4,10, 5},
- {[0]=10, 2, 8, 4, 7, 6, 1, 5,15,11, 9,14, 3,12,13, 0}
- }
- local function quarterRound(s, a, b, c, d, m, r, i)
- local j, k = sigma[r%10][2*i], sigma[r%10][(2*i)+1]
- s[a] = (s[a]+(s[b]+(bxor(m[j], const[k]))))%mod
- s[d] = rrotate(bxor(s[d], s[a]), 16)
- s[c] = (s[c]+s[d])%mod
- s[b] = rrotate(bxor(s[b], s[c]), 12)
- s[a] = (s[a]+(s[b]+(bxor(m[k], const[j]))))%mod
- s[d] = rrotate(bxor(s[d], s[a]), 8)
- s[c] = (s[c]+s[d])%mod
- s[b] = rrotate(bxor(s[b], s[c]), 7)
- return s
- end
- local function compress(h, m, s)
- local v = {[0]=
- h[ 0], h[ 1], h[ 2], h[ 3], h[ 4], h[ 5], h[ 6], h[ 7],
- h[ 8], h[ 9], h[10], h[11], h[12], h[13], h[14], h[15]
- }
- for r = 0, 13 do
- v = quarterRound(v, 0, 4, 8,12, m, r, 0)
- v = quarterRound(v, 1, 5, 9,13, m, r, 1)
- v = quarterRound(v, 2, 6,10,14, m, r, 2)
- v = quarterRound(v, 3, 7,11,15, m, r, 3)
- v = quarterRound(v, 0, 5,10,15, m, r, 4)
- v = quarterRound(v, 1, 6,11,12, m, r, 5)
- v = quarterRound(v, 2, 7, 8,13, m, r, 6)
- v = quarterRound(v, 3, 4, 9,14, m, r, 7)
- end
- for i = 0, 7 do
- h[i] = bxor(bxor(bxor(h[i], v[i]), v[i+8]), s[i] or s[i-4])
- end
- return h
- end
- local function BE_toInt(bs, i)
- return blshift((bs[i+1] or 0), 24) + blshift((bs[i+2] or 0), 16) + blshift((bs[i+3] or 0), 8) + (bs[i+4] or 0)
- end
- local function incr(t, incr)
- if 0xFFFFFFFF - t[0] < incr then
- t[1] = t[1] + 1
- t[0] = incr - (0xFFFFFFFF - t[0]) - 1
- else
- t[0] = t[0] + incr
- end
- return t
- end
- local mt = {
- __tostring = function(a) return string.char(unpack(a)) end,
- __index = {
- toHex = function(self, s) return ("%02x"):rep(#self):format(unpack(self)) end,
- isEqual = function(self, t)
- if type(t) ~= "table" then return false end
- if #self ~= #t then return false end
- local ret = 0
- for i = 1, #self do
- ret = bor(ret, bxor(self[i], t[i]))
- end
- return ret == 0
- end
- }
- }
- local function toBytes(t, n)
- local b = {}
- for i = 1, n do
- b[(i-1)*4+1] = band(brshift(t[i], 24), 0xFF)
- b[(i-1)*4+2] = band(brshift(t[i], 16), 0xFF)
- b[(i-1)*4+3] = band(brshift(t[i], 8), 0xFF)
- b[(i-1)*4+4] = band(t[i], 0xFF)
- end
- return setmetatable(b, mt)
- end
- local function digest(data, salt)
- local data = type(data) == "string" and {data:byte(1,-1)} or data
- local salt = type(salt) == "string" and {salt:byte(1,-1)} or salt
- local salt = salt or {}
- local m = {}
- local v = {}
- local t = {[0]=0,0}
- local h = {[0]=iv[0], iv[1], iv[2], iv[3], iv[4], iv[5], iv[6], iv[7]}
- local s = {[0]=BE_toInt(salt, 0), BE_toInt(salt, 4), BE_toInt(salt, 8), BE_toInt(salt,12)}
- local mLen = #data
- data[#data+1] = 0x80
- while #data%64~=56 do data[#data+1] = 0 end
- data[#data] = bor(data[#data], 1)
- t = incr(t, mLen*8)
- for i = 1, 0, -1 do
- data[#data+1] = band(brshift(t[i], 24), 0xFF)
- data[#data+1] = band(brshift(t[i], 16), 0xFF)
- data[#data+1] = band(brshift(t[i], 8), 0xFF)
- data[#data+1] = band(t[i], 0xFF)
- end
- t[0], t[1] = 0, 0
- local blockAmt = math.ceil(#data/64)
- for i = 0, blockAmt-1 do
- for j = 0, 15 do m[j] = BE_toInt(data, (64*i)+4*j) end
- if mLen == 0 then t[0], t[1] = 0, 0
- elseif (mLen-64) >= 0 then
- t = incr(t, 512)
- mLen = mLen-64
- elseif (mLen-64) < 0 then
- t = incr(t, mLen*8)
- mLen = 0
- end
- v = {[0]=
- h[0], h[1], h[2], h[3], h[4], h[5], h[6], h[7],
- bxor(s[0], const[0]), bxor(s[1], const[1]), bxor(s[2], const[2]), bxor(s[3], const[3]),
- bxor(t[0], const[4]), bxor(t[0], const[5]), bxor(t[1], const[6]), bxor(t[1], const[7]),
- }
- h = compress(v, m, s)
- end
- return toBytes({h[0], h[1], h[2], h[3], h[4], h[5], h[6], h[7]}, 8)
- end
- return {
- digest = digest,
- }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement