Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- bit32_lshift = nil
- bit32_rshift = nil
- bit32_or = nil
- bit32_and = nil
- bit32_xor = nil
- bit32_negate = nil
- if not bit then -- lua >= 5.4
- load([[
- bit32_lshift = function(a,b) return a << b end;
- bit32_rshift = function(a,b) return a >> b end;
- bit32_or = function(a,b) return a | b end;
- bit32_and = function(a,b) return a & b end;
- bit32_xor = function(a,b) return a ^ b end;
- bit32_negate = function(a) return ~a end;
- ]])()
- else -- bit library is global on my restricted env
- bit32_lshift = bit.lshift
- bit32_rshift = bit.rshift
- bit32_or = bit.bor
- bit32_and = bit.band
- bit32_xor = bit.bxor
- bit32_negate = bit.bnot
- end
- function my_unpack(tbl, i, j)
- i = i or 1
- j = j or #tbl
- if i <= j then
- return tbl[i], my_unpack(tbl, i + 1, j)
- end
- end
- local table_unpack = my_unpack or table.unpack or unpack
- --equivalent of string.unpack with <I4 formats
- local function lendian_string_unpack_to_ints(num_ints, str, start_index)
- start_index = start_index or 1
- num_ints = num_ints or 100000
- local count = 0
- if type(num_ints == string) then
- local _, endIndex = string.find(num_ints, "I4")
- while endIndex do
- count = count + 1
- _, endIndex = string.find(num_ints, "I4", endIndex + 1)
- end
- end
- local results = {}
- local end_index = start_index + (count * 4) - 1
- for i = start_index, end_index, 4 do
- if i <= #str then
- local bytes = {string.byte(str, i, i + 3)}
- local value = 0
- for j = #bytes, 1, -1 do
- value = value * 256 + bytes[j]
- end
- table.insert(results, value)
- end
- end
- return table_unpack(results)
- end
- --equivalent of string.pack with <I4 formats
- local function lendian_string_pack_to_ints(num_ints, ...)
- local result = {}
- local args = { ... }
- local argIndex = 1
- local count = 0
- if type(num_ints == string) then
- local _, endIndex = string.find(num_ints, "I4")
- while endIndex do
- count = count + 1
- _, endIndex = string.find(num_ints, "I4", endIndex + 1)
- end
- end
- for i = 1, count do
- local num = args[argIndex]
- for j = 1, 4 do
- table.insert(result, string.char(bit32_and(num, 0xFF)))
- num = bit32_rshift(num, 8)
- end
- argIndex = argIndex + 1
- end
- return table.concat(result)
- end
- local sunp = lendian_string_unpack_to_ints;
- local function poly_init(k)
- local st = {r={bit32_and((sunp("<I4", k, 1)), 67108863),bit32_and(bit32_rshift(sunp("<I4", k, 4), 2), 67108611),bit32_and(bit32_rshift(sunp("<I4", k, 7), 4), 67092735),bit32_and(bit32_rshift(sunp("<I4", k, 10), 6), 66076671),bit32_and(bit32_rshift(sunp("<I4", k, 13), 8), 1048575)},h={0,0,0,0,0},pad={sunp("<I4", k, 17),sunp("<I4", k, 21),sunp("<I4", k, 25),sunp("<I4", k, 29)},buffer="",leftover=0,final=false};
- return st;
- end
- local function poly_blocks(st, m)
- local bytes = #m;
- local midx = 1;
- local hibit = (st.final and 0) or 16777216;
- local r0 = st.r[1];
- local r1 = st.r[2];
- local r2 = st.r[3];
- local r3 = st.r[4];
- local r4 = st.r[5];
- local s1 = r1 * 5;
- local s2 = r2 * 5;
- local s3 = r3 * 5;
- local s4 = r4 * 5;
- local h0 = st.h[1];
- local h1 = st.h[2];
- local h2 = st.h[3];
- local h3 = st.h[4];
- local h4 = st.h[5];
- local d0, d1, d2, d3, d4, c;
- while bytes >= 16 do
- h0 = h0 + bit32_and((sunp("<I4", m, midx)), 67108863);
- h1 = h1 + bit32_and(bit32_rshift(sunp("<I4", m, midx + 3), 2), 67108863);
- h2 = h2 + bit32_and(bit32_rshift(sunp("<I4", m, midx + 6), 4), 67108863);
- h3 = h3 + bit32_and(bit32_rshift(sunp("<I4", m, midx + 9), 6), 67108863);
- h4 = h4 + bit32_or(bit32_rshift(sunp("<I4", m, midx + 12), 8), hibit);
- d0 = (h0 * r0) + (h1 * s4) + (h2 * s3) + (h3 * s2) + (h4 * s1);
- d1 = (h0 * r1) + (h1 * r0) + (h2 * s4) + (h3 * s3) + (h4 * s2);
- d2 = (h0 * r2) + (h1 * r1) + (h2 * r0) + (h3 * s4) + (h4 * s3);
- d3 = (h0 * r3) + (h1 * r2) + (h2 * r1) + (h3 * r0) + (h4 * s4);
- d4 = (h0 * r4) + (h1 * r3) + (h2 * r2) + (h3 * r1) + (h4 * r0);
- c = bit32_and(bit32_rshift(d0, 26), 4294967295);
- h0 = bit32_and(d0, 67108863);
- d1 = d1 + c;
- c = bit32_and(bit32_rshift(d1, 26), 4294967295);
- h1 = bit32_and(d1, 67108863);
- d2 = d2 + c;
- c = bit32_and(bit32_rshift(d2, 26), 4294967295);
- h2 = bit32_and(d2, 67108863);
- d3 = d3 + c;
- c = bit32_and(bit32_rshift(d3, 26), 4294967295);
- h3 = bit32_and(d3, 67108863);
- d4 = d4 + c;
- c = bit32_and(bit32_rshift(d4, 26), 4294967295);
- h4 = bit32_and(d4, 67108863);
- h0 = h0 + (c * 5);
- c = bit32_rshift(h0, 26);
- h0 = bit32_and(h0, 67108863);
- h1 = h1 + c;
- midx = midx + 16;
- bytes = bytes - 16;
- end
- st.h[1] = h0;
- st.h[2] = h1;
- st.h[3] = h2;
- st.h[4] = h3;
- st.h[5] = h4;
- st.bytes = bytes;
- st.midx = midx;
- return st;
- end
- local function poly_update(st, m)
- st.bytes, st.midx = #m, 1;
- if (st.bytes >= 16) then
- poly_blocks(st, m);
- end
- if (st.bytes == 0) then
- else
- local buffer = string.sub(m, st.midx) .. "\x01" .. string.rep("\0", (16 - st.bytes) - 1);
- assert(#buffer == 16);
- st.final = true;
- poly_blocks(st, buffer);
- end
- return st;
- end
- local function poly_finish(st)
- local c, mask;
- local f;
- local h0 = st.h[1];
- local h1 = st.h[2];
- local h2 = st.h[3];
- local h3 = st.h[4];
- local h4 = st.h[5];
- c = bit32_rshift(h1, 26);
- h1 = bit32_and(h1, 67108863);
- h2 = h2 + c;
- c = bit32_rshift(h2, 26);
- h2 = bit32_and(h2, 67108863);
- h3 = h3 + c;
- c = bit32_rshift(h3, 26);
- h3 = bit32_and(h3, 67108863);
- h4 = h4 + c;
- c = bit32_rshift(h4, 26);
- h4 = bit32_and(h4, 67108863);
- h0 = h0 + (c * 5);
- c = bit32_rshift(h0, 26);
- h0 = bit32_and(h0, 67108863);
- h1 = h1 + c;
- local g0 = h0 + 5;
- c = bit32_rshift(g0, 26);
- g0 = bit32_and(g0, 67108863);
- local g1 = h1 + c;
- c = bit32_rshift(g1, 26);
- g1 = bit32_and(g1, 67108863);
- local g2 = h2 + c;
- c = bit32_rshift(g2, 26);
- g2 = bit32_and(g2, 67108863);
- local g3 = h3 + c;
- c = bit32_rshift(g3, 26);
- g3 = bit32_and(g3, 67108863);
- local g4 = bit32_and((h4 + c) - 67108864, 4294967295);
- mask = bit32_and(bit32_rshift(g4, 31) - 1, 4294967295);
- g0 = bit32_and(g0, mask);
- g1 = bit32_and(g1, mask);
- g2 = bit32_and(g2, mask);
- g3 = bit32_and(g3, mask);
- g4 = bit32_and(g4, mask);
- mask = bit32_and(bit32_negate(mask), 4294967295);
- h0 = bit32_or(bit32_and(h0, mask), g0);
- h1 = bit32_or(bit32_and(h1, mask), g1);
- h2 = bit32_or(bit32_and(h2, mask), g2);
- h3 = bit32_or(bit32_and(h3, mask), g3);
- h4 = bit32_or(bit32_and(h4, mask), g4);
- h0 = bit32_and(bit32_or(h0, bit32_lshift(h1, 26)), 4294967295);
- h1 = bit32_and(bit32_or(bit32_rshift(h1, 6), bit32_lshift(h2, 20)), 4294967295);
- h2 = bit32_and(bit32_or(bit32_rshift(h2, 12), bit32_lshift(h3, 14)), 4294967295);
- h3 = bit32_and(bit32_or(bit32_rshift(h3, 18), bit32_lshift(h4, 8)), 4294967295);
- f = h0 + st.pad[1];
- h0 = bit32_and(f, 4294967295);
- f = h1 + st.pad[2] + bit32_rshift(f, 32);
- h1 = bit32_and(f, 4294967295);
- f = h2 + st.pad[3] + bit32_rshift(f, 32);
- h2 = bit32_and(f, 4294967295);
- f = h3 + st.pad[4] + bit32_rshift(f, 32);
- h3 = bit32_and(f, 4294967295);
- local mac = lendian_string_pack_to_ints("<I4I4I4I4", h0, h1, h2, h3);
- return mac;
- end
- local function poly_auth(m, k)
- assert(#k == 32);
- local st = poly_init(k);
- poly_update(st, m);
- local mac = poly_finish(st);
- return mac;
- end
- local function poly_verify(m, k, mac)
- local macm = poly_auth(m, k);
- return macm == mac;
- end
- local t = {
- init = poly_init,
- update = poly_update,
- finish = poly_finish,
- auth = poly_auth,
- verify = poly_verify,
- }
- function stringToASCII(str)
- local ascii = {}
- for i = 1, #str do
- table.insert(ascii, string.byte(str, i))
- end
- return ascii
- end
- function printStringAsASCII(str)
- local ascii = stringToASCII(str)
- for i = 1, #ascii do
- print(ascii[i])
- end
- end
- printStringAsASCII(t.auth("1234123412341234","12345678123456781234567812345678"))
Advertisement
Add Comment
Please, Sign In to add comment