Last active
November 23, 2019 03:28
-
-
Save starwing/9781a8e16be29d514926102487777dcd to your computer and use it in GitHub Desktop.
A simple MD5 module for Lua
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#ifdef _MSC_VER | |
# define _CRT_SECURE_NO_WARNINGS | |
# define _CRT_NONSTDC_NO_WARNINGS | |
#endif | |
#define LUA_LIB | |
#include <lua.h> | |
#include <lauxlib.h> | |
#if LUA_VERSION_NUM < 502 | |
# define luaL_setfuncs(L,l,n) (assert(n==0), luaL_register(L,NULL,l)) | |
# define luaL_setmetatable(L, name) \ | |
(luaL_getmetatable((L), (name)), lua_setmetatable(L, -2)) | |
#endif | |
#include <stdint.h> | |
#include <string.h> | |
typedef struct { | |
uint64_t bytes; | |
uint32_t a, b, c, d; | |
uint8_t buffer[64]; | |
} md5_t; | |
#define F(x, y, z) ((z) ^ ((x) & ((y) ^ (z)))) | |
#define G(x, y, z) ((y) ^ ((z) & ((x) ^ (y)))) | |
#define H(x, y, z) ((x) ^ (y) ^ (z)) | |
#define I(x, y, z) ((y) ^ ((x) | ~(z))) | |
#define STEP(f, a, b, c, d, x, t, s) \ | |
(a) += f((b), (c), (d)) + (x) + (t); \ | |
(a) = (((a) << (s)) | (((a) & 0xffffffff) >> (32 - (s)))); \ | |
(a) += (b) | |
#define SET(n) \ | |
(block[n] = \ | |
((uint32_t)p[n*4 ] ) | \ | |
((uint32_t)p[n*4 + 1] << 8) | \ | |
((uint32_t)p[n*4 + 2] << 16) | \ | |
((uint32_t)p[n*4 + 3] << 24)) | |
#define GET(n) block[n] | |
#define DUMP(r, n, a) \ | |
r[n*4 ] = (uint8_t)((a) ); \ | |
r[n*4 + 1] = (uint8_t)((a) >> 8); \ | |
r[n*4 + 2] = (uint8_t)((a) >> 16); \ | |
r[n*4 + 3] = (uint8_t)((a) >> 24); | |
static const uint8_t *md5_body(md5_t *ctx, const uint8_t *data, size_t size) { | |
const uint8_t *p = (const uint8_t*)data; | |
uint32_t a, b, c, d; | |
a = ctx->a, b = ctx->b, c = ctx->c, d = ctx->d; | |
do { | |
uint32_t oa = a, ob = b, oc = c, od = d; | |
uint32_t block[16]; | |
/* Transformations */ | |
STEP(F, a, b, c, d, SET(0), 0xd76aa478, 7); | |
STEP(F, d, a, b, c, SET(1), 0xe8c7b756, 12); | |
STEP(F, c, d, a, b, SET(2), 0x242070db, 17); | |
STEP(F, b, c, d, a, SET(3), 0xc1bdceee, 22); | |
STEP(F, a, b, c, d, SET(4), 0xf57c0faf, 7); | |
STEP(F, d, a, b, c, SET(5), 0x4787c62a, 12); | |
STEP(F, c, d, a, b, SET(6), 0xa8304613, 17); | |
STEP(F, b, c, d, a, SET(7), 0xfd469501, 22); | |
STEP(F, a, b, c, d, SET(8), 0x698098d8, 7); | |
STEP(F, d, a, b, c, SET(9), 0x8b44f7af, 12); | |
STEP(F, c, d, a, b, SET(10), 0xffff5bb1, 17); | |
STEP(F, b, c, d, a, SET(11), 0x895cd7be, 22); | |
STEP(F, a, b, c, d, SET(12), 0x6b901122, 7); | |
STEP(F, d, a, b, c, SET(13), 0xfd987193, 12); | |
STEP(F, c, d, a, b, SET(14), 0xa679438e, 17); | |
STEP(F, b, c, d, a, SET(15), 0x49b40821, 22); | |
STEP(G, a, b, c, d, GET(1), 0xf61e2562, 5); | |
STEP(G, d, a, b, c, GET(6), 0xc040b340, 9); | |
STEP(G, c, d, a, b, GET(11), 0x265e5a51, 14); | |
STEP(G, b, c, d, a, GET(0), 0xe9b6c7aa, 20); | |
STEP(G, a, b, c, d, GET(5), 0xd62f105d, 5); | |
STEP(G, d, a, b, c, GET(10), 0x02441453, 9); | |
STEP(G, c, d, a, b, GET(15), 0xd8a1e681, 14); | |
STEP(G, b, c, d, a, GET(4), 0xe7d3fbc8, 20); | |
STEP(G, a, b, c, d, GET(9), 0x21e1cde6, 5); | |
STEP(G, d, a, b, c, GET(14), 0xc33707d6, 9); | |
STEP(G, c, d, a, b, GET(3), 0xf4d50d87, 14); | |
STEP(G, b, c, d, a, GET(8), 0x455a14ed, 20); | |
STEP(G, a, b, c, d, GET(13), 0xa9e3e905, 5); | |
STEP(G, d, a, b, c, GET(2), 0xfcefa3f8, 9); | |
STEP(G, c, d, a, b, GET(7), 0x676f02d9, 14); | |
STEP(G, b, c, d, a, GET(12), 0x8d2a4c8a, 20); | |
STEP(H, a, b, c, d, GET(5), 0xfffa3942, 4); | |
STEP(H, d, a, b, c, GET(8), 0x8771f681, 11); | |
STEP(H, c, d, a, b, GET(11), 0x6d9d6122, 16); | |
STEP(H, b, c, d, a, GET(14), 0xfde5380c, 23); | |
STEP(H, a, b, c, d, GET(1), 0xa4beea44, 4); | |
STEP(H, d, a, b, c, GET(4), 0x4bdecfa9, 11); | |
STEP(H, c, d, a, b, GET(7), 0xf6bb4b60, 16); | |
STEP(H, b, c, d, a, GET(10), 0xbebfbc70, 23); | |
STEP(H, a, b, c, d, GET(13), 0x289b7ec6, 4); | |
STEP(H, d, a, b, c, GET(0), 0xeaa127fa, 11); | |
STEP(H, c, d, a, b, GET(3), 0xd4ef3085, 16); | |
STEP(H, b, c, d, a, GET(6), 0x04881d05, 23); | |
STEP(H, a, b, c, d, GET(9), 0xd9d4d039, 4); | |
STEP(H, d, a, b, c, GET(12), 0xe6db99e5, 11); | |
STEP(H, c, d, a, b, GET(15), 0x1fa27cf8, 16); | |
STEP(H, b, c, d, a, GET(2), 0xc4ac5665, 23); | |
STEP(I, a, b, c, d, GET(0), 0xf4292244, 6); | |
STEP(I, d, a, b, c, GET(7), 0x432aff97, 10); | |
STEP(I, c, d, a, b, GET(14), 0xab9423a7, 15); | |
STEP(I, b, c, d, a, GET(5), 0xfc93a039, 21); | |
STEP(I, a, b, c, d, GET(12), 0x655b59c3, 6); | |
STEP(I, d, a, b, c, GET(3), 0x8f0ccc92, 10); | |
STEP(I, c, d, a, b, GET(10), 0xffeff47d, 15); | |
STEP(I, b, c, d, a, GET(1), 0x85845dd1, 21); | |
STEP(I, a, b, c, d, GET(8), 0x6fa87e4f, 6); | |
STEP(I, d, a, b, c, GET(15), 0xfe2ce6e0, 10); | |
STEP(I, c, d, a, b, GET(6), 0xa3014314, 15); | |
STEP(I, b, c, d, a, GET(13), 0x4e0811a1, 21); | |
STEP(I, a, b, c, d, GET(4), 0xf7537e82, 6); | |
STEP(I, d, a, b, c, GET(11), 0xbd3af235, 10); | |
STEP(I, c, d, a, b, GET(2), 0x2ad7d2bb, 15); | |
STEP(I, b, c, d, a, GET(9), 0xeb86d391, 21); | |
a += oa, b += ob, c += oc, d += od; | |
p += 64; | |
} while (size -= 64); | |
ctx->a = a, ctx->b = b, ctx->c = c, ctx->d = d; | |
return p; | |
} | |
static void md5_init(md5_t *ctx) { | |
ctx->a = 0x67452301; | |
ctx->b = 0xefcdab89; | |
ctx->c = 0x98badcfe; | |
ctx->d = 0x10325476; | |
ctx->bytes = 0; | |
} | |
static void md5_update(md5_t *ctx, const void *data, size_t size) { | |
size_t used = ctx->bytes & 0x3f; | |
ctx->bytes += size; | |
if (used) { | |
size_t free = 64 - used; | |
if (size < free) { | |
memcpy(&ctx->buffer[used], data, size); | |
return; | |
} | |
memcpy(&ctx->buffer[used], data, free); | |
data = (uint8_t*)data + free; | |
size -= free; | |
md5_body(ctx, ctx->buffer, 64); | |
} | |
if (size >= 64) { | |
data = md5_body(ctx, data, size & ~(size_t) 0x3f); | |
size &= 0x3f; | |
} | |
memcpy(ctx->buffer, data, size); | |
} | |
static void md5_finish(md5_t *ctx, uint8_t result[16]) { | |
size_t used = ctx->bytes & 0x3f; | |
size_t free = 64 - used - 1; | |
ctx->buffer[used++] = 0x80; | |
if (free < 8) { | |
memset(&ctx->buffer[used], 0, free); | |
md5_body(ctx, ctx->buffer, 64); | |
used = 0, free = 64; | |
} | |
memset(&ctx->buffer[used], 0, free - 8); | |
ctx->bytes <<= 3; | |
DUMP(ctx->buffer, 14, ctx->bytes ); | |
DUMP(ctx->buffer, 15, ctx->bytes >> 32); | |
md5_body(ctx, ctx->buffer, 64); | |
DUMP(result, 0, ctx->a); | |
DUMP(result, 1, ctx->b); | |
DUMP(result, 2, ctx->c); | |
DUMP(result, 3, ctx->d); | |
} | |
#define MD5_TYPE "md5.Object" | |
static void update(md5_t *md5, lua_State *L, int i, int top) { | |
for (; i <= top; ++i) { | |
size_t len; | |
const char *s = luaL_checklstring(L, i, &len); | |
md5_update(md5, s, len); | |
} | |
} | |
static int Lnew(lua_State *L) { | |
int top = lua_gettop(L); | |
md5_t *md5 = (md5_t*)lua_newuserdata(L, sizeof(md5_t)); | |
md5_init(md5); | |
luaL_setmetatable(L, MD5_TYPE); | |
update(md5, L, 1, top); | |
return 1; | |
} | |
static int Lupdate(lua_State *L) { | |
md5_t *md5 = (md5_t*)luaL_checkudata(L, 1, MD5_TYPE); | |
update(md5, L, 2, lua_gettop(L)); | |
lua_settop(L, 1); | |
return 1; | |
} | |
static int Lfinish(lua_State *L) { | |
md5_t *md5 = (md5_t*)luaL_checkudata(L, 1, MD5_TYPE); | |
uint8_t result[16]; | |
update(md5, L, 2, lua_gettop(L)); | |
md5_finish(md5, result); | |
md5_init(md5); | |
lua_pushlstring(L, (const char*)result, 16); | |
return 1; | |
} | |
static int push_hexa(lua_State *L, const char *s, size_t len) { | |
const char *hexa = "0123456789ABCDEF"; | |
size_t i; | |
luaL_Buffer B; | |
luaL_buffinit(L, &B); | |
for (i = 0; i < len; ++i) { | |
char *p = luaL_prepbuffer(&B); | |
*p++ = hexa[(s[i] >> 4) & 0xF]; | |
*p++ = hexa[(s[i] >> 0) & 0xF]; | |
luaL_addsize(&B, 2); | |
} | |
luaL_pushresult(&B); | |
return 1; | |
} | |
static void sum(lua_State *L, uint8_t result[16]) { | |
md5_t md5; | |
md5_init(&md5); | |
update(&md5, L, 1, lua_gettop(L)); | |
md5_finish(&md5, result); | |
} | |
static int Lsum(lua_State *L) { | |
uint8_t result[16]; | |
sum(L, result); | |
lua_pushlstring(L, (const char*)result, 16); | |
return 1; | |
} | |
static int Lsumhexa(lua_State *L) { | |
uint8_t result[16]; | |
sum(L, result); | |
return push_hexa(L, (const char*)result, 16); | |
} | |
static int Ltohex(lua_State *L) { | |
size_t len; | |
const char *s = luaL_checklstring(L, 1, &len); | |
return push_hexa(L, s, len); | |
} | |
LUALIB_API int luaopen_md5(lua_State *L) { | |
luaL_Reg libs[] = { | |
#define ENTRY(name) { #name, L##name } | |
ENTRY(new), | |
ENTRY(sum), | |
ENTRY(sumhexa), | |
ENTRY(tohex), | |
ENTRY(update), | |
ENTRY(finish), | |
#undef ENTRY | |
{ NULL, NULL } | |
}; | |
if (luaL_newmetatable(L, MD5_TYPE)) { | |
luaL_setfuncs(L, libs, 0); | |
lua_pushvalue(L, -1); | |
lua_setfield(L, -2, "__index"); | |
} | |
return 1; | |
} | |
/* cc: flags+='-O3 -ggdb -pedantic -std=c90 -Wall -Wextra --coverage' | |
* maccc: flags+='-shared -undefined dynamic_lookup' output='md5.so' | |
* win32cc: flags+='-s -mdll -DLUA_BUILD_AS_DLL ' output='md5.dll' libs+='-llua53' */ | |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#ifdef _MSC_VER | |
# define _CRT_SECURE_NO_WARNINGS | |
# define _CRT_NONSTDC_NO_WARNINGS | |
#endif | |
#define LUA_LIB | |
#include <lua.h> | |
#include <lauxlib.h> | |
#if LUA_VERSION_NUM < 502 | |
# define luaL_setfuncs(L,l,n) (assert(n==0), luaL_register(L,NULL,l)) | |
# define luaL_setmetatable(L, name) \ | |
(luaL_getmetatable((L), (name)), lua_setmetatable(L, -2)) | |
#endif | |
#include <stdint.h> | |
#include <string.h> | |
typedef struct { | |
uint64_t bytes; | |
uint32_t a, b, c, d, e, f; | |
uint8_t buffer[64]; | |
} sha1_t; | |
#define F(b, c, d) (((b) & (c)) | ((~(b)) & (d))) | |
#define G(b, c, d) ((b) ^ (c) ^ (d)) | |
#define H(b, c, d) (((b) & (c)) | ((b) & (d)) | ((c) & (d))) | |
#define I(b, c, d) G(b, c, d) | |
#define ROTATE(bits, word) (((word) << (bits)) | ((word) >> (32 - (bits)))) | |
#define STEP(f, a, b, c, d, e, w, t) \ | |
temp = ROTATE(5, (a)) + f((b), (c), (d)) + (e) + (w) + (t); \ | |
(e) = (d); (d) = (c); \ | |
(c) = ROTATE(30, (b)); \ | |
(b) = (a); (a) = temp; | |
#define GET(n) \ | |
((uint32_t)p[n*4 + 3] | \ | |
((uint32_t)p[n*4 + 2] << 8) | \ | |
((uint32_t)p[n*4 + 1] << 16) | \ | |
((uint32_t)p[n*4 ] << 24)) | |
#define DUMP(r, n, a) \ | |
r[n*4 ] = (uint8_t)((a) >> 24); \ | |
r[n*4 + 1] = (uint8_t)((a) >> 16); \ | |
r[n*4 + 2] = (uint8_t)((a) >> 8); \ | |
r[n*4 + 3] = (uint8_t)((a) ); | |
static const uint8_t *sha1_body(sha1_t *ctx, const void *data, size_t size) { | |
const uint8_t *p = (const uint8_t*)data; | |
uint32_t a, b, c, d, e, temp; | |
a = ctx->a, b = ctx->b, c = ctx->c, d = ctx->d, e = ctx->e; | |
do { | |
uint32_t oa = a, ob = b, oc = c, od = d, oe = e; | |
uint32_t words[80]; | |
size_t i; | |
/* Load data block into the words array */ | |
for (i = 0; i < 16; i++) | |
words[i] = GET(i); | |
for (i = 16; i < 80; i++) | |
words[i] = ROTATE(1, words[i - 3] | |
^ words[i - 8] | |
^ words[i - 14] | |
^ words[i - 16]); | |
/* Transformations */ | |
STEP(F, a, b, c, d, e, words[0], 0x5a827999); | |
STEP(F, a, b, c, d, e, words[1], 0x5a827999); | |
STEP(F, a, b, c, d, e, words[2], 0x5a827999); | |
STEP(F, a, b, c, d, e, words[3], 0x5a827999); | |
STEP(F, a, b, c, d, e, words[4], 0x5a827999); | |
STEP(F, a, b, c, d, e, words[5], 0x5a827999); | |
STEP(F, a, b, c, d, e, words[6], 0x5a827999); | |
STEP(F, a, b, c, d, e, words[7], 0x5a827999); | |
STEP(F, a, b, c, d, e, words[8], 0x5a827999); | |
STEP(F, a, b, c, d, e, words[9], 0x5a827999); | |
STEP(F, a, b, c, d, e, words[10], 0x5a827999); | |
STEP(F, a, b, c, d, e, words[11], 0x5a827999); | |
STEP(F, a, b, c, d, e, words[12], 0x5a827999); | |
STEP(F, a, b, c, d, e, words[13], 0x5a827999); | |
STEP(F, a, b, c, d, e, words[14], 0x5a827999); | |
STEP(F, a, b, c, d, e, words[15], 0x5a827999); | |
STEP(F, a, b, c, d, e, words[16], 0x5a827999); | |
STEP(F, a, b, c, d, e, words[17], 0x5a827999); | |
STEP(F, a, b, c, d, e, words[18], 0x5a827999); | |
STEP(F, a, b, c, d, e, words[19], 0x5a827999); | |
STEP(G, a, b, c, d, e, words[20], 0x6ed9eba1); | |
STEP(G, a, b, c, d, e, words[21], 0x6ed9eba1); | |
STEP(G, a, b, c, d, e, words[22], 0x6ed9eba1); | |
STEP(G, a, b, c, d, e, words[23], 0x6ed9eba1); | |
STEP(G, a, b, c, d, e, words[24], 0x6ed9eba1); | |
STEP(G, a, b, c, d, e, words[25], 0x6ed9eba1); | |
STEP(G, a, b, c, d, e, words[26], 0x6ed9eba1); | |
STEP(G, a, b, c, d, e, words[27], 0x6ed9eba1); | |
STEP(G, a, b, c, d, e, words[28], 0x6ed9eba1); | |
STEP(G, a, b, c, d, e, words[29], 0x6ed9eba1); | |
STEP(G, a, b, c, d, e, words[30], 0x6ed9eba1); | |
STEP(G, a, b, c, d, e, words[31], 0x6ed9eba1); | |
STEP(G, a, b, c, d, e, words[32], 0x6ed9eba1); | |
STEP(G, a, b, c, d, e, words[33], 0x6ed9eba1); | |
STEP(G, a, b, c, d, e, words[34], 0x6ed9eba1); | |
STEP(G, a, b, c, d, e, words[35], 0x6ed9eba1); | |
STEP(G, a, b, c, d, e, words[36], 0x6ed9eba1); | |
STEP(G, a, b, c, d, e, words[37], 0x6ed9eba1); | |
STEP(G, a, b, c, d, e, words[38], 0x6ed9eba1); | |
STEP(G, a, b, c, d, e, words[39], 0x6ed9eba1); | |
STEP(H, a, b, c, d, e, words[40], 0x8f1bbcdc); | |
STEP(H, a, b, c, d, e, words[41], 0x8f1bbcdc); | |
STEP(H, a, b, c, d, e, words[42], 0x8f1bbcdc); | |
STEP(H, a, b, c, d, e, words[43], 0x8f1bbcdc); | |
STEP(H, a, b, c, d, e, words[44], 0x8f1bbcdc); | |
STEP(H, a, b, c, d, e, words[45], 0x8f1bbcdc); | |
STEP(H, a, b, c, d, e, words[46], 0x8f1bbcdc); | |
STEP(H, a, b, c, d, e, words[47], 0x8f1bbcdc); | |
STEP(H, a, b, c, d, e, words[48], 0x8f1bbcdc); | |
STEP(H, a, b, c, d, e, words[49], 0x8f1bbcdc); | |
STEP(H, a, b, c, d, e, words[50], 0x8f1bbcdc); | |
STEP(H, a, b, c, d, e, words[51], 0x8f1bbcdc); | |
STEP(H, a, b, c, d, e, words[52], 0x8f1bbcdc); | |
STEP(H, a, b, c, d, e, words[53], 0x8f1bbcdc); | |
STEP(H, a, b, c, d, e, words[54], 0x8f1bbcdc); | |
STEP(H, a, b, c, d, e, words[55], 0x8f1bbcdc); | |
STEP(H, a, b, c, d, e, words[56], 0x8f1bbcdc); | |
STEP(H, a, b, c, d, e, words[57], 0x8f1bbcdc); | |
STEP(H, a, b, c, d, e, words[58], 0x8f1bbcdc); | |
STEP(H, a, b, c, d, e, words[59], 0x8f1bbcdc); | |
STEP(I, a, b, c, d, e, words[60], 0xca62c1d6); | |
STEP(I, a, b, c, d, e, words[61], 0xca62c1d6); | |
STEP(I, a, b, c, d, e, words[62], 0xca62c1d6); | |
STEP(I, a, b, c, d, e, words[63], 0xca62c1d6); | |
STEP(I, a, b, c, d, e, words[64], 0xca62c1d6); | |
STEP(I, a, b, c, d, e, words[65], 0xca62c1d6); | |
STEP(I, a, b, c, d, e, words[66], 0xca62c1d6); | |
STEP(I, a, b, c, d, e, words[67], 0xca62c1d6); | |
STEP(I, a, b, c, d, e, words[68], 0xca62c1d6); | |
STEP(I, a, b, c, d, e, words[69], 0xca62c1d6); | |
STEP(I, a, b, c, d, e, words[70], 0xca62c1d6); | |
STEP(I, a, b, c, d, e, words[71], 0xca62c1d6); | |
STEP(I, a, b, c, d, e, words[72], 0xca62c1d6); | |
STEP(I, a, b, c, d, e, words[73], 0xca62c1d6); | |
STEP(I, a, b, c, d, e, words[74], 0xca62c1d6); | |
STEP(I, a, b, c, d, e, words[75], 0xca62c1d6); | |
STEP(I, a, b, c, d, e, words[76], 0xca62c1d6); | |
STEP(I, a, b, c, d, e, words[77], 0xca62c1d6); | |
STEP(I, a, b, c, d, e, words[78], 0xca62c1d6); | |
STEP(I, a, b, c, d, e, words[79], 0xca62c1d6); | |
a += oa, b += ob, c += oc, d += od, e += oe; | |
p += 64; | |
} while (size -= 64); | |
ctx->a = a, ctx->b = b, ctx->c = c, ctx->d = d, ctx->e = e; | |
return p; | |
} | |
static void sha1_init(sha1_t *ctx) { | |
ctx->a = 0x67452301; | |
ctx->b = 0xefcdab89; | |
ctx->c = 0x98badcfe; | |
ctx->d = 0x10325476; | |
ctx->e = 0xc3d2e1f0; | |
ctx->bytes = 0; | |
} | |
static void sha1_update(sha1_t *ctx, const void *data, size_t size) { | |
size_t used = ctx->bytes & 0x3f; | |
ctx->bytes += size; | |
if (used) { | |
size_t free = 64 - used; | |
if (size < free) { | |
memcpy(&ctx->buffer[used], data, size); | |
return; | |
} | |
memcpy(&ctx->buffer[used], data, free); | |
data = (uint8_t*)data + free; | |
size -= free; | |
sha1_body(ctx, ctx->buffer, 64); | |
} | |
if (size >= 64) { | |
data = sha1_body(ctx, data, size & ~(size_t)0x3f); | |
size &= 0x3f; | |
} | |
memcpy(ctx->buffer, data, size); | |
} | |
static void sha1_finish(sha1_t *ctx, uint8_t result[20]) { | |
size_t used = ctx->bytes & 0x3f; | |
size_t free = 64 - used - 1; | |
ctx->buffer[used++] = 0x80; | |
if (free < 8) { | |
memset(&ctx->buffer[used], 0, free); | |
sha1_body(ctx, ctx->buffer, 64); | |
used = 0, free = 64; | |
} | |
memset(&ctx->buffer[used], 0, free - 8); | |
ctx->bytes <<= 3; | |
DUMP(ctx->buffer, 14, ctx->bytes >> 32); | |
DUMP(ctx->buffer, 15, ctx->bytes ); | |
sha1_body(ctx, ctx->buffer, 64); | |
DUMP(result, 0, ctx->a); | |
DUMP(result, 1, ctx->b); | |
DUMP(result, 2, ctx->c); | |
DUMP(result, 3, ctx->d); | |
DUMP(result, 4, ctx->e); | |
} | |
#define SHA1_TYPE "sha1.Object" | |
static void update(sha1_t *sha1, lua_State *L, int i, int top) { | |
for (; i <= top; ++i) { | |
size_t len; | |
const char *s = luaL_checklstring(L, i, &len); | |
sha1_update(sha1, s, len); | |
} | |
} | |
static int Lnew(lua_State *L) { | |
int top = lua_gettop(L); | |
sha1_t *sha1 = (sha1_t*)lua_newuserdata(L, sizeof(sha1_t)); | |
sha1_init(sha1); | |
luaL_setmetatable(L, SHA1_TYPE); | |
update(sha1, L, 1, top); | |
return 1; | |
} | |
static int Lupdate(lua_State *L) { | |
sha1_t *sha1 = (sha1_t*)luaL_checkudata(L, 1, SHA1_TYPE); | |
update(sha1, L, 2, lua_gettop(L)); | |
lua_settop(L, 1); | |
return 1; | |
} | |
static int Lfinish(lua_State *L) { | |
sha1_t *sha1 = (sha1_t*)luaL_checkudata(L, 1, SHA1_TYPE); | |
uint8_t result[20]; | |
update(sha1, L, 2, lua_gettop(L)); | |
sha1_finish(sha1, result); | |
sha1_init(sha1); | |
lua_pushlstring(L, (const char*)result, 20); | |
return 1; | |
} | |
static int push_hexa(lua_State *L, const char *s, size_t len) { | |
const char *hexa = "0123456789ABCDEF"; | |
size_t i; | |
luaL_Buffer B; | |
luaL_buffinit(L, &B); | |
for (i = 0; i < len; ++i) { | |
char *p = luaL_prepbuffer(&B); | |
*p++ = hexa[(s[i] >> 4) & 0xF]; | |
*p++ = hexa[(s[i] >> 0) & 0xF]; | |
luaL_addsize(&B, 2); | |
} | |
luaL_pushresult(&B); | |
return 1; | |
} | |
static void sum(lua_State *L, uint8_t result[20]) { | |
sha1_t sha1; | |
sha1_init(&sha1); | |
update(&sha1, L, 1, lua_gettop(L)); | |
sha1_finish(&sha1, result); | |
} | |
static int Lsum(lua_State *L) { | |
uint8_t result[20]; | |
sum(L, result); | |
lua_pushlstring(L, (const char*)result, 20); | |
return 1; | |
} | |
static int Lsumhexa(lua_State *L) { | |
uint8_t result[20]; | |
sum(L, result); | |
return push_hexa(L, (const char*)result, 20); | |
} | |
static int Ltohex(lua_State *L) { | |
size_t len; | |
const char *s = luaL_checklstring(L, 1, &len); | |
return push_hexa(L, s, len); | |
} | |
LUALIB_API int luaopen_sha1(lua_State *L) { | |
luaL_Reg libs[] = { | |
#define ENTRY(name) { #name, L##name } | |
ENTRY(new), | |
ENTRY(sum), | |
ENTRY(sumhexa), | |
ENTRY(tohex), | |
ENTRY(update), | |
ENTRY(finish), | |
#undef ENTRY | |
{ NULL, NULL } | |
}; | |
if (luaL_newmetatable(L, SHA1_TYPE)) { | |
luaL_setfuncs(L, libs, 0); | |
lua_pushvalue(L, -1); | |
lua_setfield(L, -2, "__index"); | |
} | |
return 1; | |
} | |
/* cc: flags+='-O3 -ggdb -pedantic -std=c90 -Wall -Wextra --coverage' | |
* maccc: flags+='-shared -undefined dynamic_lookup' output='sha1.so' | |
* win32cc: flags+='-s -mdll -DLUA_BUILD_AS_DLL ' output='sha1.dll' libs+='-llua53' */ | |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment