#include #include #include #include #include "monocypher.h" static int new_blake2b (lua_State *L) { // Initialize an incremental blake2b hashing function. // lua api: blake2b_init([hash_size]) return iterator // hash_size: the optional length of the digest to be computed // (between 1 and 64) - default value is 64 // iterator: opaque handle to be passed to blake2b_update(). int hash_size = luaL_optinteger (L, 1, 64); if ((hash_size < 1)||(hash_size > 64)) return luaL_error (L, "Bad digest size"); crypto_blake2b_ctx *ctx = lua_newuserdatauv (L, sizeof (*ctx), 1); luaL_getmetatable (L, "monocypher.B2Context"); lua_setmetatable (L, -2); crypto_blake2b_init (ctx, hash_size); return 1; } static int l_blake2b_update (lua_State *L) { // Update a blake2b hash. // // This function can be used to feed message data into a hash incrementally // in a streaming fashion. // // lua api: blake2b_update(it, m) // it: iterator handle obtained with blake2b_init(). // m: the string to be hashed. size_t msg_size; crypto_blake2b_ctx *ctx = luaL_checkudata (L, 1, "monocypher.B2Context"); const char *m = luaL_checklstring (L, 2, &msg_size); crypto_blake2b_update (ctx, m, msg_size); return 0; } static int l_blake2b_final (lua_State *L) { // Finalize a blake2b incremental hash and return the checksum. // lua_api blake2b_final(it) return digest // it: iterator handle obtained with blake2b_init(). // digest: BLAKE2 hash. crypto_blake2b_ctx *ctx = luaL_checkudata (L, 1, "monocypher.B2Context"); bool convert_hex = lua_toboolean (L, 2); printf ("Convert to hex: %d\n", convert_hex); unsigned char digest[64]; size_t hash_size = ctx->hash_size; crypto_blake2b_final (ctx, digest); char *hex_hash; if (convert_hex) { size_t hash_hex_size = 2 * hash_size + 1; hex_hash = calloc (hash_hex_size, sizeof (*hex_hash)); if (!hex_hash) return luaL_error (L, "Allocation error"); for (size_t i = 0; i < hash_size; i++) sprintf (hex_hash + 2 * i, "%02x", digest[i]); lua_pushstring (L, hex_hash); } else lua_pushlstring (L, digest, hash_size); return 1; } static const luaL_Reg mc_lib_fn [] = { {"new_blake2b", new_blake2b}, {NULL} }; int luaopen_pocket_archive_monocypher (lua_State *L) { luaL_newmetatable (L, "monocypher"); luaL_newmetatable (L, "monocypher.B2Context"); lua_pushvalue (L, -1); lua_setfield (L, -2, "__index"); lua_pushcfunction (L, l_blake2b_update); lua_setfield (L, -2, "update"); lua_pushcfunction (L, l_blake2b_final); lua_setfield (L, -2, "final"); luaL_newlib (L, mc_lib_fn); return 1; }