Hash_Lua.c (6629B)
1 /* 2 * Hash_Lua.c - Lua bindings for hash functions 3 */ 4 5 #include "Hash_Lua.h" 6 #include "hashing/hash.h" 7 #include "hashing/SHA3.h" 8 #include "hashing/BLAKE2.h" 9 #include <string.h> 10 #include <stdlib.h> 11 12 /* ============================================================================ 13 * Helper Functions 14 * ========================================================================= */ 15 16 /* Base64 decode helper (simplified version) */ 17 static uint8_t* base64_decode_simple(const char *input, size_t input_len, size_t *output_len) { 18 static const unsigned char decode_table[256] = { 19 ['A']=0, ['B']=1, ['C']=2, ['D']=3, ['E']=4, ['F']=5, ['G']=6, ['H']=7, 20 ['I']=8, ['J']=9, ['K']=10, ['L']=11, ['M']=12, ['N']=13, ['O']=14, ['P']=15, 21 ['Q']=16, ['R']=17, ['S']=18, ['T']=19, ['U']=20, ['V']=21, ['W']=22, ['X']=23, 22 ['Y']=24, ['Z']=25, ['a']=26, ['b']=27, ['c']=28, ['d']=29, ['e']=30, ['f']=31, 23 ['g']=32, ['h']=33, ['i']=34, ['j']=35, ['k']=36, ['l']=37, ['m']=38, ['n']=39, 24 ['o']=40, ['p']=41, ['q']=42, ['r']=43, ['s']=44, ['t']=45, ['u']=46, ['v']=47, 25 ['w']=48, ['x']=49, ['y']=50, ['z']=51, ['0']=52, ['1']=53, ['2']=54, ['3']=55, 26 ['4']=56, ['5']=57, ['6']=58, ['7']=59, ['8']=60, ['9']=61, ['+']=62, ['/']=63 27 }; 28 29 size_t decoded_len = (input_len / 4) * 3; 30 if (input_len > 0 && input[input_len - 1] == '=') decoded_len--; 31 if (input_len > 1 && input[input_len - 2] == '=') decoded_len--; 32 33 uint8_t *decoded = malloc(decoded_len); 34 if (!decoded) return NULL; 35 36 size_t j = 0; 37 for (size_t i = 0; i < input_len; i += 4) { 38 uint32_t sextet_a = input[i] == '=' ? 0 : decode_table[(unsigned char)input[i]]; 39 uint32_t sextet_b = input[i+1] == '=' ? 0 : decode_table[(unsigned char)input[i+1]]; 40 uint32_t sextet_c = input[i+2] == '=' ? 0 : decode_table[(unsigned char)input[i+2]]; 41 uint32_t sextet_d = input[i+3] == '=' ? 0 : decode_table[(unsigned char)input[i+3]]; 42 43 uint32_t triple = (sextet_a << 18) | (sextet_b << 12) | (sextet_c << 6) | sextet_d; 44 45 if (j < decoded_len) decoded[j++] = (triple >> 16) & 0xFF; 46 if (j < decoded_len) decoded[j++] = (triple >> 8) & 0xFF; 47 if (j < decoded_len) decoded[j++] = triple & 0xFF; 48 } 49 50 *output_len = decoded_len; 51 return decoded; 52 } 53 54 /* Check if string looks like base64 */ 55 static int is_base64(const char *str, size_t len) { 56 if (len == 0 || len % 4 != 0) return 0; 57 58 for (size_t i = 0; i < len; i++) { 59 char c = str[i]; 60 if (!((c >= 'A' && c <= 'Z') || (c >= 'a' && c <= 'z') || 61 (c >= '0' && c <= '9') || c == '+' || c == '/' || c == '=')) { 62 return 0; 63 } 64 } 65 return 1; 66 } 67 68 /* ============================================================================ 69 * Hash Functions 70 * ========================================================================= */ 71 72 /* hash(string) - SHA-256 hash returning raw binary */ 73 int l_hash(lua_State *L) { 74 size_t input_len; 75 const char *input = luaL_checklstring(L, 1, &input_len); 76 77 uint8_t digest[32]; 78 sha256((const uint8_t*)input, input_len, digest); 79 80 lua_pushlstring(L, (const char*)digest, 32); 81 return 1; 82 } 83 84 /* hash.SHA512(string) - SHA-512 hash returning raw binary */ 85 int l_hash_sha512(lua_State *L) { 86 size_t input_len; 87 const char *input = luaL_checklstring(L, 1, &input_len); 88 89 uint8_t digest[64]; 90 sha512((const uint8_t*)input, input_len, digest); 91 92 lua_pushlstring(L, (const char*)digest, 64); 93 return 1; 94 } 95 96 /* hash.SHA1(string) - SHA-1 hash (legacy) returning raw binary */ 97 int l_hash_sha1(lua_State *L) { 98 size_t input_len; 99 const char *input = luaL_checklstring(L, 1, &input_len); 100 101 uint8_t digest[20]; 102 sha1((const uint8_t*)input, input_len, digest); 103 104 lua_pushlstring(L, (const char*)digest, 20); 105 return 1; 106 } 107 108 /* hash.CRC32(string) - CRC32 checksum returning raw binary (4 bytes, big-endian) */ 109 int l_hash_crc32(lua_State *L) { 110 size_t input_len; 111 const char *input = luaL_checklstring(L, 1, &input_len); 112 113 uint32_t checksum = crc32((const uint8_t*)input, input_len); 114 115 /* Convert uint32_t to bytes (big-endian) */ 116 uint8_t digest[4]; 117 digest[0] = (checksum >> 24) & 0xFF; 118 digest[1] = (checksum >> 16) & 0xFF; 119 digest[2] = (checksum >> 8) & 0xFF; 120 digest[3] = checksum & 0xFF; 121 122 lua_pushlstring(L, (const char*)digest, 4); 123 return 1; 124 } 125 126 /* hash.MD5(string) - MD5 hash returning raw binary */ 127 int l_hash_md5(lua_State *L) { 128 size_t input_len; 129 const char *input = luaL_checklstring(L, 1, &input_len); 130 131 /* Compute MD5 hash */ 132 uint8_t digest[16]; 133 md5((const uint8_t*)input, input_len, digest); 134 135 lua_pushlstring(L, (const char*)digest, 16); 136 return 1; 137 } 138 139 /* hash.SHA3(string) or hash.SHA3_256(string) - SHA3-256 hash returning raw binary */ 140 int l_hash_sha3(lua_State *L) { 141 size_t input_len; 142 const char *input = luaL_checklstring(L, 1, &input_len); 143 144 uint8_t digest[32]; 145 sha3_256((const uint8_t*)input, input_len, digest); 146 147 lua_pushlstring(L, (const char*)digest, 32); 148 return 1; 149 } 150 151 /* hash.SHA3_512(string) - SHA3-512 hash returning raw binary */ 152 int l_hash_sha3_512(lua_State *L) { 153 size_t input_len; 154 const char *input = luaL_checklstring(L, 1, &input_len); 155 156 uint8_t digest[64]; 157 sha3_512((const uint8_t*)input, input_len, digest); 158 159 lua_pushlstring(L, (const char*)digest, 64); 160 return 1; 161 } 162 163 /* hash(string) via __call metamethod - SHA3-256 hash (default) 164 * When called as crypto.hash("data"), the table is arg 1, data is arg 2 */ 165 int l_hash_call(lua_State *L) { 166 size_t input_len; 167 /* Argument 2 because arg 1 is the hash table itself when using __call */ 168 const char *input = luaL_checklstring(L, 2, &input_len); 169 170 uint8_t digest[32]; 171 sha3_256((const uint8_t*)input, input_len, digest); 172 173 lua_pushlstring(L, (const char*)digest, 32); 174 return 1; 175 } 176 177 /* hash.BLAKE2b(string) or hash.BLAKE2b_256(string) - BLAKE2b-256 hash returning raw binary */ 178 int l_hash_blake2b(lua_State *L) { 179 size_t input_len; 180 const char *input = luaL_checklstring(L, 1, &input_len); 181 182 uint8_t digest[32]; 183 blake2b_256((const uint8_t*)input, input_len, digest); 184 185 lua_pushlstring(L, (const char*)digest, 32); 186 return 1; 187 } 188 189 /* hash.BLAKE2b_512(string) - BLAKE2b-512 hash returning raw binary */ 190 int l_hash_blake2b_512(lua_State *L) { 191 size_t input_len; 192 const char *input = luaL_checklstring(L, 1, &input_len); 193 194 uint8_t digest[64]; 195 blake2b_512((const uint8_t*)input, input_len, digest); 196 197 lua_pushlstring(L, (const char*)digest, 64); 198 return 1; 199 }