X25519_Lua.c (2902B)
1 /* 2 * X25519_Lua.c - Lua bindings for X25519 key exchange 3 */ 4 5 #include "X25519_Lua.h" 6 #include "X25519.h" 7 #include "CSPRNG.h" 8 #include <string.h> 9 #include <stdlib.h> 10 11 /* Base64 encoding function (provided by crypto.c) */ 12 extern char* base64_encode(const uint8_t *data, size_t len, size_t *out_len); 13 14 /* x25519.keypair() - Generate X25519 keypair (returns public_key_b64, secret_key_b64) */ 15 int l_x25519_keypair(lua_State *L) { 16 uint8_t secret_key[32]; 17 uint8_t public_key[32]; 18 19 /* Generate random secret key */ 20 random_bytes(secret_key, 32); 21 22 /* Generate public key */ 23 x25519_public_key(public_key, secret_key); 24 25 /* Encode to base64 */ 26 size_t pub_b64_len, sec_b64_len; 27 char *pub_b64 = base64_encode(public_key, 32, &pub_b64_len); 28 char *sec_b64 = base64_encode(secret_key, 32, &sec_b64_len); 29 30 /* Zero sensitive data */ 31 memset(secret_key, 0, 32); 32 33 if (!pub_b64 || !sec_b64) { 34 free(pub_b64); 35 free(sec_b64); 36 return luaL_error(L, "Base64 encoding failed"); 37 } 38 39 /* Return public_key, secret_key */ 40 lua_pushlstring(L, pub_b64, pub_b64_len); 41 lua_pushlstring(L, sec_b64, sec_b64_len); 42 43 free(pub_b64); 44 free(sec_b64); 45 return 2; 46 } 47 48 /* x25519.publicKey(secret_key) - Derive public key from secret key */ 49 int l_x25519_public_key(lua_State *L) { 50 size_t secret_len; 51 const uint8_t *secret_key = (const uint8_t*)luaL_checklstring(L, 1, &secret_len); 52 53 if (secret_len != 32) { 54 return luaL_error(L, "Secret key must be 32 bytes"); 55 } 56 57 uint8_t public_key[32]; 58 x25519_public_key(public_key, secret_key); 59 60 size_t b64_len; 61 char *b64 = base64_encode(public_key, 32, &b64_len); 62 63 if (!b64) { 64 return luaL_error(L, "Base64 encoding failed"); 65 } 66 67 lua_pushlstring(L, b64, b64_len); 68 free(b64); 69 return 1; 70 } 71 72 /* x25519.sharedSecret(my_secret, their_public) - Compute shared secret */ 73 int l_x25519_shared_secret(lua_State *L) { 74 size_t my_secret_len, their_public_len; 75 const uint8_t *my_secret = (const uint8_t*)luaL_checklstring(L, 1, &my_secret_len); 76 const uint8_t *their_public = (const uint8_t*)luaL_checklstring(L, 2, &their_public_len); 77 78 if (my_secret_len != 32) { 79 return luaL_error(L, "Secret key must be 32 bytes"); 80 } 81 82 if (their_public_len != 32) { 83 return luaL_error(L, "Public key must be 32 bytes"); 84 } 85 86 uint8_t shared_secret[32]; 87 if (x25519_shared_secret(shared_secret, my_secret, their_public) != 0) { 88 memset(shared_secret, 0, 32); 89 return luaL_error(L, "Invalid public key (weak key detected)"); 90 } 91 92 size_t b64_len; 93 char *b64 = base64_encode(shared_secret, 32, &b64_len); 94 memset(shared_secret, 0, 32); /* Zero sensitive data */ 95 96 if (!b64) { 97 return luaL_error(L, "Base64 encoding failed"); 98 } 99 100 lua_pushlstring(L, b64, b64_len); 101 free(b64); 102 return 1; 103 }