jbe@499: #include jbe@499: #include jbe@499: #include "moonhash_sha3.c" jbe@499: jbe@499: void moonhash_push_hex(lua_State *L, unsigned char *buf, int len) { jbe@499: int i; jbe@499: unsigned char n; jbe@499: char str[2*len+1]; jbe@499: for (i=0; i> 4; jbe@499: str[2*i+0] = n + ((n < 10) ? '0' : ('a' - 10)); jbe@499: n = buf[i] & 0x0f; jbe@499: str[2*i+1] = n + ((n < 10) ? '0' : ('a' - 10)); jbe@499: } jbe@499: str[2*len] = 0; jbe@499: lua_pushstring(L, str); jbe@499: } jbe@499: jbe@499: typedef void (*moonhash_sha3_fptr)(const uint8_t *, uint64_t, uint8_t *); jbe@499: typedef void (*moonhash_shake_fptr)(const uint8_t *, uint64_t, uint8_t *, uint64_t); jbe@499: jbe@499: int moonhash_sha3(lua_State *L, moonhash_sha3_fptr hashfunc, int len) { jbe@499: const char *input; jbe@499: size_t inputlen; jbe@499: unsigned char output[len]; jbe@499: input = luaL_checklstring(L, 1, &inputlen); jbe@499: hashfunc((const uint8_t *)input, inputlen, output); jbe@499: moonhash_push_hex(L, output, len); jbe@499: return 1; jbe@499: } jbe@499: jbe@499: int moonhash_sha3_224(lua_State *L) { jbe@499: return moonhash_sha3(L, FIPS202_SHA3_224, 224/8); jbe@499: } jbe@499: int moonhash_sha3_256(lua_State *L) { jbe@499: return moonhash_sha3(L, FIPS202_SHA3_256, 256/8); jbe@499: } jbe@499: int moonhash_sha3_384(lua_State *L) { jbe@499: return moonhash_sha3(L, FIPS202_SHA3_384, 384/8); jbe@499: } jbe@499: int moonhash_sha3_512(lua_State *L) { jbe@499: return moonhash_sha3(L, FIPS202_SHA3_512, 512/8); jbe@499: } jbe@499: jbe@506: int moonhash_shake(lua_State *L, int R, lua_Integer deflen) { jbe@499: const char *input; jbe@499: size_t inputlen; jbe@506: lua_Integer outputlen; jbe@506: const char *alphabet; jbe@506: size_t alen; jbe@506: int abits = 0; jbe@506: uint8_t s[200]; jbe@506: luaL_Buffer luabuf; jbe@506: uint8_t *output; jbe@506: int readpos = 0; jbe@506: lua_Integer writepos = 0; jbe@506: int rbits = 0; jbe@506: int rbuf = 0; jbe@506: int rvalue; jbe@499: input = luaL_checklstring(L, 1, &inputlen); jbe@506: outputlen = luaL_optinteger(L, 2, deflen); jbe@506: alphabet = luaL_optlstring(L, 3, "0123456789abcdef", &alen); jbe@506: luaL_argcheck(L, alen>1, 3, "too few characters in alphabet"); jbe@506: { jbe@506: size_t t = alen-1; jbe@506: while (t) { jbe@506: abits++; jbe@506: if (abits > 8) luaL_argcheck(L, 0, 3, "too many characters in alphabet"); jbe@506: t >>= 1; jbe@506: } jbe@506: } jbe@506: KeccakF1600Init(s, R, (const uint8_t *)input, inputlen, 0x1F); jbe@506: output = (uint8_t *)luaL_buffinitsize(L, &luabuf, outputlen); jbe@506: while (writepos < outputlen) { jbe@506: if (rbits < abits) { jbe@506: if (readpos == R) { jbe@506: KeccakF1600(s); jbe@506: readpos = 0; jbe@506: } jbe@506: rbuf = (rbuf << 8) | s[readpos++]; jbe@506: rbits += 8; jbe@506: } jbe@506: rbits -= abits; jbe@506: rvalue = rbuf >> rbits; jbe@506: rbuf &= (1<