# HG changeset patch # User jbe # Date 1502836271 -7200 # Node ID 83b3882dc31be6213a4b1804eab048c9516e5190 # Parent b53dee61a930e0cb08af3942c771ab545c3ea555 New functions moonhash.shake128(data, len, alphabet), moonhash.shake256(data, len, alphabet) Removed moonhash.shake128_128(...) diff -r b53dee61a930 -r 83b3882dc31b libraries/moonhash/moonhash.autodoc.lua --- a/libraries/moonhash/moonhash.autodoc.lua Tue Aug 15 21:00:51 2017 +0200 +++ b/libraries/moonhash/moonhash.autodoc.lua Wed Aug 16 00:31:11 2017 +0200 @@ -51,15 +51,31 @@ --[[-- -hash = -- 128 bits of SHAKE128 digest (in hex notation) of input string -moonhash.shake128_128( - data -- input string +hash = -- SHAKE128 digest of input string +moonhash.shake128( + input_data, -- input string + output_length, -- number of characters (not bytes or bits) in output, defaults to 32 + output_alphabet -- characters for encoding, defaults to "0123456789abcdef" for hex encoding ) -Calculates the first 128 bits of the SHAKE128 digest (FIPS 202) with a security of 64 bits for collision attacks and 128 bits for preimage and second preimage attacks. +Calculates a SHAKE128 digest (FIPS 202) with a security of math.min(128, math.log(#output_alphabet, 2) * output_length/2) for collision attacks and math.min(128, math.log(#output_alphabet, 2) * output_length) for preimage and second preimage attacks. If #output_alphabet is a power of 2, a direct base-N encoding is performed. Otherwise, a base-N encoding with N equal to the next higher power of 2 is performed, and all character values smaller than or equal to #output_alphabet are discarded from the stream (the process is repeated until the hash length reaches the required output_length). --]]-- -- Implemented in moonhash.c and moonhash_sha3.c --//-- +--[[-- +hash = -- SHAKE256 digest of input string +moonhash.shake256( + input_data, -- input string + output_length, -- number of characters (not bytes or bits) in output, defaults to 64 + output_alphabet -- characters for encoding, defaults to "0123456789abcdef" for hex encoding +) + +Calculates a SHAKE256 digest (FIPS 202) with a security of math.min(256, math.log(#output_alphabet, 2) * output_length/2) for collision attacks and math.min(256, math.log(#output_alphabet, 2) * output_length) for preimage and second preimage attacks. If #output_alphabet is a power of 2, a direct base-N encoding is performed. Otherwise, a base-N encoding with N equal to the next higher power of 2 is performed, and all character values smaller than or equal to #output_alphabet are discarded from the stream (the process is repeated until the hash length reaches the required output_length). + +--]]-- +-- Implemented in moonhash.c and moonhash_sha3.c +--//-- + diff -r b53dee61a930 -r 83b3882dc31b libraries/moonhash/moonhash.c --- a/libraries/moonhash/moonhash.c Tue Aug 15 21:00:51 2017 +0200 +++ b/libraries/moonhash/moonhash.c Wed Aug 16 00:31:11 2017 +0200 @@ -42,18 +42,59 @@ return moonhash_sha3(L, FIPS202_SHA3_512, 512/8); } -int moonhash_shake(lua_State *L, moonhash_shake_fptr shakefunc, int len) { +int moonhash_shake(lua_State *L, int R, lua_Integer deflen) { const char *input; size_t inputlen; - unsigned char output[len]; + lua_Integer outputlen; + const char *alphabet; + size_t alen; + int abits = 0; + uint8_t s[200]; + luaL_Buffer luabuf; + uint8_t *output; + int readpos = 0; + lua_Integer writepos = 0; + int rbits = 0; + int rbuf = 0; + int rvalue; input = luaL_checklstring(L, 1, &inputlen); - shakefunc((const uint8_t *)input, inputlen, output, len); - moonhash_push_hex(L, output, len); + outputlen = luaL_optinteger(L, 2, deflen); + alphabet = luaL_optlstring(L, 3, "0123456789abcdef", &alen); + luaL_argcheck(L, alen>1, 3, "too few characters in alphabet"); + { + size_t t = alen-1; + while (t) { + abits++; + if (abits > 8) luaL_argcheck(L, 0, 3, "too many characters in alphabet"); + t >>= 1; + } + } + KeccakF1600Init(s, R, (const uint8_t *)input, inputlen, 0x1F); + output = (uint8_t *)luaL_buffinitsize(L, &luabuf, outputlen); + while (writepos < outputlen) { + if (rbits < abits) { + if (readpos == R) { + KeccakF1600(s); + readpos = 0; + } + rbuf = (rbuf << 8) | s[readpos++]; + rbits += 8; + } + rbits -= abits; + rvalue = rbuf >> rbits; + rbuf &= (1<