crypto.c (44803B)
1 /* 2 * crypto.c - Lua bindings for encryption library 3 * 4 * Provides Lua interface to AES, ChaCha20, Serpent, and Twofish encryption 5 * All functions use the format: [Nonce(12)][Tag(16)][Ciphertext(var)] 6 * 7 * All functions take key as first parameter (binary or base64) 8 */ 9 10 #include <lua.h> 11 #include <lauxlib.h> 12 #include <string.h> 13 #include <stdlib.h> 14 #include <stdint.h> 15 #include "EasyCrypto.h" 16 #include "CSPRNG.h" 17 #include "CSPRNG_Lua.h" 18 #include "PBKDF2_Lua.h" 19 #include "Hash_Lua.h" 20 #include "X25519_Lua.h" 21 #include "Ed25519_Lua.h" 22 #include "RSA_Lua.h" 23 #include "P256_Lua.h" 24 #include "Kyber_Lua.h" 25 #include "Dilithium_Lua.h" 26 27 /* Base64 encoding table */ 28 static const char base64_chars[] = 29 "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/"; 30 31 /* Base64 encode */ 32 char* base64_encode(const uint8_t *data, size_t len, size_t *out_len) { 33 size_t encoded_len = 4 * ((len + 2) / 3); 34 char *encoded = malloc(encoded_len + 1); 35 if (!encoded) return NULL; 36 37 size_t i, j; 38 for (i = 0, j = 0; i < len; ) { 39 uint32_t octet_a = i < len ? data[i++] : 0; 40 uint32_t octet_b = i < len ? data[i++] : 0; 41 uint32_t octet_c = i < len ? data[i++] : 0; 42 43 uint32_t triple = (octet_a << 16) + (octet_b << 8) + octet_c; 44 45 encoded[j++] = base64_chars[(triple >> 18) & 0x3F]; 46 encoded[j++] = base64_chars[(triple >> 12) & 0x3F]; 47 encoded[j++] = base64_chars[(triple >> 6) & 0x3F]; 48 encoded[j++] = base64_chars[triple & 0x3F]; 49 } 50 51 /* Add padding */ 52 for (i = 0; i < (3 - len % 3) % 3; i++) { 53 encoded[encoded_len - 1 - i] = '='; 54 } 55 56 encoded[encoded_len] = '\0'; 57 *out_len = encoded_len; 58 return encoded; 59 } 60 61 /* Base64 decode (non-static for RSA_Lua.c) */ 62 uint8_t* base64_decode(const char *data, size_t len, size_t *out_len) { 63 if (len % 4 != 0) return NULL; 64 65 size_t decoded_len = len / 4 * 3; 66 if (data[len - 1] == '=') decoded_len--; 67 if (data[len - 2] == '=') decoded_len--; 68 69 uint8_t *decoded = malloc(decoded_len); 70 if (!decoded) return NULL; 71 72 /* Build decode table */ 73 uint8_t decode_table[256]; 74 memset(decode_table, 0xFF, 256); 75 for (int i = 0; i < 64; i++) { 76 decode_table[(uint8_t)base64_chars[i]] = i; 77 } 78 79 size_t i, j; 80 for (i = 0, j = 0; i < len; ) { 81 uint32_t sextet_a = data[i] == '=' ? 0 : decode_table[(uint8_t)data[i]]; i++; 82 uint32_t sextet_b = data[i] == '=' ? 0 : decode_table[(uint8_t)data[i]]; i++; 83 uint32_t sextet_c = data[i] == '=' ? 0 : decode_table[(uint8_t)data[i]]; i++; 84 uint32_t sextet_d = data[i] == '=' ? 0 : decode_table[(uint8_t)data[i]]; i++; 85 86 uint32_t triple = (sextet_a << 18) + (sextet_b << 12) + (sextet_c << 6) + sextet_d; 87 88 if (j < decoded_len) decoded[j++] = (triple >> 16) & 0xFF; 89 if (j < decoded_len) decoded[j++] = (triple >> 8) & 0xFF; 90 if (j < decoded_len) decoded[j++] = triple & 0xFF; 91 } 92 93 *out_len = decoded_len; 94 return decoded; 95 } 96 97 /* Hex encoding */ 98 static char* hex_encode(const uint8_t *data, size_t len, size_t *out_len) { 99 static const char hex_chars[] = "0123456789abcdef"; 100 char *encoded = malloc(len * 2 + 1); 101 if (!encoded) return NULL; 102 103 for (size_t i = 0; i < len; i++) { 104 encoded[i * 2] = hex_chars[(data[i] >> 4) & 0xF]; 105 encoded[i * 2 + 1] = hex_chars[data[i] & 0xF]; 106 } 107 encoded[len * 2] = '\0'; 108 *out_len = len * 2; 109 return encoded; 110 } 111 112 /* Hex decode */ 113 static uint8_t* hex_decode(const char *data, size_t len, size_t *out_len) { 114 if (len % 2 != 0) return NULL; 115 116 size_t decoded_len = len / 2; 117 uint8_t *decoded = malloc(decoded_len); 118 if (!decoded) return NULL; 119 120 for (size_t i = 0; i < decoded_len; i++) { 121 char high = data[i * 2]; 122 char low = data[i * 2 + 1]; 123 124 uint8_t h = (high >= '0' && high <= '9') ? (high - '0') : 125 (high >= 'a' && high <= 'f') ? (high - 'a' + 10) : 126 (high >= 'A' && high <= 'F') ? (high - 'A' + 10) : 0; 127 uint8_t l = (low >= '0' && low <= '9') ? (low - '0') : 128 (low >= 'a' && low <= 'f') ? (low - 'a' + 10) : 129 (low >= 'A' && low <= 'F') ? (low - 'A' + 10) : 0; 130 131 decoded[i] = (h << 4) | l; 132 } 133 134 *out_len = decoded_len; 135 return decoded; 136 } 137 138 /* Metamethod for raw data: result:raw() */ 139 static int encrypted_data_raw(lua_State *L) { 140 /* Get _raw field (internal storage) */ 141 lua_getfield(L, 1, "_raw"); 142 return 1; 143 } 144 145 /* Metamethod for base64 encoding: result:base64() */ 146 static int encrypted_data_base64(lua_State *L) { 147 /* Get _raw field */ 148 lua_getfield(L, 1, "_raw"); 149 size_t len; 150 const uint8_t *data = (const uint8_t*)lua_tolstring(L, -1, &len); 151 152 /* Encode to base64 */ 153 size_t b64_len; 154 char *b64 = base64_encode(data, len, &b64_len); 155 if (!b64) { 156 return luaL_error(L, "Base64 encoding failed"); 157 } 158 159 lua_pushlstring(L, b64, b64_len); 160 free(b64); 161 return 1; 162 } 163 164 /* Metamethod for hex encoding: result:hex() */ 165 static int encrypted_data_hex(lua_State *L) { 166 /* Get _raw field */ 167 lua_getfield(L, 1, "_raw"); 168 size_t len; 169 const uint8_t *data = (const uint8_t*)lua_tolstring(L, -1, &len); 170 171 /* Encode to hex */ 172 size_t hex_len; 173 char *hex = hex_encode(data, len, &hex_len); 174 if (!hex) { 175 return luaL_error(L, "Hex encoding failed"); 176 } 177 178 lua_pushlstring(L, hex, hex_len); 179 free(hex); 180 return 1; 181 } 182 183 /* Create encrypted data table with raw(), length, base64(), and hex() methods */ 184 static void push_encrypted_data(lua_State *L, const uint8_t *data, size_t len) { 185 lua_newtable(L); /* Create result table */ 186 187 /* Set _raw field (internal storage with underscore prefix) */ 188 lua_pushlstring(L, (const char*)data, len); 189 lua_setfield(L, -2, "_raw"); 190 191 /* Set length field */ 192 lua_pushinteger(L, len); 193 lua_setfield(L, -2, "length"); 194 195 /* Create metatable with raw, base64, and hex methods */ 196 lua_newtable(L); /* Create metatable */ 197 198 lua_pushcfunction(L, encrypted_data_raw); 199 lua_setfield(L, -2, "raw"); 200 201 lua_pushcfunction(L, encrypted_data_base64); 202 lua_setfield(L, -2, "base64"); 203 204 lua_pushcfunction(L, encrypted_data_hex); 205 lua_setfield(L, -2, "hex"); 206 207 /* Set __index to point to itself so methods work */ 208 lua_pushvalue(L, -1); /* Duplicate metatable */ 209 lua_setfield(L, -2, "__index"); 210 211 lua_setmetatable(L, -2); /* Set metatable on result table */ 212 } 213 214 /* Get encrypted data from argument - accepts encrypted result table or binary string */ 215 static const uint8_t* get_encrypted_from_arg(lua_State *L, int arg, size_t *len) { 216 if (lua_istable(L, arg)) { 217 /* Table: Try calling :raw() method first */ 218 lua_getfield(L, arg, "raw"); 219 if (lua_isfunction(L, -1)) { 220 /* Call the raw() method */ 221 lua_pushvalue(L, arg); /* Push table as self */ 222 lua_call(L, 1, 1); /* Call raw(self) */ 223 224 if (lua_isstring(L, -1)) { 225 const uint8_t *data = (const uint8_t*)lua_tolstring(L, -1, len); 226 lua_replace(L, arg); /* Replace arg with raw string */ 227 return data; 228 } 229 lua_pop(L, 1); 230 } else { 231 lua_pop(L, 1); 232 } 233 234 /* Fallback: try _raw field directly */ 235 lua_getfield(L, arg, "_raw"); 236 if (!lua_isnil(L, -1)) { 237 const uint8_t *data = (const uint8_t*)lua_tolstring(L, -1, len); 238 lua_replace(L, arg); /* Replace arg with raw string */ 239 return data; 240 } 241 lua_pop(L, 1); 242 243 luaL_error(L, "Encrypted data table must have :raw() method or '_raw' field"); 244 return NULL; 245 } else if (lua_isstring(L, arg)) { 246 /* Binary string */ 247 return (const uint8_t*)lua_tolstring(L, arg, len); 248 } else { 249 luaL_error(L, "Encrypted data must be a table or binary string"); 250 return NULL; 251 } 252 } 253 254 /* 255 * Get key from binary string 256 * Returns pointer to key data (valid until Lua string is collected) 257 */ 258 static const uint8_t* get_key_from_arg(lua_State *L, int arg, size_t *key_len) { 259 size_t len; 260 const char *key_str = luaL_checklstring(L, arg, &len); 261 *key_len = len; 262 return (const uint8_t*)key_str; 263 } 264 265 /* generateKey() - Generate a random 32-byte key (returns binary string) */ 266 static int l_generateKey(lua_State *L) { 267 uint8_t key[32]; 268 random_bytes(key, 32); 269 lua_pushlstring(L, (const char*)key, 32); 270 return 1; 271 } 272 273 /* generateKeyString() - Generate a random key as base64 string */ 274 static int l_generateKeyString(lua_State *L) { 275 uint8_t key[32]; 276 random_bytes(key, 32); 277 278 size_t b64_len; 279 char *b64 = base64_encode(key, 32, &b64_len); 280 if (!b64) { 281 return luaL_error(L, "Base64 encoding failed"); 282 } 283 284 lua_pushlstring(L, b64, b64_len); 285 free(b64); 286 return 1; 287 } 288 289 /* ============================================================================ 290 * PBKDF2 Functions 291 * ========================================================================= */ 292 293 /* ============================================================================ 294 * AES-256-GCM Functions 295 * ========================================================================= */ 296 297 /* encrypt(key, plaintext, [length]) - Encrypt with AES-256-GCM, returns table with raw, length, :base64(), :hex() */ 298 static int l_encrypt(lua_State *L) { 299 size_t key_len; 300 const uint8_t *key = get_key_from_arg(L, 1, &key_len); 301 302 size_t plaintext_len; 303 const uint8_t *plaintext = (const uint8_t*)luaL_checklstring(L, 2, &plaintext_len); 304 305 /* Optional explicit length parameter - when provided, use exact binary length */ 306 if (!lua_isnoneornil(L, 3)) { 307 size_t explicit_len = luaL_checkinteger(L, 3); 308 if (explicit_len <= plaintext_len) { 309 plaintext_len = explicit_len; 310 } 311 } 312 313 size_t encrypted_len; 314 void *encrypted = ENCRYPT_AES(key, plaintext, plaintext_len, &encrypted_len); 315 316 if (!encrypted) { 317 return luaL_error(L, "Encryption failed"); 318 } 319 320 push_encrypted_data(L, encrypted, encrypted_len); 321 free(encrypted); 322 return 1; 323 } 324 325 /* decrypt(key, encrypted) - Decrypt with AES-256-GCM, accepts table or binary string, returns binary string */ 326 static int l_decrypt(lua_State *L) { 327 size_t key_len; 328 const uint8_t *key = get_key_from_arg(L, 1, &key_len); 329 330 size_t encrypted_len; 331 const uint8_t *encrypted = get_encrypted_from_arg(L, 2, &encrypted_len); 332 333 size_t plaintext_len; 334 void *plaintext = DECRYPT_AES(key, encrypted, encrypted_len, &plaintext_len); 335 336 if (!plaintext) { 337 return luaL_error(L, "Decryption failed (authentication error or corrupted data)"); 338 } 339 340 lua_pushlstring(L, (const char*)plaintext, plaintext_len); 341 free(plaintext); 342 return 1; 343 } 344 345 /* encryptAsBase64(key, plaintext) - Encrypt and return base64 string */ 346 static int l_encryptAsBase64(lua_State *L) { 347 size_t key_len; 348 const uint8_t *key = get_key_from_arg(L, 1, &key_len); 349 350 size_t plaintext_len; 351 const uint8_t *plaintext = (const uint8_t*)luaL_checklstring(L, 2, &plaintext_len); 352 353 size_t encrypted_len; 354 void *encrypted = ENCRYPT_AES(key, plaintext, plaintext_len, &encrypted_len); 355 356 if (!encrypted) { 357 return luaL_error(L, "Encryption failed"); 358 } 359 360 size_t b64_len; 361 char *b64 = base64_encode(encrypted, encrypted_len, &b64_len); 362 free(encrypted); 363 364 if (!b64) { 365 return luaL_error(L, "Base64 encoding failed"); 366 } 367 368 lua_pushlstring(L, b64, b64_len); 369 free(b64); 370 return 1; 371 } 372 373 /* decryptFromBase64(key, base64_encrypted) - Decrypt from base64 string */ 374 static int l_decryptFromBase64(lua_State *L) { 375 size_t key_len; 376 const uint8_t *key = get_key_from_arg(L, 1, &key_len); 377 378 size_t b64_len; 379 const char *b64 = luaL_checklstring(L, 2, &b64_len); 380 381 size_t encrypted_len; 382 uint8_t *encrypted = base64_decode(b64, b64_len, &encrypted_len); 383 384 if (!encrypted) { 385 return luaL_error(L, "Base64 decoding failed"); 386 } 387 388 size_t plaintext_len; 389 void *plaintext = DECRYPT_AES(key, encrypted, encrypted_len, &plaintext_len); 390 free(encrypted); 391 392 if (!plaintext) { 393 return luaL_error(L, "Decryption failed (authentication error or corrupted data)"); 394 } 395 396 lua_pushlstring(L, (const char*)plaintext, plaintext_len); 397 free(plaintext); 398 return 1; 399 } 400 401 /* ============================================================================ 402 * AES-128-GCM Functions 403 * ========================================================================= */ 404 405 /* encryptAES128(key, plaintext, [length]) - Encrypt with AES-128-GCM, returns table with raw, length, :base64(), :hex() */ 406 static int l_encryptAES128(lua_State *L) { 407 size_t key_len; 408 const uint8_t *key = get_key_from_arg(L, 1, &key_len); 409 410 /* Verify key is 16 bytes */ 411 if (key_len != 16) { 412 return luaL_error(L, "AES-128 requires 16-byte key (got %d bytes)", (int)key_len); 413 } 414 415 size_t plaintext_len; 416 const uint8_t *plaintext = (const uint8_t*)luaL_checklstring(L, 2, &plaintext_len); 417 418 /* Optional explicit length parameter - when provided, use exact binary length */ 419 if (!lua_isnoneornil(L, 3)) { 420 size_t explicit_len = luaL_checkinteger(L, 3); 421 if (explicit_len <= plaintext_len) { 422 plaintext_len = explicit_len; 423 } 424 } 425 426 size_t encrypted_len; 427 void *encrypted = ENCRYPT_AES128(key, plaintext, plaintext_len, &encrypted_len); 428 429 if (!encrypted) { 430 return luaL_error(L, "AES-128 encryption failed"); 431 } 432 433 push_encrypted_data(L, encrypted, encrypted_len); 434 free(encrypted); 435 return 1; 436 } 437 438 /* decryptAES128(key, encrypted) - Decrypt with AES-128-GCM, accepts table or binary string, returns binary string */ 439 static int l_decryptAES128(lua_State *L) { 440 size_t key_len; 441 const uint8_t *key = get_key_from_arg(L, 1, &key_len); 442 443 /* Verify key is 16 bytes */ 444 if (key_len != 16) { 445 return luaL_error(L, "AES-128 requires 16-byte key (got %d bytes)", (int)key_len); 446 } 447 448 size_t encrypted_len; 449 const uint8_t *encrypted = get_encrypted_from_arg(L, 2, &encrypted_len); 450 451 size_t plaintext_len; 452 void *plaintext = DECRYPT_AES128(key, encrypted, encrypted_len, &plaintext_len); 453 454 if (!plaintext) { 455 return luaL_error(L, "AES-128 decryption failed (authentication error or corrupted data)"); 456 } 457 458 lua_pushlstring(L, (const char*)plaintext, plaintext_len); 459 free(plaintext); 460 return 1; 461 } 462 463 /* encryptAES128String(key, plaintext) - Encrypt and return base64 string */ 464 static int l_encryptAES128String(lua_State *L) { 465 size_t key_len; 466 const uint8_t *key = get_key_from_arg(L, 1, &key_len); 467 468 /* Verify key is 16 bytes */ 469 if (key_len != 16) { 470 return luaL_error(L, "AES-128 requires 16-byte key (got %d bytes)", (int)key_len); 471 } 472 473 size_t plaintext_len; 474 const uint8_t *plaintext = (const uint8_t*)luaL_checklstring(L, 2, &plaintext_len); 475 476 size_t encrypted_len; 477 void *encrypted = ENCRYPT_AES128(key, plaintext, plaintext_len, &encrypted_len); 478 479 if (!encrypted) { 480 return luaL_error(L, "AES-128 encryption failed"); 481 } 482 483 size_t b64_len; 484 char *b64 = base64_encode(encrypted, encrypted_len, &b64_len); 485 free(encrypted); 486 487 if (!b64) { 488 return luaL_error(L, "Base64 encoding failed"); 489 } 490 491 lua_pushlstring(L, b64, b64_len); 492 free(b64); 493 return 1; 494 } 495 496 /* decryptAES128String(key, base64_encrypted) - Decrypt from base64 string */ 497 static int l_decryptAES128String(lua_State *L) { 498 size_t key_len; 499 const uint8_t *key = get_key_from_arg(L, 1, &key_len); 500 501 /* Verify key is 16 bytes */ 502 if (key_len != 16) { 503 return luaL_error(L, "AES-128 requires 16-byte key (got %d bytes)", (int)key_len); 504 } 505 506 size_t b64_len; 507 const char *b64 = luaL_checklstring(L, 2, &b64_len); 508 509 size_t encrypted_len; 510 uint8_t *encrypted = base64_decode(b64, b64_len, &encrypted_len); 511 512 if (!encrypted) { 513 return luaL_error(L, "Base64 decoding failed"); 514 } 515 516 size_t plaintext_len; 517 void *plaintext = DECRYPT_AES128(key, encrypted, encrypted_len, &plaintext_len); 518 free(encrypted); 519 520 if (!plaintext) { 521 return luaL_error(L, "AES-128 decryption failed (authentication error or corrupted data)"); 522 } 523 524 lua_pushlstring(L, (const char*)plaintext, plaintext_len); 525 free(plaintext); 526 return 1; 527 } 528 529 /* ============================================================================ 530 * ChaCha20-Poly1305 Functions 531 * ========================================================================= */ 532 533 /* encryptChaCha(key, plaintext, [length]) - Returns table with raw, length, :base64(), :hex() */ 534 static int l_encryptChaCha(lua_State *L) { 535 size_t key_len; 536 const uint8_t *key = get_key_from_arg(L, 1, &key_len); 537 538 size_t plaintext_len; 539 const uint8_t *plaintext = (const uint8_t*)luaL_checklstring(L, 2, &plaintext_len); 540 541 /* Optional explicit length parameter - when provided, use exact binary length */ 542 if (!lua_isnoneornil(L, 3)) { 543 size_t explicit_len = luaL_checkinteger(L, 3); 544 if (explicit_len <= plaintext_len) { 545 plaintext_len = explicit_len; 546 } 547 } 548 549 size_t encrypted_len; 550 void *encrypted = ENCRYPT_CHACHA(key, plaintext, plaintext_len, &encrypted_len); 551 552 if (!encrypted) { 553 return luaL_error(L, "ChaCha20 encryption failed"); 554 } 555 556 push_encrypted_data(L, encrypted, encrypted_len); 557 free(encrypted); 558 return 1; 559 } 560 561 /* decryptChaCha(key, encrypted) - Accepts table or binary string, returns binary string */ 562 static int l_decryptChaCha(lua_State *L) { 563 size_t key_len; 564 const uint8_t *key = get_key_from_arg(L, 1, &key_len); 565 566 size_t encrypted_len; 567 const uint8_t *encrypted = get_encrypted_from_arg(L, 2, &encrypted_len); 568 569 size_t plaintext_len; 570 void *plaintext = DECRYPT_CHACHA(key, encrypted, encrypted_len, &plaintext_len); 571 572 if (!plaintext) { 573 return luaL_error(L, "ChaCha20 decryption failed"); 574 } 575 576 lua_pushlstring(L, (const char*)plaintext, plaintext_len); 577 free(plaintext); 578 return 1; 579 } 580 581 /* encryptChaChaString(key, plaintext) - Returns base64 string */ 582 static int l_encryptChaChaString(lua_State *L) { 583 size_t key_len; 584 const uint8_t *key = get_key_from_arg(L, 1, &key_len); 585 586 size_t plaintext_len; 587 const uint8_t *plaintext = (const uint8_t*)luaL_checklstring(L, 2, &plaintext_len); 588 589 size_t encrypted_len; 590 void *encrypted = ENCRYPT_CHACHA(key, plaintext, plaintext_len, &encrypted_len); 591 592 if (!encrypted) { 593 return luaL_error(L, "ChaCha20 encryption failed"); 594 } 595 596 size_t b64_len; 597 char *b64 = base64_encode(encrypted, encrypted_len, &b64_len); 598 free(encrypted); 599 600 if (!b64) { 601 return luaL_error(L, "Base64 encoding failed"); 602 } 603 604 lua_pushlstring(L, b64, b64_len); 605 free(b64); 606 return 1; 607 } 608 609 /* decryptChaChaString(key, base64_encrypted) - Returns binary string */ 610 static int l_decryptChaChaString(lua_State *L) { 611 size_t key_len; 612 const uint8_t *key = get_key_from_arg(L, 1, &key_len); 613 614 size_t b64_len; 615 const char *b64 = luaL_checklstring(L, 2, &b64_len); 616 617 size_t encrypted_len; 618 uint8_t *encrypted = base64_decode(b64, b64_len, &encrypted_len); 619 620 if (!encrypted) { 621 return luaL_error(L, "Base64 decoding failed"); 622 } 623 624 size_t plaintext_len; 625 void *plaintext = DECRYPT_CHACHA(key, encrypted, encrypted_len, &plaintext_len); 626 free(encrypted); 627 628 if (!plaintext) { 629 return luaL_error(L, "ChaCha20 decryption failed"); 630 } 631 632 lua_pushlstring(L, (const char*)plaintext, plaintext_len); 633 free(plaintext); 634 return 1; 635 } 636 637 /* ============================================================================ 638 * XChaCha20-Poly1305 Functions 639 * ========================================================================= */ 640 641 /* encryptXChaCha(key, plaintext, [length]) - Returns table with raw, length, :base64(), :hex() */ 642 static int l_encryptXChaCha(lua_State *L) { 643 size_t key_len; 644 const uint8_t *key = get_key_from_arg(L, 1, &key_len); 645 646 size_t plaintext_len; 647 const uint8_t *plaintext = (const uint8_t*)luaL_checklstring(L, 2, &plaintext_len); 648 649 /* Optional explicit length parameter - when provided, use exact binary length */ 650 if (!lua_isnoneornil(L, 3)) { 651 size_t explicit_len = luaL_checkinteger(L, 3); 652 if (explicit_len <= plaintext_len) { 653 plaintext_len = explicit_len; 654 } 655 } 656 657 size_t encrypted_len; 658 void *encrypted = ENCRYPT_XCHACHA(key, plaintext, plaintext_len, &encrypted_len); 659 660 if (!encrypted) { 661 return luaL_error(L, "XChaCha20 encryption failed"); 662 } 663 664 push_encrypted_data(L, encrypted, encrypted_len); 665 free(encrypted); 666 return 1; 667 } 668 669 /* decryptXChaCha(key, encrypted) - Accepts table or binary string, returns binary string */ 670 static int l_decryptXChaCha(lua_State *L) { 671 size_t key_len; 672 const uint8_t *key = get_key_from_arg(L, 1, &key_len); 673 674 size_t encrypted_len; 675 const uint8_t *encrypted = get_encrypted_from_arg(L, 2, &encrypted_len); 676 677 size_t plaintext_len; 678 void *plaintext = DECRYPT_XCHACHA(key, encrypted, encrypted_len, &plaintext_len); 679 680 if (!plaintext) { 681 return luaL_error(L, "XChaCha20 decryption failed"); 682 } 683 684 lua_pushlstring(L, (const char*)plaintext, plaintext_len); 685 free(plaintext); 686 return 1; 687 } 688 689 /* encryptXChaChaString(key, plaintext) - Returns base64 string */ 690 static int l_encryptXChaChaString(lua_State *L) { 691 size_t key_len; 692 const uint8_t *key = get_key_from_arg(L, 1, &key_len); 693 694 size_t plaintext_len; 695 const uint8_t *plaintext = (const uint8_t*)luaL_checklstring(L, 2, &plaintext_len); 696 697 size_t encrypted_len; 698 void *encrypted = ENCRYPT_XCHACHA(key, plaintext, plaintext_len, &encrypted_len); 699 700 if (!encrypted) { 701 return luaL_error(L, "XChaCha20 encryption failed"); 702 } 703 704 size_t b64_len; 705 char *b64 = base64_encode(encrypted, encrypted_len, &b64_len); 706 free(encrypted); 707 708 if (!b64) { 709 return luaL_error(L, "Base64 encoding failed"); 710 } 711 712 lua_pushlstring(L, b64, b64_len); 713 free(b64); 714 return 1; 715 } 716 717 /* decryptXChaChaString(key, base64_encrypted) - Returns binary string */ 718 static int l_decryptXChaChaString(lua_State *L) { 719 size_t key_len; 720 const uint8_t *key = get_key_from_arg(L, 1, &key_len); 721 722 size_t b64_len; 723 const char *b64 = luaL_checklstring(L, 2, &b64_len); 724 725 size_t encrypted_len; 726 uint8_t *encrypted = base64_decode(b64, b64_len, &encrypted_len); 727 728 if (!encrypted) { 729 return luaL_error(L, "Base64 decoding failed"); 730 } 731 732 size_t plaintext_len; 733 void *plaintext = DECRYPT_XCHACHA(key, encrypted, encrypted_len, &plaintext_len); 734 free(encrypted); 735 736 if (!plaintext) { 737 return luaL_error(L, "XChaCha20 decryption failed"); 738 } 739 740 lua_pushlstring(L, (const char*)plaintext, plaintext_len); 741 free(plaintext); 742 return 1; 743 } 744 745 /* ============================================================================ 746 * Serpent-256-GCM Functions 747 * ========================================================================= */ 748 749 /* encryptSerpent(key, plaintext, [length]) - Returns table with raw, length, :base64(), :hex() */ 750 static int l_encryptSerpent(lua_State *L) { 751 size_t key_len; 752 const uint8_t *key = get_key_from_arg(L, 1, &key_len); 753 754 size_t plaintext_len; 755 const uint8_t *plaintext = (const uint8_t*)luaL_checklstring(L, 2, &plaintext_len); 756 757 /* Optional explicit length parameter - when provided, use exact binary length */ 758 if (!lua_isnoneornil(L, 3)) { 759 size_t explicit_len = luaL_checkinteger(L, 3); 760 if (explicit_len <= plaintext_len) { 761 plaintext_len = explicit_len; 762 } 763 } 764 765 size_t encrypted_len; 766 void *encrypted = ENCRYPT_SERPENT(key, plaintext, plaintext_len, &encrypted_len); 767 768 if (!encrypted) { 769 return luaL_error(L, "Serpent encryption failed"); 770 } 771 772 push_encrypted_data(L, encrypted, encrypted_len); 773 free(encrypted); 774 return 1; 775 } 776 777 /* decryptSerpent(key, encrypted) - Accepts table or binary string, returns binary string */ 778 static int l_decryptSerpent(lua_State *L) { 779 size_t key_len; 780 const uint8_t *key = get_key_from_arg(L, 1, &key_len); 781 782 size_t encrypted_len; 783 const uint8_t *encrypted = get_encrypted_from_arg(L, 2, &encrypted_len); 784 785 size_t plaintext_len; 786 void *plaintext = DECRYPT_SERPENT(key, encrypted, encrypted_len, &plaintext_len); 787 788 if (!plaintext) { 789 return luaL_error(L, "Serpent decryption failed"); 790 } 791 792 lua_pushlstring(L, (const char*)plaintext, plaintext_len); 793 free(plaintext); 794 return 1; 795 } 796 797 /* encryptSerpentString(key, plaintext) - Returns base64 string */ 798 static int l_encryptSerpentString(lua_State *L) { 799 size_t key_len; 800 const uint8_t *key = get_key_from_arg(L, 1, &key_len); 801 802 size_t plaintext_len; 803 const uint8_t *plaintext = (const uint8_t*)luaL_checklstring(L, 2, &plaintext_len); 804 805 size_t encrypted_len; 806 void *encrypted = ENCRYPT_SERPENT(key, plaintext, plaintext_len, &encrypted_len); 807 808 if (!encrypted) { 809 return luaL_error(L, "Serpent encryption failed"); 810 } 811 812 size_t b64_len; 813 char *b64 = base64_encode(encrypted, encrypted_len, &b64_len); 814 free(encrypted); 815 816 if (!b64) { 817 return luaL_error(L, "Base64 encoding failed"); 818 } 819 820 lua_pushlstring(L, b64, b64_len); 821 free(b64); 822 return 1; 823 } 824 825 /* decryptSerpentString(key, base64_encrypted) - Returns binary string */ 826 static int l_decryptSerpentString(lua_State *L) { 827 size_t key_len; 828 const uint8_t *key = get_key_from_arg(L, 1, &key_len); 829 830 size_t b64_len; 831 const char *b64 = luaL_checklstring(L, 2, &b64_len); 832 833 size_t encrypted_len; 834 uint8_t *encrypted = base64_decode(b64, b64_len, &encrypted_len); 835 836 if (!encrypted) { 837 return luaL_error(L, "Base64 decoding failed"); 838 } 839 840 size_t plaintext_len; 841 void *plaintext = DECRYPT_SERPENT(key, encrypted, encrypted_len, &plaintext_len); 842 free(encrypted); 843 844 if (!plaintext) { 845 return luaL_error(L, "Serpent decryption failed"); 846 } 847 848 lua_pushlstring(L, (const char*)plaintext, plaintext_len); 849 free(plaintext); 850 return 1; 851 } 852 853 /* ============================================================================ 854 * Twofish-256-GCM Functions 855 * ========================================================================= */ 856 857 /* encryptTwofish(key, plaintext, [length]) - Returns table with raw, length, :base64(), :hex() */ 858 static int l_encryptTwofish(lua_State *L) { 859 size_t key_len; 860 const uint8_t *key = get_key_from_arg(L, 1, &key_len); 861 862 size_t plaintext_len; 863 const uint8_t *plaintext = (const uint8_t*)luaL_checklstring(L, 2, &plaintext_len); 864 865 /* Optional explicit length parameter - when provided, use exact binary length */ 866 if (!lua_isnoneornil(L, 3)) { 867 size_t explicit_len = luaL_checkinteger(L, 3); 868 if (explicit_len <= plaintext_len) { 869 plaintext_len = explicit_len; 870 } 871 } 872 873 size_t encrypted_len; 874 void *encrypted = ENCRYPT_TWOFISH(key, plaintext, plaintext_len, &encrypted_len); 875 876 if (!encrypted) { 877 return luaL_error(L, "Twofish encryption failed"); 878 } 879 880 push_encrypted_data(L, encrypted, encrypted_len); 881 free(encrypted); 882 return 1; 883 } 884 885 /* decryptTwofish(key, encrypted) - Accepts table or binary string, returns binary string */ 886 static int l_decryptTwofish(lua_State *L) { 887 size_t key_len; 888 const uint8_t *key = get_key_from_arg(L, 1, &key_len); 889 890 size_t encrypted_len; 891 const uint8_t *encrypted = get_encrypted_from_arg(L, 2, &encrypted_len); 892 893 size_t plaintext_len; 894 void *plaintext = DECRYPT_TWOFISH(key, encrypted, encrypted_len, &plaintext_len); 895 896 if (!plaintext) { 897 return luaL_error(L, "Twofish decryption failed"); 898 } 899 900 lua_pushlstring(L, (const char*)plaintext, plaintext_len); 901 free(plaintext); 902 return 1; 903 } 904 905 /* encryptTwofishString(key, plaintext) - Returns base64 string */ 906 static int l_encryptTwofishString(lua_State *L) { 907 size_t key_len; 908 const uint8_t *key = get_key_from_arg(L, 1, &key_len); 909 910 size_t plaintext_len; 911 const uint8_t *plaintext = (const uint8_t*)luaL_checklstring(L, 2, &plaintext_len); 912 913 size_t encrypted_len; 914 void *encrypted = ENCRYPT_TWOFISH(key, plaintext, plaintext_len, &encrypted_len); 915 916 if (!encrypted) { 917 return luaL_error(L, "Twofish encryption failed"); 918 } 919 920 size_t b64_len; 921 char *b64 = base64_encode(encrypted, encrypted_len, &b64_len); 922 free(encrypted); 923 924 if (!b64) { 925 return luaL_error(L, "Base64 encoding failed"); 926 } 927 928 lua_pushlstring(L, b64, b64_len); 929 free(b64); 930 return 1; 931 } 932 933 /* decryptTwofishString(key, base64_encrypted) - Returns binary string */ 934 static int l_decryptTwofishString(lua_State *L) { 935 size_t key_len; 936 const uint8_t *key = get_key_from_arg(L, 1, &key_len); 937 938 size_t b64_len; 939 const char *b64 = luaL_checklstring(L, 2, &b64_len); 940 941 size_t encrypted_len; 942 uint8_t *encrypted = base64_decode(b64, b64_len, &encrypted_len); 943 944 if (!encrypted) { 945 return luaL_error(L, "Base64 decoding failed"); 946 } 947 948 size_t plaintext_len; 949 void *plaintext = DECRYPT_TWOFISH(key, encrypted, encrypted_len, &plaintext_len); 950 free(encrypted); 951 952 if (!plaintext) { 953 return luaL_error(L, "Twofish decryption failed"); 954 } 955 956 lua_pushlstring(L, (const char*)plaintext, plaintext_len); 957 free(plaintext); 958 return 1; 959 } 960 961 /* ============================================================================ 962 * Salsa20-Poly1305 Functions 963 * ========================================================================= */ 964 965 /* encryptSalsa(key, plaintext, [length]) - Returns table with raw, length, :base64(), :hex() */ 966 static int l_encryptSalsa(lua_State *L) { 967 size_t key_len; 968 const uint8_t *key = get_key_from_arg(L, 1, &key_len); 969 970 size_t plaintext_len; 971 const uint8_t *plaintext = (const uint8_t*)luaL_checklstring(L, 2, &plaintext_len); 972 973 /* Optional explicit length parameter - when provided, use exact binary length */ 974 if (!lua_isnoneornil(L, 3)) { 975 size_t explicit_len = luaL_checkinteger(L, 3); 976 if (explicit_len <= plaintext_len) { 977 plaintext_len = explicit_len; 978 } 979 } 980 981 size_t encrypted_len; 982 void *encrypted = ENCRYPT_SALSA(key, plaintext, plaintext_len, &encrypted_len); 983 984 if (!encrypted) { 985 return luaL_error(L, "Salsa20 encryption failed"); 986 } 987 988 push_encrypted_data(L, encrypted, encrypted_len); 989 free(encrypted); 990 return 1; 991 } 992 993 /* decryptSalsa(key, encrypted) - Accepts table or binary string, returns binary string */ 994 static int l_decryptSalsa(lua_State *L) { 995 size_t key_len; 996 const uint8_t *key = get_key_from_arg(L, 1, &key_len); 997 998 size_t encrypted_len; 999 const uint8_t *encrypted = get_encrypted_from_arg(L, 2, &encrypted_len); 1000 1001 size_t plaintext_len; 1002 void *plaintext = DECRYPT_SALSA(key, encrypted, encrypted_len, &plaintext_len); 1003 1004 if (!plaintext) { 1005 return luaL_error(L, "Salsa20 decryption failed"); 1006 } 1007 1008 lua_pushlstring(L, (const char*)plaintext, plaintext_len); 1009 free(plaintext); 1010 return 1; 1011 } 1012 1013 /* encryptSalsaString(key, plaintext) - Returns base64 string */ 1014 static int l_encryptSalsaString(lua_State *L) { 1015 size_t key_len; 1016 const uint8_t *key = get_key_from_arg(L, 1, &key_len); 1017 1018 size_t plaintext_len; 1019 const uint8_t *plaintext = (const uint8_t*)luaL_checklstring(L, 2, &plaintext_len); 1020 1021 size_t encrypted_len; 1022 void *encrypted = ENCRYPT_SALSA(key, plaintext, plaintext_len, &encrypted_len); 1023 1024 if (!encrypted) { 1025 return luaL_error(L, "Salsa20 encryption failed"); 1026 } 1027 1028 size_t b64_len; 1029 char *b64 = base64_encode(encrypted, encrypted_len, &b64_len); 1030 free(encrypted); 1031 1032 if (!b64) { 1033 return luaL_error(L, "Base64 encoding failed"); 1034 } 1035 1036 lua_pushlstring(L, b64, b64_len); 1037 free(b64); 1038 return 1; 1039 } 1040 1041 /* decryptSalsaString(key, base64_encrypted) - Returns binary string */ 1042 static int l_decryptSalsaString(lua_State *L) { 1043 size_t key_len; 1044 const uint8_t *key = get_key_from_arg(L, 1, &key_len); 1045 1046 size_t b64_len; 1047 const char *b64 = luaL_checklstring(L, 2, &b64_len); 1048 1049 size_t encrypted_len; 1050 uint8_t *encrypted = base64_decode(b64, b64_len, &encrypted_len); 1051 1052 if (!encrypted) { 1053 return luaL_error(L, "Base64 decoding failed"); 1054 } 1055 1056 size_t plaintext_len; 1057 void *plaintext = DECRYPT_SALSA(key, encrypted, encrypted_len, &plaintext_len); 1058 free(encrypted); 1059 1060 if (!plaintext) { 1061 return luaL_error(L, "Salsa20 decryption failed"); 1062 } 1063 1064 lua_pushlstring(L, (const char*)plaintext, plaintext_len); 1065 free(plaintext); 1066 return 1; 1067 } 1068 1069 /* ============================================================================ 1070 * Library Registration 1071 * ========================================================================= */ 1072 1073 static const luaL_Reg crypto_functions[] = { 1074 /* Key management */ 1075 {"generateKey", l_generateKey}, 1076 {"generateKeyString", l_generateKeyString}, 1077 1078 /* AES-256-GCM (default) */ 1079 {"encrypt", l_encrypt}, 1080 {"decrypt", l_decrypt}, 1081 {"encryptAsBase64", l_encryptAsBase64}, 1082 {"decryptFromBase64", l_decryptFromBase64}, 1083 1084 /* ChaCha20-Poly1305 */ 1085 {"encryptChaCha", l_encryptChaCha}, 1086 {"decryptChaCha", l_decryptChaCha}, 1087 {"encryptChaChaString", l_encryptChaChaString}, 1088 {"decryptChaChaString", l_decryptChaChaString}, 1089 1090 /* Serpent-256-GCM */ 1091 {"encryptSerpent", l_encryptSerpent}, 1092 {"decryptSerpent", l_decryptSerpent}, 1093 {"encryptSerpentString", l_encryptSerpentString}, 1094 {"decryptSerpentString", l_decryptSerpentString}, 1095 1096 /* Twofish-256-GCM */ 1097 {"encryptTwofish", l_encryptTwofish}, 1098 {"decryptTwofish", l_decryptTwofish}, 1099 {"encryptTwofishString", l_encryptTwofishString}, 1100 {"decryptTwofishString", l_decryptTwofishString}, 1101 1102 /* Salsa20-Poly1305 */ 1103 {"encryptSalsa", l_encryptSalsa}, 1104 {"decryptSalsa", l_decryptSalsa}, 1105 {"encryptSalsaString", l_encryptSalsaString}, 1106 {"decryptSalsaString", l_decryptSalsaString}, 1107 1108 /* PBKDF2 Key Derivation */ 1109 {"deriveKey", l_deriveKey}, 1110 {"deriveKeyString", l_deriveKeyString}, 1111 {"generateSalt", l_generateSalt}, 1112 1113 {NULL, NULL} 1114 }; 1115 1116 /* Module initialization */ 1117 int luaopen_crypto(lua_State *L) { 1118 /* Initialize CSPRNG */ 1119 csprng_global_init(); 1120 1121 /* Register CSPRNG metatable for instances */ 1122 register_csprng_metatable(L); 1123 1124 /* Create module table */ 1125 luaL_newlib(L, crypto_functions); 1126 1127 /* Create AES subtable - crypto.AES.encrypt/encryptAsBase64/decrypt/decryptFromBase64 (AES-256-GCM) */ 1128 lua_newtable(L); 1129 lua_pushcfunction(L, l_encrypt); 1130 lua_setfield(L, -2, "encrypt"); 1131 lua_pushcfunction(L, l_encryptAsBase64); 1132 lua_setfield(L, -2, "encryptAsBase64"); 1133 lua_pushcfunction(L, l_decrypt); 1134 lua_setfield(L, -2, "decrypt"); 1135 lua_pushcfunction(L, l_decryptFromBase64); 1136 lua_setfield(L, -2, "decryptFromBase64"); 1137 lua_setfield(L, -2, "AES"); 1138 1139 /* Create AES128 subtable - crypto.AES128.encrypt/encryptAsBase64/decrypt/decryptFromBase64 (AES-128-GCM) */ 1140 lua_newtable(L); 1141 lua_pushcfunction(L, l_encryptAES128); 1142 lua_setfield(L, -2, "encrypt"); 1143 lua_pushcfunction(L, l_encryptAES128String); 1144 lua_setfield(L, -2, "encryptAsBase64"); 1145 lua_pushcfunction(L, l_decryptAES128); 1146 lua_setfield(L, -2, "decrypt"); 1147 lua_pushcfunction(L, l_decryptAES128String); 1148 lua_setfield(L, -2, "decryptFromBase64"); 1149 lua_setfield(L, -2, "AES128"); 1150 1151 /* Create ChaCha20 subtable */ 1152 lua_newtable(L); 1153 lua_pushcfunction(L, l_encryptChaCha); 1154 lua_setfield(L, -2, "encrypt"); 1155 lua_pushcfunction(L, l_encryptChaChaString); 1156 lua_setfield(L, -2, "encryptAsBase64"); 1157 lua_pushcfunction(L, l_decryptChaCha); 1158 lua_setfield(L, -2, "decrypt"); 1159 lua_pushcfunction(L, l_decryptChaChaString); 1160 lua_setfield(L, -2, "decryptFromBase64"); 1161 lua_setfield(L, -2, "ChaCha20"); 1162 1163 /* Create XChaCha20 subtable */ 1164 lua_newtable(L); 1165 lua_pushcfunction(L, l_encryptXChaCha); 1166 lua_setfield(L, -2, "encrypt"); 1167 lua_pushcfunction(L, l_encryptXChaChaString); 1168 lua_setfield(L, -2, "encryptAsBase64"); 1169 lua_pushcfunction(L, l_decryptXChaCha); 1170 lua_setfield(L, -2, "decrypt"); 1171 lua_pushcfunction(L, l_decryptXChaChaString); 1172 lua_setfield(L, -2, "decryptFromBase64"); 1173 lua_setfield(L, -2, "XChaCha20"); 1174 1175 /* Create Serpent subtable */ 1176 lua_newtable(L); 1177 lua_pushcfunction(L, l_encryptSerpent); 1178 lua_setfield(L, -2, "encrypt"); 1179 lua_pushcfunction(L, l_encryptSerpentString); 1180 lua_setfield(L, -2, "encryptAsBase64"); 1181 lua_pushcfunction(L, l_decryptSerpent); 1182 lua_setfield(L, -2, "decrypt"); 1183 lua_pushcfunction(L, l_decryptSerpentString); 1184 lua_setfield(L, -2, "decryptFromBase64"); 1185 lua_setfield(L, -2, "Serpent"); 1186 1187 /* Create Twofish subtable */ 1188 lua_newtable(L); 1189 lua_pushcfunction(L, l_encryptTwofish); 1190 lua_setfield(L, -2, "encrypt"); 1191 lua_pushcfunction(L, l_encryptTwofishString); 1192 lua_setfield(L, -2, "encryptAsBase64"); 1193 lua_pushcfunction(L, l_decryptTwofish); 1194 lua_setfield(L, -2, "decrypt"); 1195 lua_pushcfunction(L, l_decryptTwofishString); 1196 lua_setfield(L, -2, "decryptFromBase64"); 1197 lua_setfield(L, -2, "Twofish"); 1198 1199 /* Create Salsa20 subtable */ 1200 lua_newtable(L); 1201 lua_pushcfunction(L, l_encryptSalsa); 1202 lua_setfield(L, -2, "encrypt"); 1203 lua_pushcfunction(L, l_encryptSalsaString); 1204 lua_setfield(L, -2, "encryptAsBase64"); 1205 lua_pushcfunction(L, l_decryptSalsa); 1206 lua_setfield(L, -2, "decrypt"); 1207 lua_pushcfunction(L, l_decryptSalsaString); 1208 lua_setfield(L, -2, "decryptFromBase64"); 1209 lua_setfield(L, -2, "Salsa20"); 1210 1211 /* Register hash functions directly on crypto table */ 1212 lua_pushcfunction(L, l_hash); 1213 lua_setfield(L, -2, "SHA256"); 1214 1215 lua_pushcfunction(L, l_hash_sha512); 1216 lua_setfield(L, -2, "SHA512"); 1217 1218 lua_pushcfunction(L, l_hash_sha1); 1219 lua_setfield(L, -2, "SHA1"); 1220 1221 lua_pushcfunction(L, l_hash_md5); 1222 lua_setfield(L, -2, "MD5"); 1223 1224 lua_pushcfunction(L, l_hash_crc32); 1225 lua_setfield(L, -2, "CRC32"); 1226 1227 lua_pushcfunction(L, l_hash_sha3); 1228 lua_setfield(L, -2, "SHA3-256"); 1229 lua_pushcfunction(L, l_hash_sha3_512); 1230 lua_setfield(L, -2, "SHA3-512"); 1231 1232 lua_pushcfunction(L, l_hash_blake2b); 1233 lua_setfield(L, -2, "BLAKE2b-256"); 1234 lua_pushcfunction(L, l_hash_blake2b_512); 1235 lua_setfield(L, -2, "BLAKE2b-512"); 1236 1237 /* Register KDF functions directly on crypto table */ 1238 lua_pushcfunction(L, l_deriveKey); 1239 lua_setfield(L, -2, "PBKDF2"); 1240 1241 lua_pushcfunction(L, l_argon2id_derive); 1242 lua_setfield(L, -2, "Argon2id"); 1243 1244 lua_pushcfunction(L, l_hkdf_derive); 1245 lua_setfield(L, -2, "HKDF"); 1246 1247 lua_pushcfunction(L, l_generateSalt); 1248 lua_setfield(L, -2, "generateSalt"); 1249 1250 /* Add simple deriveKey function at top level - crypto.deriveKey(password) uses Argon2id */ 1251 lua_pushcfunction(L, l_deriveKeySimple); 1252 lua_setfield(L, -2, "deriveKey"); 1253 1254 /* Create X25519 subtable - crypto.X25519.keypair/publicKey/sharedSecret */ 1255 lua_newtable(L); 1256 lua_pushcfunction(L, l_x25519_keypair); 1257 lua_setfield(L, -2, "keypair"); 1258 lua_pushcfunction(L, l_x25519_public_key); 1259 lua_setfield(L, -2, "publicKey"); 1260 lua_pushcfunction(L, l_x25519_shared_secret); 1261 lua_setfield(L, -2, "sharedSecret"); 1262 lua_setfield(L, -2, "X25519"); 1263 1264 /* Create Ed25519 subtable - crypto.Ed25519.keypair/sign/verify */ 1265 lua_newtable(L); 1266 lua_pushcfunction(L, l_ed25519_keypair); 1267 lua_setfield(L, -2, "keypair"); 1268 lua_pushcfunction(L, l_ed25519_sign); 1269 lua_setfield(L, -2, "sign"); 1270 lua_pushcfunction(L, l_ed25519_verify); 1271 lua_setfield(L, -2, "verify"); 1272 lua_setfield(L, -2, "Ed25519"); 1273 1274 /* Create RSA subtable - crypto.RSA.generateKeypair/encrypt/decrypt/sign/verify/signPSS/verifyPSS */ 1275 lua_newtable(L); 1276 lua_pushcfunction(L, l_rsa_generate_keypair); 1277 lua_setfield(L, -2, "generateKeypair"); 1278 lua_pushcfunction(L, l_rsa_encrypt); 1279 lua_setfield(L, -2, "encrypt"); 1280 lua_pushcfunction(L, l_rsa_decrypt); 1281 lua_setfield(L, -2, "decrypt"); 1282 lua_pushcfunction(L, l_rsa_sign); 1283 lua_setfield(L, -2, "sign"); 1284 lua_pushcfunction(L, l_rsa_verify); 1285 lua_setfield(L, -2, "verify"); 1286 lua_pushcfunction(L, l_rsa_sign_pss); 1287 lua_setfield(L, -2, "signPSS"); 1288 lua_pushcfunction(L, l_rsa_verify_pss); 1289 lua_setfield(L, -2, "verifyPSS"); 1290 lua_setfield(L, -2, "RSA"); 1291 1292 /* Create CSPRNG subtable - crypto.CSPRNG.newKey/randomBytes/new */ 1293 lua_newtable(L); 1294 lua_pushcfunction(L, l_csprng_new_key); 1295 lua_setfield(L, -2, "newKey"); 1296 lua_pushcfunction(L, l_csprng_random_bytes); 1297 lua_setfield(L, -2, "randomBytes"); 1298 lua_pushcfunction(L, l_csprng_new_instance); 1299 lua_setfield(L, -2, "new"); 1300 lua_setfield(L, -2, "CSPRNG"); 1301 1302 /* Create P256 subtable - crypto.P256.ecdhKeypair/ecdhPublicKey/ecdhSharedSecret/ecdsaKeypair/ecdsaSign/ecdsaVerify */ 1303 lua_newtable(L); 1304 lua_pushcfunction(L, l_p256_ecdh_keypair); 1305 lua_setfield(L, -2, "ecdhKeypair"); 1306 lua_pushcfunction(L, l_p256_ecdh_public_key); 1307 lua_setfield(L, -2, "ecdhPublicKey"); 1308 lua_pushcfunction(L, l_p256_ecdh_shared_secret); 1309 lua_setfield(L, -2, "ecdhSharedSecret"); 1310 lua_pushcfunction(L, l_p256_ecdsa_keypair); 1311 lua_setfield(L, -2, "ecdsaKeypair"); 1312 lua_pushcfunction(L, l_p256_ecdsa_sign); 1313 lua_setfield(L, -2, "ecdsaSign"); 1314 lua_pushcfunction(L, l_p256_ecdsa_verify); 1315 lua_setfield(L, -2, "ecdsaVerify"); 1316 lua_setfield(L, -2, "P256"); 1317 1318 /* Create Kyber subtable - Post-quantum key encapsulation (CRYSTALS-Kyber) */ 1319 lua_newtable(L); 1320 /* Kyber512 - NIST Level 1 security */ 1321 lua_pushcfunction(L, l_kyber512_keypair); 1322 lua_setfield(L, -2, "keypair512"); 1323 lua_pushcfunction(L, l_kyber512_encapsulate); 1324 lua_setfield(L, -2, "encapsulate512"); 1325 lua_pushcfunction(L, l_kyber512_decapsulate); 1326 lua_setfield(L, -2, "decapsulate512"); 1327 /* Kyber768 - NIST Level 3 security (recommended) */ 1328 lua_pushcfunction(L, l_kyber768_keypair); 1329 lua_setfield(L, -2, "keypair"); 1330 lua_pushcfunction(L, l_kyber768_keypair); 1331 lua_setfield(L, -2, "keypair768"); 1332 lua_pushcfunction(L, l_kyber768_encapsulate); 1333 lua_setfield(L, -2, "encapsulate"); 1334 lua_pushcfunction(L, l_kyber768_encapsulate); 1335 lua_setfield(L, -2, "encapsulate768"); 1336 lua_pushcfunction(L, l_kyber768_decapsulate); 1337 lua_setfield(L, -2, "decapsulate"); 1338 lua_pushcfunction(L, l_kyber768_decapsulate); 1339 lua_setfield(L, -2, "decapsulate768"); 1340 /* Kyber1024 - NIST Level 5 security */ 1341 lua_pushcfunction(L, l_kyber1024_keypair); 1342 lua_setfield(L, -2, "keypair1024"); 1343 lua_pushcfunction(L, l_kyber1024_encapsulate); 1344 lua_setfield(L, -2, "encapsulate1024"); 1345 lua_pushcfunction(L, l_kyber1024_decapsulate); 1346 lua_setfield(L, -2, "decapsulate1024"); 1347 lua_setfield(L, -2, "Kyber"); 1348 1349 /* Create Dilithium subtable - Post-quantum digital signatures (CRYSTALS-Dilithium) */ 1350 lua_newtable(L); 1351 /* Dilithium2 - NIST Level 2 security */ 1352 lua_pushcfunction(L, l_dilithium2_keypair); 1353 lua_setfield(L, -2, "keypair2"); 1354 lua_pushcfunction(L, l_dilithium2_sign); 1355 lua_setfield(L, -2, "sign2"); 1356 lua_pushcfunction(L, l_dilithium2_verify); 1357 lua_setfield(L, -2, "verify2"); 1358 /* Dilithium3 - NIST Level 3 security (recommended) */ 1359 lua_pushcfunction(L, l_dilithium3_keypair); 1360 lua_setfield(L, -2, "keypair"); 1361 lua_pushcfunction(L, l_dilithium3_keypair); 1362 lua_setfield(L, -2, "keypair3"); 1363 lua_pushcfunction(L, l_dilithium3_sign); 1364 lua_setfield(L, -2, "sign"); 1365 lua_pushcfunction(L, l_dilithium3_sign); 1366 lua_setfield(L, -2, "sign3"); 1367 lua_pushcfunction(L, l_dilithium3_verify); 1368 lua_setfield(L, -2, "verify"); 1369 lua_pushcfunction(L, l_dilithium3_verify); 1370 lua_setfield(L, -2, "verify3"); 1371 /* Dilithium5 - NIST Level 5 security */ 1372 lua_pushcfunction(L, l_dilithium5_keypair); 1373 lua_setfield(L, -2, "keypair5"); 1374 lua_pushcfunction(L, l_dilithium5_sign); 1375 lua_setfield(L, -2, "sign5"); 1376 lua_pushcfunction(L, l_dilithium5_verify); 1377 lua_setfield(L, -2, "verify5"); 1378 lua_setfield(L, -2, "Dilithium"); 1379 1380 /* Keep default encrypt/decrypt at top level (AES) for convenience */ 1381 lua_pushcfunction(L, l_encrypt); 1382 lua_setfield(L, -2, "encrypt"); 1383 lua_pushcfunction(L, l_encryptAsBase64); 1384 lua_setfield(L, -2, "encryptAsBase64"); 1385 lua_pushcfunction(L, l_decrypt); 1386 lua_setfield(L, -2, "decrypt"); 1387 lua_pushcfunction(L, l_decryptFromBase64); 1388 lua_setfield(L, -2, "decryptFromBase64"); 1389 1390 return 1; 1391 }