lua_monocypher.c 2.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596
  1. #include <stdlib.h>
  2. #include <stdbool.h>
  3. #include <lua.h>
  4. #include <lauxlib.h>
  5. #include "monocypher.h"
  6. static int new_blake2b (lua_State *L) {
  7. // Initialize an incremental blake2b hashing function.
  8. // lua api: blake2b_init([hash_size]) return iterator
  9. // hash_size: the optional length of the digest to be computed
  10. // (between 1 and 64) - default value is 64
  11. // iterator: opaque handle to be passed to blake2b_update().
  12. int hash_size = luaL_optinteger (L, 1, 64);
  13. if ((hash_size < 1)||(hash_size > 64))
  14. return luaL_error (L, "Bad digest size");
  15. crypto_blake2b_ctx *ctx = lua_newuserdatauv (L, sizeof (*ctx), 1);
  16. luaL_getmetatable (L, "monocypher.B2Context");
  17. lua_setmetatable (L, -2);
  18. crypto_blake2b_init (ctx, hash_size);
  19. return 1;
  20. }
  21. static int l_blake2b_update (lua_State *L) {
  22. // Update a blake2b hash.
  23. //
  24. // This function can be used to feed message data into a hash incrementally
  25. // in a streaming fashion.
  26. //
  27. // lua api: blake2b_update(it, m)
  28. // it: iterator handle obtained with blake2b_init().
  29. // m: the string to be hashed.
  30. size_t msg_size;
  31. crypto_blake2b_ctx *ctx = luaL_checkudata (L, 1, "monocypher.B2Context");
  32. const char *m = luaL_checklstring (L, 2, &msg_size);
  33. crypto_blake2b_update (ctx, m, msg_size);
  34. return 0;
  35. }
  36. static int l_blake2b_final (lua_State *L) {
  37. // Finalize a blake2b incremental hash and return the checksum.
  38. // lua_api blake2b_final(it) return digest
  39. // it: iterator handle obtained with blake2b_init().
  40. // digest: BLAKE2 hash.
  41. crypto_blake2b_ctx *ctx = luaL_checkudata (L, 1, "monocypher.B2Context");
  42. bool convert_hex = lua_toboolean (L, 2);
  43. printf ("Convert to hex: %d\n", convert_hex);
  44. unsigned char digest[64];
  45. size_t hash_size = ctx->hash_size;
  46. crypto_blake2b_final (ctx, digest);
  47. char *hex_hash;
  48. if (convert_hex) {
  49. size_t hash_hex_size = 2 * hash_size + 1;
  50. hex_hash = calloc (hash_hex_size, sizeof (*hex_hash));
  51. if (!hex_hash) return luaL_error (L, "Allocation error");
  52. for (size_t i = 0; i < hash_size; i++)
  53. sprintf (hex_hash + 2 * i, "%02x", digest[i]);
  54. lua_pushstring (L, hex_hash);
  55. } else lua_pushlstring (L, digest, hash_size);
  56. return 1;
  57. }
  58. static const luaL_Reg mc_lib_fn [] = {
  59. {"new_blake2b", new_blake2b},
  60. {NULL}
  61. };
  62. int luaopen_pocket_archive_monocypher (lua_State *L)
  63. {
  64. luaL_newmetatable (L, "monocypher");
  65. luaL_newmetatable (L, "monocypher.B2Context");
  66. lua_pushvalue (L, -1);
  67. lua_setfield (L, -2, "__index");
  68. lua_pushcfunction (L, l_blake2b_update);
  69. lua_setfield (L, -2, "update");
  70. lua_pushcfunction (L, l_blake2b_final);
  71. lua_setfield (L, -2, "final");
  72. luaL_newlib (L, mc_lib_fn);
  73. return 1;
  74. }