luajitos

Unnamed repository; edit this file 'description' to name the repository.
Log | Files | Refs

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 }