Skip to content

Instantly share code, notes, and snippets.

@creationix
Last active February 5, 2016 20:53
Show Gist options
  • Save creationix/7ce3796e65b66549c4b0 to your computer and use it in GitHub Desktop.
Save creationix/7ce3796e65b66549c4b0 to your computer and use it in GitHub Desktop.
SHA1 and Base64 implemented for nodemcu using bit library.
do
local byte, char = string.byte, string.char
local floor = math.floor
local rshift = bit.rshift
local lshift = bit.lshift
local band = bit.band
local bor = bit.bor
local bnot = bit.bnot
local bxor = bit.bxor
local function leftrotate(num, b)
return bor(lshift(num, b), rshift(num, 32 - b))
end
function sha1(message)
local len = #message
local high = floor(len / 0x20000000)
local low = (len * 8) % 100000000
local function slot(g, o)
local i = g + o
if i <= len then
return byte(message, i)
elseif i == len + 1 then
return 0x80
elseif o <= 56 or len >= g + 56 then
return 0
elseif o <= 60 then
return rshift(high, (60 - o) * 8) % 256
else
return rshift(low, (64 - o) * 8) % 256
end
end
local h0, h1, h2, h3, h4 = 0x67452301, 0xEFCDAB89, 0x98BADCFE, 0x10325476, 0xC3D2E1F0
local w = {}
for g = 0, len + 8, 64 do
for i = 0, 15 do
local b = i * 4
w[i] = bor(
lshift(slot(g, b + 1), 24),
lshift(slot(g, b + 2), 16),
lshift(slot(g, b + 3), 8),
slot(g, b + 4)
)
end
for i = 16, 79 do
w[i] = leftrotate(bxor(w[i - 3], w[i - 8], w[i - 14], w[i - 16]), 1)
end
local a, b, c, d, e = h0, h1, h2, h3, h4
local function process(f, k, s)
a, b, c, d, e =
leftrotate(a, 5) + f + e + k + s,
a, leftrotate(b, 30), c, d
end
for i = 0, 19 do
process(bor(band(b, c), band(bnot(b), d)), 0x5A827999, w[i])
end
for i = 20, 39 do
process(bxor(b, c, d), 0x6ED9EBA1, w[i])
end
for i = 40, 59 do
process(bor(band(b, c), band(b, d), band(c, d)), 0x8F1BBCDC, w[i])
end
for i = 60, 79 do
process(bxor(b, c, d), 0xCA62C1D6, w[i])
end
h0 = rshift(h0 + a, 0)
h1 = rshift(h1 + b, 0)
h2 = rshift(h2 + c, 0)
h3 = rshift(h3 + d, 0)
h4 = rshift(h4 + e, 0)
end
return char(
rshift(h0, 24),
band(rshift(h0, 16), 0xff),
band(rshift(h0, 8), 0xff),
band(h0, 0xff),
rshift(h1, 24),
band(rshift(h1, 16), 0xff),
band(rshift(h1, 8), 0xff),
band(h1, 0xff),
rshift(h2, 24),
band(rshift(h2, 16), 0xff),
band(rshift(h2, 8), 0xff),
band(h2, 0xff),
rshift(h3, 24),
band(rshift(h3, 16), 0xff),
band(rshift(h3, 8), 0xff),
band(h3, 0xff),
rshift(h4, 24),
band(rshift(h4, 16), 0xff),
band(rshift(h4, 8), 0xff),
band(h4, 0xff)
)
end
local bytes =
"ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/"
function base64(s)
local parts = {}
for i = 1, #s, 3 do
local a, b, c = byte(s, i, i + 3)
parts[#parts + 1] = char(
byte(bytes, rshift(a, 2) + 1),
byte(bytes, bor(lshift(band(a, 3), 4), rshift(b or 0, 4)) + 1),
b and byte(bytes, bor(lshift(band(b, 15), 2), rshift(c or 0, 6)) + 1) or 61,
c and byte(bytes, band(c, 63) + 1) or 61)
end
return table.concat(parts)
end
end
dofile("sha1.lua")
local function dump(hash)
local hex = {}
for i = 1, #hash do
hex[i] = string.format("%02x", string.byte(hash, i))
end
return table.concat(hex)
end
-- Test data from http://www.nsrl.nist.gov/testdata/ and Wikipedia
-- http://csrc.nist.gov/groups/ST/toolkit/documents/Examples/SHA_All.pdf
local tests = {
"2fd4e1c67a2d28fced849ee1bb76e7391b93eb12", "The quick brown fox jumps over the lazy dog",
"de9f2c7fd25e1b3afad3e85a0bd17d9b100db4b3", "The quick brown fox jumps over the lazy cog",
"da39a3ee5e6b4b0d3255bfef95601890afd80709", "",
"a9993e364706816aba3e25717850c26c9cd0d89d", "abc",
"84983e441c3bd26ebaae4aa1f95129e5e54670f1", "abcdbcdecdefdefgefghfghighijhijkijkljklmklmnlmnomnopnopq",
"34aa973cd4c4daa4f61eeb2bdbad27316534016f", ("a"):rep(1000000),
}
for i = 1, #tests, 2 do
local expected = tests[i]
local input = tests[i + 1]
local actual = dump(sha1(input))
assert(expected == actual, expected)
end
tests = {
"L9ThxnotKPzthJ7hu3bnORuT6xI=", "The quick brown fox jumps over the lazy dog",
"3p8sf9JeGzr60+haC9F9mxANtLM=", "The quick brown fox jumps over the lazy cog",
"2jmj7l5rSw0yVb/vlWAYkK/YBwk=", ""
}
for i = 1, #tests, 2 do
local expected = tests[i]
local input = tests[i + 1]
local actual = base64(sha1(input))
assert(actual == expected, expected)
end
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment