diff options
| author | ame <[email protected]> | 2024-03-13 16:03:10 -0500 |
|---|---|---|
| committer | ame <[email protected]> | 2024-03-13 16:03:10 -0500 |
| commit | cf36c993ba4bb931ecf9c84de41ab0bc5fc915e4 (patch) | |
| tree | 6e7f5619f468e5b4e34378def3e9f2960d909b38 | |
| parent | 74289579ac66890ef0d7df2a5ec5f15f8308b8cd (diff) | |
blake2{b,s} and maybe other stuff
| -rw-r--r-- | docs/crypto.md | 4 | ||||
| -rw-r--r-- | docs/net.md | 320 | ||||
| -rw-r--r-- | docs/readme.md | 48 | ||||
| -rw-r--r-- | readme.md | 74 | ||||
| -rw-r--r-- | src/crypto.h | 3 | ||||
| -rw-r--r-- | src/hash/blake2.c | 261 | ||||
| -rw-r--r-- | src/hash/blake2.h | 21 | ||||
| -rw-r--r-- | src/types/map.c | 268 | ||||
| -rw-r--r-- | src/types/map.h | 58 | ||||
| -rw-r--r-- | src/types/str.c | 132 | ||||
| -rw-r--r-- | tests/hash.lua | 17 |
11 files changed, 751 insertions, 455 deletions
diff --git a/docs/crypto.md b/docs/crypto.md index 997ede9..6a375b8 100644 --- a/docs/crypto.md +++ b/docs/crypto.md @@ -4,7 +4,7 @@ \* is optional -|name|out len|arg 2|extra| +|name|out len|other args|extra| |--|--|--|--| | sha0 | 160 | nil | insecure, use sha1| | sha1 | 160 | nil | | @@ -54,6 +54,8 @@ | spookyhash64_v2 | 64 | *seed | | | spookyhash32_v1 | 32 | *seed | | | spookyhash32_v2 | 32 | *seed | | +| blake2b | length of arg 2 * 8 | *output len (default is 64), *key | | +| blake2s | length of arg 2 * 8 | *output len (default is 32), *key | | ### usage diff --git a/docs/net.md b/docs/net.md index b4f749a..8becf4c 100644 --- a/docs/net.md +++ b/docs/net.md @@ -1,160 +1,160 @@ -# net - -## listen (PARTIALLY IMPLEMENTED) - -'takes a function with 1 argument and a integer for a port - -(intentionally styled after expressjs:3) -the function will be ran on initilization, the argument has info on the server and functions to set it up - -** -right now everything within a server:GET function is partially global, it can read global variables (by making a copy), -it can not read/copy local variables or modify globals -** - -```lua -llib.net.listen(function(server) - ... -end, 80) -``` - -### server:lock server:unlock - -continues on the current thread, but pauses all other threads at that point - -```lua -... -server:lock() ---do something with a global -server:unlock() -... -``` - -### server:close - -closes server - -### server:GET/POST/... - -'takes a string (the path) and a function to be ran in the background on request - -the function has 2 arguments, the first (res) contains functions and info about resolving the request, -the second (req) contains info on the request, the path allows for wildcards, multiple get requests per path is allowed - -the actual name of the function will change based on what request method you want to accept, all requests are treated the exact same on the backend, besides HEAD requests which will also use all GET requets, and the 'all' variant will get everything - -```lua -server:all("*", function(res, req, next) - if(req['Version'] ~= "HTTP/1.1") then - res:close() - end -end) - -... -server:GET("/", function(res, req) do - --version will always be 1.1, as per the middleware - ... -end) -... -``` - -#### res:write - -'takes a string - -sends the string to the client, constructs a header on first call (whether or not res.header._sent is null) -(the constructed header can not be changed later on in the request), and sends the string without closing the client - -```lua -... -res:write("<h1>hello world</h1>") -res:write("<h1>good bye world</h1>") -... -``` - -#### res:send - -'takes a string - -sends the string to the client, constructs a header then closes client_fd - -```lua -... -res:send("<h1>hello world</h1>") -... -``` - -#### res:close - -closes connection, sets res.client_fd to -1, any calls that use this value will fail - -#### res.header - -table containing all head information, anything added to it will be used, certain keys will affect other values or have other side effects on res:send, listed below - -|key|side effect| -|--|--| -|Code|Changes response note, ie: (200: OK)| - -```lua -... -res.header["Code"] = 404 -res.header["test"] = "wowa" --- new header will have a code of 404 (at the top duh) --- and a new field "test" --- --- HTTP/1.1 404 Not Found --- ... --- test: wowa -... -``` - -### res:serve ** - -'takes one string, which is a path that will be served, file or dir - -```lua -... -res:serve("./html/") -... -``` - -### req:roll - -'takes an integer of bytes to read & parse - -will update req according to how the bytes needed to be parsed, returns the number of bytes read (not necessarily parsed), 0 if there -is no more data, and any other values \< 0 is a recv error - -```lua ---when a request contains "hello world" -req.Body --"hello" -req:roll(30) --does not matter if you go over, returns 7 (probably) -req.Body --"hello world" -req:roll(50) --returns 0, no more to read ---req.Body has not been updated -``` - -can have unique results with files (this example is not perfect, roll could read less than 2 bytes, and this does not account for newlines) - -```lua ---sent a file ina request to the server, where the boundary is 'abcd': --- ---abcd --- (header junk, file name and stuff) --- --- wowa --- -- --- --ab --- --abcd - ---when the line 'wowa' has just been read, using roll for less than two will not update the file -req.Body -- (...)"wowa" -req:roll(2) -req.Body -- (...)"wowa" (unchanged) ---any lines that contain just the boundary and -'s will be put in a seperate buffer until it ends or breaks ---a previous condition, then it will be added -req:roll(2) -req.Body -- (...)"wowa\n--" ---and now "--" (from the next line) is in the possible boundary buffer, it ends in "ab" so it will be added to the main body -``` - +# net
+
+## listen (PARTIALLY IMPLEMENTED)
+
+'takes a function with 1 argument and a integer for a port
+
+(intentionally styled after expressjs:3)
+the function will be ran on initilization, the argument has info on the server and functions to set it up
+
+**
+right now everything within a server:GET function is partially global, it can read global variables (by making a copy),
+it can not read/copy local variables or modify globals
+**
+
+```lua
+llib.net.listen(function(server)
+ ...
+end, 80)
+```
+
+### server:lock server:unlock
+
+continues on the current thread, but pauses all other threads at that point
+
+```lua
+...
+server:lock()
+--do something with a global
+server:unlock()
+...
+```
+
+### server:close
+
+closes server
+
+### server:GET/POST/...
+
+'takes a string (the path) and a function to be ran in the background on request
+
+the function has 2 arguments, the first (res) contains functions and info about resolving the request,
+the second (req) contains info on the request, the path allows for wildcards, multiple get requests per path is allowed
+
+the actual name of the function will change based on what request method you want to accept, all requests are treated the exact same on the backend, besides HEAD requests which will also use all GET requets, and the 'all' variant will get everything
+
+```lua
+server:all("*", function(res, req, next)
+ if(req['Version'] ~= "HTTP/1.1") then
+ res:close()
+ end
+end)
+
+...
+server:GET("/", function(res, req) do
+ --version will always be 1.1, as per the middleware
+ ...
+end)
+...
+```
+
+#### res:write
+
+'takes a string
+
+sends the string to the client, constructs a header on first call (whether or not res.header._sent is null)
+(the constructed header can not be changed later on in the request), and sends the string without closing the client
+
+```lua
+...
+res:write("<h1>hello world</h1>")
+res:write("<h1>good bye world</h1>")
+...
+```
+
+#### res:send
+
+'takes a string
+
+sends the string to the client, constructs a header then closes client_fd
+
+```lua
+...
+res:send("<h1>hello world</h1>")
+...
+```
+
+#### res:close
+
+closes connection, sets res.client_fd to -1, any calls that use this value will fail
+
+#### res.header
+
+table containing all head information, anything added to it will be used, certain keys will affect other values or have other side effects on res:send, listed below
+
+|key|side effect|
+|--|--|
+|Code|Changes response note, ie: (200: OK)|
+
+```lua
+...
+res.header["Code"] = 404
+res.header["test"] = "wowa"
+-- new header will have a code of 404 (at the top duh)
+-- and a new field "test"
+--
+-- HTTP/1.1 404 Not Found
+-- ...
+-- test: wowa
+...
+```
+
+### res:serve **
+
+'takes one string, which is a path that will be served, file or dir
+
+```lua
+...
+res:serve("./html/")
+...
+```
+
+### req:roll
+
+'takes an integer of bytes to read & parse
+
+will update req according to how the bytes needed to be parsed, returns the number of bytes read (not necessarily parsed), 0 if there
+is no more data, and any other values \< 0 is a recv error
+
+```lua
+--when a request contains "hello world"
+req.Body --"hello"
+req:roll(30) --does not matter if you go over, returns 7 (probably)
+req.Body --"hello world"
+req:roll(50) --returns 0, no more to read
+--req.Body has not been updated
+```
+
+can have unique results with files (this example is not perfect, roll could read less than 2 bytes, and this does not account for newlines)
+
+```lua
+--sent a file ina request to the server, where the boundary is 'abcd':
+-- ---abcd
+-- (header junk, file name and stuff)
+--
+-- wowa
+-- --
+-- --ab
+-- --abcd
+
+--when the line 'wowa' has just been read, using roll for less than two will not update the file
+req.Body -- (...)"wowa"
+req:roll(2)
+req.Body -- (...)"wowa" (unchanged)
+--any lines that contain just the boundary and -'s will be put in a seperate buffer until it ends or breaks
+--a previous condition, then it will be added
+req:roll(2)
+req.Body -- (...)"wowa\n--"
+--and now "--" (from the next line) is in the possible boundary buffer, it ends in "ab" so it will be added to the main body
+```
+
diff --git a/docs/readme.md b/docs/readme.md index 18deebf..14859a5 100644 --- a/docs/readme.md +++ b/docs/readme.md @@ -1,24 +1,24 @@ -# lualib (llib) -(name subject to change) - -with the library in the same directory [(or one of the other valid search locations)](https://www.lua.org/pil/8.1.html) - -```lua -require "llib" -``` - -which makes a global llib table - -> ### future require versions will eventually return the table -> ```lua -> llib = require "llib" -> ``` - -the table has many subtables, with related function in them, you can view them like so - -```lua -llib.io.pprint(llib) --pprint is a part of the io module, pprint meaning pretty print -``` - -all subtables have a corresponding file in this directory, with info on its functions - +# lualib (llib)
+(name subject to change)
+
+with the library in the same directory [(or one of the other valid search locations)](https://www.lua.org/pil/8.1.html)
+
+```lua
+require "llib"
+```
+
+which makes a global llib table
+
+> ### future require versions will eventually return the table
+> ```lua
+> llib = require "llib"
+> ```
+
+the table has many subtables, with related function in them, you can view them like so
+
+```lua
+llib.io.pprint(llib) --pprint is a part of the io module, pprint meaning pretty print
+```
+
+all subtables have a corresponding file in this directory, with info on its functions
+
@@ -1,37 +1,37 @@ -build with `clang -shared src/{*.c,*/*.c} -o llib.so -fPIC` - -or `clang -shared src/{*.c,*/*.c} -o llib.dll -L/mingw64/lib -llua -lws2_32 -fPIC` for my msys2 build - -[some docs](docs/) - -todo: - -* (working on seperatley) gui for graphs - -* finish up http server - - * https - - * <res>:serve() - - * check memory saftey - - * memory optimizations - - * settings (parse/read files, etc..) - - * define usage of new routes inside of routes, and allow route removal - - * connection limit - -* more doxygen like docs, everywhere - -* make parray_t hash based - - ----- - -# credits - -* [luaproc](https://github.com/askyrme/luaproc) helped with multithreading - +build with `clang -shared src/{*.c,*/*.c} -o llib.so -fPIC`
+
+or `clang -shared src/{*.c,*/*.c} -o llib.dll -L/mingw64/lib -llua -lws2_32 -fPIC` for my msys2 build
+
+[some docs](docs/)
+
+todo:
+
+* (working on seperatley) gui for graphs
+
+* finish up http server
+
+ * https
+
+ * <res>:serve()
+
+ * check memory saftey
+
+ * memory optimizations
+
+ * settings (parse/read files, etc..)
+
+ * define usage of new routes inside of routes, and allow route removal
+
+ * connection limit
+
+* more doxygen like docs, everywhere
+
+* make parray_t hash based
+
+
+----
+
+# credits
+
+* [luaproc](https://github.com/askyrme/luaproc) helped with multithreading
+
diff --git a/src/crypto.h b/src/crypto.h index e0a29b0..8fd83a5 100644 --- a/src/crypto.h +++ b/src/crypto.h @@ -25,6 +25,7 @@ #include "hash/sdbm.h" #include "hash/sha2-256.h" #include "hash/spookyhash.h" +#include "hash/blake2.h" #include "encode/uuencode.h" #include "encode/base64.h" @@ -55,7 +56,7 @@ static const luaL_Reg crypto_function_list [] = { {"spookyhash128_v1", l_spookyhash128_v1}, {"spookyhash128_v2", l_spookyhash128_v2}, {"spookyhash64_v1", l_spookyhash64_v1}, {"spookyhash64_v2", l_spookyhash64_v2}, {"spookyhash32_v1", l_spookyhash32_v1}, {"spookyhash32_v2", l_spookyhash32_v2}, - + {"blake2b", l_blake2b}, {"blake2s", l_blake2s}, {"uuencode",l_uuencode}, diff --git a/src/hash/blake2.c b/src/hash/blake2.c new file mode 100644 index 0000000..aeb48ad --- /dev/null +++ b/src/hash/blake2.c @@ -0,0 +1,261 @@ +#include <stdio.h>
+#include <stdint.h>
+#include <string.h>
+#include <stdlib.h>
+#include <math.h>
+#include "sha2-256.h"
+#include "blake2.h"
+#include "../util.h"
+
+uint64_t rotr64(uint64_t w, unsigned c){
+ return (w >> c) | (w << (64 - c));
+}
+uint32_t rotr32(uint32_t w, unsigned c){
+ return (w >> c) | (w << (32 - c));
+}
+
+void mix2b(uint64_t* a, uint64_t* b, uint64_t* c, uint64_t* d, int64_t x, int64_t y){
+ *a = *a + *b + x;
+ *d = rotr64((*d ^ *a), 32);
+
+ *c += *d;
+ *b = rotr64((*b ^ *c), 24);
+
+ *a += *b + y;
+ *d = rotr64((*d ^ *a), 16);
+
+ *c += *d;
+ *b = rotr64((*b ^ *c), 63);
+}
+
+void mix2s(uint32_t* a, uint32_t* b, uint32_t* c, uint32_t* d, int32_t x, int32_t y){
+ *a = *a + *b + x;
+ *d = rotr32((*d ^ *a), 16);
+
+ *c += *d;
+ *b = rotr32((*b ^ *c), 12);
+
+ *a += *b + y;
+ *d = rotr32((*d ^ *a), 8);
+
+ *c += *d;
+ *b = rotr32((*b ^ *c), 7);
+}
+
+#define baking(type) \
+ mix2##type(&v[0], &v[4], &v[8], &v[12], m[s[0]], m[s[1]]);\
+ mix2##type(&v[1], &v[5], &v[9], &v[13], m[s[2]], m[s[3]]);\
+ mix2##type(&v[2], &v[6], &v[10], &v[14], m[s[4]], m[s[5]]);\
+ mix2##type(&v[3], &v[7], &v[11], &v[15], m[s[6]], m[s[7]]);\
+ \
+ mix2##type(&v[0], &v[5], &v[10], &v[15], m[s[8]], m[s[9]]);\
+ mix2##type(&v[1], &v[6], &v[11], &v[12], m[s[10]], m[s[11]]);\
+ mix2##type(&v[2], &v[7], &v[8], &v[13], m[s[12]], m[s[13]]);\
+ mix2##type(&v[3], &v[4], &v[9], &v[14], m[s[14]], m[s[15]]);
+
+void compress2b(uint64_t* hash, uint8_t* inp, uint64_t compressed, int final){
+ uint64_t v[16], s[16], m[16];
+
+ #pragma unroll
+ for(int i = 0; i != 8; i++)
+ v[i] = hash[i];
+
+ for(int i = 0; i != 16; i++)
+ m[i] = ((uint64_t*)inp)[i];
+
+ v[8] = sha512_iv.h0;
+ v[9] = sha512_iv.h1;
+ v[10] = sha512_iv.h2;
+ v[11] = sha512_iv.h3;
+ v[12] = sha512_iv.h4;
+ v[13] = sha512_iv.h5;
+ v[14] = sha512_iv.h6;
+ v[15] = sha512_iv.h7;
+
+ v[12] ^= compressed;
+ v[13] ^= 0;
+
+ if(final)
+ v[14] ^= 0xFFFFFFFFFFFFFFFF;
+
+ for(int i = 0; i != 12; i++){
+ for(int j = 0; j != 16; j++){
+ s[j] = blake2b_sigma[i%10][j];
+ }
+
+ baking(b);
+ }
+
+ for (int i = 0; i < 8; i++) {
+ hash[i] = hash[i] ^ v[i] ^ v[i + 8];
+ }
+}
+
+void compress2s(uint32_t* hash, uint8_t* inp, uint32_t compressed, int final){
+ uint32_t v[16], s[16], m[16];
+
+ #pragma unroll
+ for(int i = 0; i != 8; i++)
+ v[i] = hash[i];
+
+ for(int i = 0; i != 16; i++)
+ m[i] = ((uint32_t*)inp)[i];
+
+ v[8] = sha512_iv.h0 >> 32;
+ v[9] = sha512_iv.h1 >> 32;
+ v[10] = sha512_iv.h2 >> 32;
+ v[11] = sha512_iv.h3 >> 32;
+ v[12] = sha512_iv.h4 >> 32;
+ v[13] = sha512_iv.h5 >> 32;
+ v[14] = sha512_iv.h6 >> 32;
+ v[15] = sha512_iv.h7 >> 32;
+
+ v[12] ^= compressed; //make this 64bit
+ v[13] ^= 0;
+
+ if(final)
+ v[14] ^= 0xFFFFFFFFFFFFFFFF >> 32;
+
+ for(int i = 0; i != 10; i++){
+ for(int j = 0; j != 16; j++){
+ s[j] = blake2b_sigma[i][j];
+ }
+
+ baking(s);
+ }
+
+ for (int i = 0; i < 8; i++) {
+ hash[i] = hash[i] ^ v[i] ^ v[i + 8];
+ }
+}
+
+void blake2b(char* inp, int inp_len, char* key, int key_len, int dig_len, char* buffer){
+ uint64_t hash[8];
+
+ uint64_t iv0 = hash[0] = sha512_iv.h0;
+ uint64_t iv1 = hash[1] = sha512_iv.h1;
+ uint64_t iv2 = hash[2] = sha512_iv.h2;
+ uint64_t iv3 = hash[3] = sha512_iv.h3;
+ uint64_t iv4 = hash[4] = sha512_iv.h4;
+ uint64_t iv5 = hash[5] = sha512_iv.h5;
+ uint64_t iv6 = hash[6] = sha512_iv.h6;
+ uint64_t iv7 = hash[7] = sha512_iv.h7;
+
+ uint64_t alen = inter(inp_len, 128) + 128;
+
+
+ //add padding
+ char* padded = calloc(alen + (128 * (key_len > 0)), sizeof * padded);
+
+ if(key_len > 0){
+ memcpy(padded, key, key_len);
+ inp_len += 128;
+ }
+
+ memcpy(padded + (128 * (key_len > 0)), inp, inp_len - (128 * (key_len > 0)));
+
+ hash[0] ^= dig_len;
+ hash[0] ^= key_len << 8;
+ hash[0] ^= 0x01010000;
+
+ uint64_t compressed = 0, bytes_remaining = inp_len;
+
+ int i = 0;
+ for(;bytes_remaining > 128; i += 2){
+ bytes_remaining -= 128;
+ compressed += 128;
+
+ compress2b(hash, (uint8_t*)padded, compressed, 0);
+ padded += 128;
+ }
+
+ compressed += bytes_remaining;
+
+ compress2b(hash, (uint8_t*)padded, compressed, 1);
+ for(int i = 0; i != dig_len; i++)sprintf(buffer, "%s%02x", buffer, (((uint8_t*)hash)[i]));
+}
+
+void blake2s(char* inp, int inp_len, char* key, int key_len, int dig_len, char* buffer){
+ uint32_t hash[8];
+
+ uint32_t iv0 = hash[0] = sha512_iv.h0 >> 32;
+ uint32_t iv1 = hash[1] = sha512_iv.h1 >> 32;
+ uint32_t iv2 = hash[2] = sha512_iv.h2 >> 32;
+ uint32_t iv3 = hash[3] = sha512_iv.h3 >> 32;
+ uint32_t iv4 = hash[4] = sha512_iv.h4 >> 32;
+ uint32_t iv5 = hash[5] = sha512_iv.h5 >> 32;
+ uint32_t iv6 = hash[6] = sha512_iv.h6 >> 32;
+ uint32_t iv7 = hash[7] = sha512_iv.h7 >> 32;
+
+ uint32_t alen = inter(inp_len, 64) + 64;
+
+ //add padding
+ char* padded = calloc(alen + (64 * (key_len > 0)), sizeof * padded);
+ if(key_len > 0){
+ memcpy(padded, key, key_len);
+ inp_len += 64;
+ }
+ memcpy(padded + (64 * (key_len > 0)), inp, inp_len - (64 * (key_len > 0)));
+
+ hash[0] ^= dig_len;
+ hash[0] ^= key_len << 8;
+ hash[0] ^= 0x01010000;
+
+ uint64_t compressed = 0, bytes_remaining = inp_len;
+
+ int i = 0;
+ for(;bytes_remaining > 64; i += 2){
+ bytes_remaining -= 64;
+ compressed += 64;
+
+ compress2s(hash, (uint8_t*)padded, compressed, 0);
+ padded += 64;
+ }
+
+ compressed += bytes_remaining;
+
+ compress2s(hash, (uint8_t*)padded, compressed, 1);
+ for(int i = 0; i != dig_len; i++)sprintf(buffer, "%s%02x", buffer, (((uint8_t*)hash)[i]));
+}
+
+int l_blake2b(lua_State* L){
+ size_t len = 0;
+ char* a = (char*)luaL_checklstring(L, 1, &len);
+ int argv = lua_gettop(L);
+
+ uint64_t out_len = 64;
+ if(argv > 1) out_len = luaL_checkinteger(L, 2);
+
+ char* key = NULL;
+ size_t key_len = 0;
+ if(argv > 2) key = (char*)luaL_checklstring(L, 3, &key_len);
+
+ char digest[out_len * 8];
+ memset(digest, 0, out_len * 8);
+
+ blake2b(a, len, key, key_len, out_len, digest);
+ lua_pushstring(L, digest);
+
+ return 1;
+}
+
+int l_blake2s(lua_State* L){
+ size_t len = 0;
+ char* a = (char*)luaL_checklstring(L, 1, &len);
+ int argv = lua_gettop(L);
+
+ uint32_t out_len = 32;
+ if(argv > 1) out_len = luaL_checkinteger(L, 2);
+
+ char* key = NULL;
+ size_t key_len = 0;
+ if(argv > 2) key = (char*)luaL_checklstring(L, 3, &key_len);
+
+ char digest[out_len * 8];
+ memset(digest, 0, out_len * 8);
+
+ blake2s(a, len, key, key_len, out_len, digest);
+ lua_pushstring(L, digest);
+
+ return 1;
+}
\ No newline at end of file diff --git a/src/hash/blake2.h b/src/hash/blake2.h new file mode 100644 index 0000000..cde04b3 --- /dev/null +++ b/src/hash/blake2.h @@ -0,0 +1,21 @@ +#include <stdint.h>
+#include "../lua.h"
+
+static const uint8_t blake2b_sigma[10][16] = {
+ { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15 },
+ { 14, 10, 4, 8, 9, 15, 13, 6, 1, 12, 0, 2, 11, 7, 5, 3 },
+ { 11, 8, 12, 0, 5, 2, 15, 13, 10, 14, 3, 6, 7, 1, 9, 4 },
+ { 7, 9, 3, 1, 13, 12, 11, 14, 2, 6, 5, 10, 4, 0, 15, 8 },
+ { 9, 0, 5, 7, 2, 4, 10, 15, 14, 1, 11, 12, 6, 8, 3, 13 },
+ { 2, 12, 6, 10, 0, 11, 8, 3, 4, 13, 7, 5, 15, 14, 1, 9 },
+ { 12, 5, 1, 15, 14, 13, 4, 10, 0, 7, 6, 3, 9, 2, 8, 11 },
+ { 13, 11, 7, 14, 12, 1, 3, 9, 5, 0, 15, 4, 8, 6, 2, 10 },
+ { 6, 15, 14, 9, 11, 3, 0, 8, 12, 2, 13, 7, 1, 4, 10, 5 },
+ { 10, 2, 8, 4, 7, 6, 1, 5, 15, 11, 9, 14, 3, 12, 13, 0 },
+};
+
+void blake2s(char*, int, char*, int, int, char*);
+void blake2b(char*, int, char*, int, int, char*);
+
+int l_blake2s(lua_State*);
+int l_blake2b(lua_State*);
\ No newline at end of file diff --git a/src/types/map.c b/src/types/map.c index cd46537..a15762a 100644 --- a/src/types/map.c +++ b/src/types/map.c @@ -1,135 +1,135 @@ -#include "map.h" -#include "../hash/fnv.h" -#include <stdio.h> -#include <string.h> -#include <stdlib.h> - -#define mod_inc 4 - -uint64_t hash(char* c, size_t len){ - return fnv_1((uint8_t*)c, len, v_a); -} - -void map_dump(map_t* M){ - printf("---\n%i %i\n- **\n",M->mod, M->len); - for(int i = 0; i != M->mod; i++){ - if(M->M[i].used){ - printf("%i | %s : %p\n",i,M->M[i].key->c, M->M[i].value); - } - } -} - -map_t* map_initl(size_t len){ - map_t* awa = calloc(sizeof * awa, 1); - awa->M = calloc(sizeof * awa->M, len); - //for(int i = 0; i != len; i++) awa->M[i].used = 0; - awa->len = 0; - awa->mod = len; - return awa; -} - -map_t* map_init(){ - return map_initl(4); -} - -void map_expand(map_t** _M){ - map_t* M = *_M; - map_t* remade = map_initl(M->mod * 4); - for(int i = 0; i != M->mod; i++){ - //what happens if the map_set calls map_regraph??? idk - if(M->M[i].used) - map_set(&remade, M->M[i].key->c, M->M[i].value); - } - - *_M = remade; -} - -void map_set(map_t** _M, char* key, void* value){ - map_t* M = *_M; - uint64_t h = hash(key, strlen(key)); - - if(M->len + 1 >= M->mod){ - expand: - map_expand(&M); - } - uint64_t ind = h % M->mod; - uint64_t oind = ind; - - //iterates until there is a free space - for(int count = 0; M->M[ind].used && M->M[ind].hash != h && strcmp(M->M[ind].key->c, key) != 0; count++){ - ind++; - if(ind >= M->mod) ind = 0; - if(ind == oind || count > 10) goto expand; - } - - M->M[ind].hash = h; - M->M[ind].key = str_init(key); - M->M[ind].value = value; - M->M[ind].used = 1; - M->len++; - - *_M = M; -} - -int map_geti(map_t* M, char* key){ - uint64_t h = hash(key, strlen(key)); - uint64_t ind = h % M->mod; - - for(uint64_t initial = ind; ind != initial - 1;){ - if(M->M[ind].key == NULL) return -1; - //printf("%s\n",M->M[ind].key->c); - if(M->M[ind].hash == h && strcmp(M->M[ind].key->c, key)==0) return ind; - ind++; - if(ind >= M->mod) ind = 0; - } - return -1; -} - -void* map_get(map_t* M, char* key){ - int r = map_geti(M, key); - //printf("%i\n",r); - return r == -1? NULL : M->M[r].value; -} - -void map_remove(map_t* p, char* key, enum free_type free){ - int ind = map_geti(p, key); - if(ind == -1) return; - p->M[ind].used = 0; - p->M[ind].hash = 0; - str_free(p->M[ind].key); - free_method(p->M[ind].value, free); -} - -void map_lclear(map_t* M){ - free(M->M); - free(M); -} - -void map_clear(map_t* M, enum free_type free){ - for(int i = 0; i != M->mod; i++){ - if(M->M[i].used){ - str_free(M->M[i].key); - free_method(M->M[i].value, free); - } - } - map_lclear(M); -} - -int main(){ - int i = 5; - int b = 24; - int c = 9; - map_t* m = map_init(); - - map_set(&m, "wowa", &b); - printf("%i\n",*(int*)map_get(m, "wowa")); - map_set(&m, "aw", &i); - map_set(&m, "awc", &i); - map_set(&m, "awa", &i); - map_set(&m, "aww", &i); - printf("%i\n",*(int*)map_get(m, "wowa")); - - map_clear(m, NONE); - - return 0; +#include "map.h"
+#include "../hash/fnv.h"
+#include <stdio.h>
+#include <string.h>
+#include <stdlib.h>
+
+#define mod_inc 4
+
+uint64_t hash(char* c, size_t len){
+ return fnv_1((uint8_t*)c, len, v_a);
+}
+
+void map_dump(map_t* M){
+ printf("---\n%i %i\n- **\n",M->mod, M->len);
+ for(int i = 0; i != M->mod; i++){
+ if(M->M[i].used){
+ printf("%i | %s : %p\n",i,M->M[i].key->c, M->M[i].value);
+ }
+ }
+}
+
+map_t* map_initl(size_t len){
+ map_t* awa = calloc(sizeof * awa, 1);
+ awa->M = calloc(sizeof * awa->M, len);
+ //for(int i = 0; i != len; i++) awa->M[i].used = 0;
+ awa->len = 0;
+ awa->mod = len;
+ return awa;
+}
+
+map_t* map_init(){
+ return map_initl(4);
+}
+
+void map_expand(map_t** _M){
+ map_t* M = *_M;
+ map_t* remade = map_initl(M->mod * 4);
+ for(int i = 0; i != M->mod; i++){
+ //what happens if the map_set calls map_regraph??? idk
+ if(M->M[i].used)
+ map_set(&remade, M->M[i].key->c, M->M[i].value);
+ }
+
+ *_M = remade;
+}
+
+void map_set(map_t** _M, char* key, void* value){
+ map_t* M = *_M;
+ uint64_t h = hash(key, strlen(key));
+
+ if(M->len + 1 >= M->mod){
+ expand:
+ map_expand(&M);
+ }
+ uint64_t ind = h % M->mod;
+ uint64_t oind = ind;
+
+ //iterates until there is a free space
+ for(int count = 0; M->M[ind].used && M->M[ind].hash != h && strcmp(M->M[ind].key->c, key) != 0; count++){
+ ind++;
+ if(ind >= M->mod) ind = 0;
+ if(ind == oind || count > 10) goto expand;
+ }
+
+ M->M[ind].hash = h;
+ M->M[ind].key = str_init(key);
+ M->M[ind].value = value;
+ M->M[ind].used = 1;
+ M->len++;
+
+ *_M = M;
+}
+
+int map_geti(map_t* M, char* key){
+ uint64_t h = hash(key, strlen(key));
+ uint64_t ind = h % M->mod;
+
+ for(uint64_t initial = ind; ind != initial - 1;){
+ if(M->M[ind].key == NULL) return -1;
+ //printf("%s\n",M->M[ind].key->c);
+ if(M->M[ind].hash == h && strcmp(M->M[ind].key->c, key)==0) return ind;
+ ind++;
+ if(ind >= M->mod) ind = 0;
+ }
+ return -1;
+}
+
+void* map_get(map_t* M, char* key){
+ int r = map_geti(M, key);
+ //printf("%i\n",r);
+ return r == -1? NULL : M->M[r].value;
+}
+
+void map_remove(map_t* p, char* key, enum free_type free){
+ int ind = map_geti(p, key);
+ if(ind == -1) return;
+ p->M[ind].used = 0;
+ p->M[ind].hash = 0;
+ str_free(p->M[ind].key);
+ free_method(p->M[ind].value, free);
+}
+
+void map_lclear(map_t* M){
+ free(M->M);
+ free(M);
+}
+
+void map_clear(map_t* M, enum free_type free){
+ for(int i = 0; i != M->mod; i++){
+ if(M->M[i].used){
+ str_free(M->M[i].key);
+ free_method(M->M[i].value, free);
+ }
+ }
+ map_lclear(M);
+}
+
+int main(){
+ int i = 5;
+ int b = 24;
+ int c = 9;
+ map_t* m = map_init();
+
+ map_set(&m, "wowa", &b);
+ printf("%i\n",*(int*)map_get(m, "wowa"));
+ map_set(&m, "aw", &i);
+ map_set(&m, "awc", &i);
+ map_set(&m, "awa", &i);
+ map_set(&m, "aww", &i);
+ printf("%i\n",*(int*)map_get(m, "wowa"));
+
+ map_clear(m, NONE);
+
+ return 0;
}
\ No newline at end of file diff --git a/src/types/map.h b/src/types/map.h index efa6d65..2603f47 100644 --- a/src/types/map.h +++ b/src/types/map.h @@ -1,30 +1,30 @@ - -#ifndef _MAP_H -#define _MAP_H - -#include <stdint.h> -#include "str.h" -#include "parray.h" - -typedef struct { - void* value; - str* key; - uint64_t hash; - int used; -} melem_t; - -typedef struct { - melem_t* M; - int len; - int mod; -} map_t; - -map_t* map_init(); -void map_set(map_t**, char*, void*); -void* map_get(map_t* , char*); -int map_geti(map_t* , char*); -void map_remove(map_t* p, char* key, enum free_type free); -void map_clear(map_t*, enum free_type); -void map_lclear(map_t*); - +
+#ifndef _MAP_H
+#define _MAP_H
+
+#include <stdint.h>
+#include "str.h"
+#include "parray.h"
+
+typedef struct {
+ void* value;
+ str* key;
+ uint64_t hash;
+ int used;
+} melem_t;
+
+typedef struct {
+ melem_t* M;
+ int len;
+ int mod;
+} map_t;
+
+map_t* map_init();
+void map_set(map_t**, char*, void*);
+void* map_get(map_t* , char*);
+int map_geti(map_t* , char*);
+void map_remove(map_t* p, char* key, enum free_type free);
+void map_clear(map_t*, enum free_type);
+void map_lclear(map_t*);
+
#endif //_MAP_H
\ No newline at end of file diff --git a/src/types/str.c b/src/types/str.c index 929057e..364a02f 100644 --- a/src/types/str.c +++ b/src/types/str.c @@ -1,66 +1,66 @@ -#include "str.h" -#include "../lua.h" -#include "../util.h" - -#define alloc_buffer 64 - -str* str_initl(char* init, size_t len){ - if(init == NULL){ - char cc = '\0'; - init = &cc; - } - - str* s = malloc(sizeof * s); - s->_bytes = len + 1 + alloc_buffer; - s->c = malloc(s->_bytes); - if(s->c == NULL) p_fatal("failed to allocate string\n"); - s->len = len ; - - memcpy(s->c, init, len + 1); - return s; -} - -str* str_init(char* init){ - return str_initl(init, strlen(init)); -} - -void str_free(str* s){ - free(s->c); - return free(s); -} - -void str_push(str* s, char* insert){ - s->len += strlen(insert); - if(s->len + 1 >= s->_bytes) - s->c = realloc(s->c, s->_bytes = s->len + 1 + alloc_buffer); - strcat(s->c, insert); -} - -void str_pushl(str* s, char* insert, size_t l){ - if(s->len + l >= s->_bytes) - s->c = realloc(s->c, s->_bytes = s->len + l + alloc_buffer); - //strcat(s->c, insert); - for(int i = 0; i != l; i++){ - s->c[i + s->len] = insert[i]; - } - s->len += l; - s->c[s->len] = '\0'; -} - -void str_clear(str* s){ - memset(s->c, 0, s->len); - - s->len = 0; -} - -void str_popf(str* s, int len){ - memmove(s->c, s->c + len, s->len -= len); - s->c[s->len] = 0; -} - -void str_popb(str* s, int len){ - s->len -= len; - s->c[s->len] = 0; -} - - +#include "str.h"
+#include "../lua.h"
+#include "../util.h"
+
+#define alloc_buffer 64
+
+str* str_initl(char* init, size_t len){
+ if(init == NULL){
+ char cc = '\0';
+ init = &cc;
+ }
+
+ str* s = malloc(sizeof * s);
+ s->_bytes = len + 1 + alloc_buffer;
+ s->c = malloc(s->_bytes);
+ if(s->c == NULL) p_fatal("failed to allocate string\n");
+ s->len = len ;
+
+ memcpy(s->c, init, len + 1);
+ return s;
+}
+
+str* str_init(char* init){
+ return str_initl(init, strlen(init));
+}
+
+void str_free(str* s){
+ free(s->c);
+ return free(s);
+}
+
+void str_push(str* s, char* insert){
+ s->len += strlen(insert);
+ if(s->len + 1 >= s->_bytes)
+ s->c = realloc(s->c, s->_bytes = s->len + 1 + alloc_buffer);
+ strcat(s->c, insert);
+}
+
+void str_pushl(str* s, char* insert, size_t l){
+ if(s->len + l >= s->_bytes)
+ s->c = realloc(s->c, s->_bytes = s->len + l + alloc_buffer);
+ //strcat(s->c, insert);
+ for(int i = 0; i != l; i++){
+ s->c[i + s->len] = insert[i];
+ }
+ s->len += l;
+ s->c[s->len] = '\0';
+}
+
+void str_clear(str* s){
+ memset(s->c, 0, s->len);
+
+ s->len = 0;
+}
+
+void str_popf(str* s, int len){
+ memmove(s->c, s->c + len, s->len -= len);
+ s->c[s->len] = 0;
+}
+
+void str_popb(str* s, int len){
+ s->len -= len;
+ s->c[s->len] = 0;
+}
+
+
diff --git a/tests/hash.lua b/tests/hash.lua index b4e455a..6bd3295 100644 --- a/tests/hash.lua +++ b/tests/hash.lua @@ -1,9 +1,16 @@ require "llib" -function test(name,b,exp) - local hash = llib.crypto[name](b) +function test(name,b,exp,oargs) + local hash + local add = "" + if oargs == nil then + hash = llib.crypto[name](b) + else + hash = llib.crypto[name](b,table.unpack(oargs)) + add = table.concat(oargs, ", ") + end if not (hash == exp) then - llib.io.error(name.." not working, got \n\t"..hash.." wanted\n\t"..exp) + llib.io.error(name.." not working, got \n\t"..hash.." wanted\n\t"..exp.."\n\twith args: {"..add.."}") else llib.io.log(name.." was correct, "..hash) end @@ -54,3 +61,7 @@ test("metrohash128_v1","meow","bfd8835cbcc06d2be6fc2c8e5ecbcc26") test("metrohash128_v2","meow","6d8634ccf529269297704cba8bf8707a") test("murmur1_32","meow","743df82f") test("murmur2_32","meow","05d01b88") +test("blake2b","meow","9919ae53fbea6c5da68e51b6e19a890fdbc01baf97fff29efd7efaa7163ea7aa205109b818bde29da815e16b869dbb2cb1b367ed1027f52116287d760808a43d") +test("blake2b","meow","424969d2fe47cdec2a824709b8066cc1d63cc4b6a16a3c1fa421cc2a6625f7c2",{32}) +test("blake2b","meow","6f30dec70f9ed6d8db2e7407d3e2325af23935464ec3ec1cf4c12575ff3c18043bf772033b91d52978c451d01f7eaeacabda76460b9f4b7bf516dd9d0cc886d",{64,"owo"}) +test("blake2s","meow","f461bed24c982ccb29cb967acdaebc9494b51c1d0f88f6bc47850952261a512d")
\ No newline at end of file |
