This repository has been archived on 2026-03-07. You can view files and clone it. You cannot open issues or pull requests or push a commit.
Files

134 lines
4.5 KiB
Lua

local _M = {}
_M.to_bin = function (str)
local data = ''
str:lower():gsub('([a-z0-9])([a-z0-9])', function (d1, d2)
d1 = _M.hexdigit2int(d1)
d2 = _M.hexdigit2int(d2)
data = (data .. string.char(d1 * 16 + d2))
end)
return data
end
_M.to_hex = function (str)
local data = ''
for i=1,#str,1 do
data = (data .. ("%02x"):format(str:byte(i)))
end
return data
end
_M.hexdigit2int = function (ch)
local b = ch:byte()
if b >= ('a'):byte() then
return 10 + (b - ('a'):byte())
elseif b >= ('0'):byte() then
return b - ('0'):byte()
else
_M.assert(false)
end
end
_M.b64 = (function ()
-- character table string
local b='ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/'
-- encoding
local function enc(data)
return ((data:gsub('.', function(x)
local r,b='',x:byte()
for i=8,1,-1 do r=r..(b%2^i-b%2^(i-1)>0 and '1' or '0') end
return r;
end)..'0000'):gsub('%d%d%d?%d?%d?%d?', function(x)
if (#x < 6) then return '' end
local c=0
for i=1,6 do c=c+(x:sub(i,i)=='1' and 2^(6-i) or 0) end
return b:sub(c+1,c+1)
end)..({ '', '==', '=' })[#data%3+1])
end
-- decoding
local function dec(data)
data = string.gsub(data, '[^'..b..'=]', '')
return (data:gsub('.', function(x)
if (x == '=') then return '' end
local r,f='',(b:find(x)-1)
for i=6,1,-1 do r=r..(f%2^i-f%2^(i-1)>0 and '1' or '0') end
return r;
end):gsub('%d%d%d?%d?%d?%d?%d?%d?', function(x)
if (#x ~= 8) then return '' end
local c=0
for i=1,8 do c=c+(x:sub(i,i)=='1' and 2^(8-i) or 0) end
return string.char(c)
end))
end
return {
encode = enc,
decode = dec,
}
end)()
_M.sha2 = require("sha2")
_M.hmac = (function ()
--local hmac = require 'hmac'
local sha2 = _M.sha2
-- these hmac-ize routine is from https://github.com/bjc/prosody/blob/master/util/hmac.lua.
-- thanks!
local s_char = string.char;
local s_gsub = string.gsub;
local s_rep = string.rep;
local xor_map = {0;1;2;3;4;5;6;7;8;9;10;11;12;13;14;15;1;0;3;2;5;4;7;6;9;8;11;10;13;12;15;14;2;3;0;1;6;7;4;5;10;11;8;9;14;15;12;13;3;2;1;0;7;6;5;4;11;10;9;8;15;14;13;12;4;5;6;7;0;1;2;3;12;13;14;15;8;9;10;11;5;4;7;6;1;0;3;2;13;12;15;14;9;8;11;10;6;7;4;5;2;3;0;1;14;15;12;13;10;11;8;9;7;6;5;4;3;2;1;0;15;14;13;12;11;10;9;8;8;9;10;11;12;13;14;15;0;1;2;3;4;5;6;7;9;8;11;10;13;12;15;14;1;0;3;2;5;4;7;6;10;11;8;9;14;15;12;13;2;3;0;1;6;7;4;5;11;10;9;8;15;14;13;12;3;2;1;0;7;6;5;4;12;13;14;15;8;9;10;11;4;5;6;7;0;1;2;3;13;12;15;14;9;8;11;10;5;4;7;6;1;0;3;2;14;15;12;13;10;11;8;9;6;7;4;5;2;3;0;1;15;14;13;12;11;10;9;8;7;6;5;4;3;2;1;0;};
local function xor(x, y)
local lowx, lowy = x % 16, y % 16;
local hix, hiy = (x - lowx) / 16, (y - lowy) / 16;
local lowr, hir = xor_map[lowx * 16 + lowy + 1], xor_map[hix * 16 + hiy + 1];
local r = hir * 16 + lowr;
return r;
end
local opadc, ipadc = s_char(0x5c), s_char(0x36);
local ipad_map = {};
local opad_map = {};
for i=0,255 do
ipad_map[s_char(i)] = s_char(xor(0x36, i));
opad_map[s_char(i)] = s_char(xor(0x5c, i));
end
local function hmac(key, message, hash, blocksize)
if #key > blocksize then
key = hash(key)
end
local padding = blocksize - #key;
local ipad = s_gsub(key, ".", ipad_map)..s_rep(ipadc, padding);
local opad = s_gsub(key, ".", opad_map)..s_rep(opadc, padding);
return hash(opad..hash(ipad..message))
end
local sha256 = function (data)
local text = sha2.hash256(data)
return _M.to_bin(text)
end
local digest_routines = {
hex = _M.to_hex,
base64 = _M.b64.encode
}
local hmac_sha256 = function (key, data, digest)
local bin = hmac(key, data, sha256, 64)
-- print(_M.to_hex(bin))
--local bin = _M.to_bin("8BDD6729CE0F580B7424921D5F0CFD1F1642243762CBA71FFCC8FABCFC72608B")
return digest_routines[digest] and digest_routines[digest](bin) or bin
end
local hmac_sha1 = function (key, data, digest)
local bin = sha1.sha1_bin(key, data)
return digest_routines[digest] and digest_routines[digest](bin) or bin
end
_M.hmac_by = {
sha256 = hmac_sha256,
sha1 = hmac_sha1,
}
return hmac_sha256
end)()
return _M