libs/hashes.lua

Tue, 12 Jan 2016 14:06:20 +0100

author
Kim Alvefur <zash@zash.se>
date
Tue, 12 Jan 2016 14:06:20 +0100
changeset 398
b4ce2e524ed8
parent 389
bf3a4fcdcb76
child 414
2a5eff919f4a
permissions
-rw-r--r--

libs.hashes: Fix HMAC-SHA-1 blocksize to 64 (20 is output size)

local have_luacrypto, crypto = pcall(require, "crypto");

if have_luacrypto then
	local hashes = {};

	local digest = crypto.digest;
	local function gethash(algo)
		return function (string, hex)
			return digest(algo, string, not hex);
		end
	end

	local hmac = crypto.hmac.digest;
	local function gethmac(algo)
		return function (key, message, hex)
			return hmac(algo, message, key, not hex);
		end
	end

	local hash_algos = { "md5", "sha1", "sha256", "sha512" };

	for _, hash_algo in ipairs(hash_algos) do
		hashes[hash_algo] = gethash(hash_algo);
		hashes["hmac_"..hash_algo] = gethmac(hash_algo);
	end

	return hashes;
else
	local sha1 = require"util.sha1".sha1;
	local bxor = require"bit".bxor;

	local s_rep = string.rep;
	local s_char = string.char;
	local s_byte = string.byte;
	local t_concat = table.concat;

	local function hmac_sha1(key, message, hexres)
		if #key > 64 then
			key = sha1(key);
		elseif #key < 64 then
			key = key .. s_rep("\0", 64 - #key);
		end
		local o_key_pad, i_key_pad = {}, {}
		for i = 1, 64 do
			local b = s_byte(key, i)
			o_key_pad[i] = s_char(bxor(b, 0x5c));
			i_key_pad[i] = s_char(bxor(b, 0x36));
		end
		o_key_pad = t_concat(o_key_pad);
		i_key_pad = t_concat(i_key_pad);
		return sha1(o_key_pad .. sha1(i_key_pad .. message), hexres);
	end

	return {
		sha1 = sha1;
		hmac_sha1 = hmac_sha1;
	};
end

mercurial