luajitos

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

P256_Lua.c (7604B)


      1 /*
      2  * P256_Lua.c - Lua bindings for P-256 (secp256r1) elliptic curve
      3  */
      4 
      5 #include "P256_Lua.h"
      6 #include "P256.h"
      7 #include <stdlib.h>
      8 #include <string.h>
      9 
     10 /* Base64 encoding function (provided by crypto.c) */
     11 extern char* base64_encode(const uint8_t *data, size_t len, size_t *out_len);
     12 extern uint8_t* base64_decode(const char *data, size_t len, size_t *out_len);
     13 
     14 /* ============================================================================
     15  * P-256 ECDH Functions
     16  * ========================================================================= */
     17 
     18 /**
     19  * Generate P-256 ECDH keypair
     20  * Usage: public_key_b64, private_key_b64 = crypto.P256.ecdhKeypair()
     21  */
     22 int l_p256_ecdh_keypair(lua_State *L) {
     23     uint8_t public_key[65];
     24     uint8_t private_key[32];
     25 
     26     p256_ecdh_keypair(public_key, private_key);
     27 
     28     /* Encode to base64 */
     29     size_t pub_b64_len, priv_b64_len;
     30     char *pub_b64 = base64_encode(public_key, 65, &pub_b64_len);
     31     char *priv_b64 = base64_encode(private_key, 32, &priv_b64_len);
     32 
     33     if (!pub_b64 || !priv_b64) {
     34         free(pub_b64);
     35         free(priv_b64);
     36         return luaL_error(L, "Base64 encoding failed");
     37     }
     38 
     39     lua_pushlstring(L, pub_b64, pub_b64_len);
     40     lua_pushlstring(L, priv_b64, priv_b64_len);
     41 
     42     free(pub_b64);
     43     free(priv_b64);
     44 
     45     return 2;
     46 }
     47 
     48 /**
     49  * Derive P-256 public key from private key
     50  * Usage: public_key_b64 = crypto.P256.ecdhPublicKey(private_key_b64)
     51  */
     52 int l_p256_ecdh_public_key(lua_State *L) {
     53     size_t priv_key_len;
     54     const char *priv_key_b64 = luaL_checklstring(L, 1, &priv_key_len);
     55 
     56     /* Decode private key */
     57     size_t priv_decoded_len;
     58     uint8_t *priv_decoded = base64_decode(priv_key_b64, priv_key_len, &priv_decoded_len);
     59     if (!priv_decoded || priv_decoded_len != 32) {
     60         free(priv_decoded);
     61         return luaL_error(L, "Invalid private key (expected 32 bytes)");
     62     }
     63 
     64     /* Derive public key */
     65     uint8_t public_key[65];
     66     p256_ecdh_public_key(public_key, priv_decoded);
     67     free(priv_decoded);
     68 
     69     /* Encode to base64 */
     70     size_t pub_b64_len;
     71     char *pub_b64 = base64_encode(public_key, 65, &pub_b64_len);
     72     if (!pub_b64) {
     73         return luaL_error(L, "Base64 encoding failed");
     74     }
     75 
     76     lua_pushlstring(L, pub_b64, pub_b64_len);
     77     free(pub_b64);
     78 
     79     return 1;
     80 }
     81 
     82 /**
     83  * Compute P-256 ECDH shared secret
     84  * Usage: shared_secret_b64 = crypto.P256.ecdhSharedSecret(my_private_key_b64, their_public_key_b64)
     85  */
     86 int l_p256_ecdh_shared_secret(lua_State *L) {
     87     size_t my_priv_len, their_pub_len;
     88     const char *my_priv_b64 = luaL_checklstring(L, 1, &my_priv_len);
     89     const char *their_pub_b64 = luaL_checklstring(L, 2, &their_pub_len);
     90 
     91     /* Decode my private key */
     92     size_t my_priv_decoded_len;
     93     uint8_t *my_priv_decoded = base64_decode(my_priv_b64, my_priv_len, &my_priv_decoded_len);
     94     if (!my_priv_decoded || my_priv_decoded_len != 32) {
     95         free(my_priv_decoded);
     96         return luaL_error(L, "Invalid private key (expected 32 bytes)");
     97     }
     98 
     99     /* Decode their public key */
    100     size_t their_pub_decoded_len;
    101     uint8_t *their_pub_decoded = base64_decode(their_pub_b64, their_pub_len, &their_pub_decoded_len);
    102     if (!their_pub_decoded || their_pub_decoded_len != 65) {
    103         free(my_priv_decoded);
    104         free(their_pub_decoded);
    105         return luaL_error(L, "Invalid public key (expected 65 bytes)");
    106     }
    107 
    108     /* Compute shared secret */
    109     uint8_t shared_secret[32];
    110     int result = p256_ecdh_shared_secret(shared_secret, my_priv_decoded, their_pub_decoded);
    111     free(my_priv_decoded);
    112     free(their_pub_decoded);
    113 
    114     if (result != 0) {
    115         return luaL_error(L, "ECDH shared secret computation failed");
    116     }
    117 
    118     /* Encode to base64 */
    119     size_t shared_b64_len;
    120     char *shared_b64 = base64_encode(shared_secret, 32, &shared_b64_len);
    121     if (!shared_b64) {
    122         return luaL_error(L, "Base64 encoding failed");
    123     }
    124 
    125     lua_pushlstring(L, shared_b64, shared_b64_len);
    126     free(shared_b64);
    127 
    128     return 1;
    129 }
    130 
    131 /* ============================================================================
    132  * P-256 ECDSA Functions
    133  * ========================================================================= */
    134 
    135 /**
    136  * Generate P-256 ECDSA keypair
    137  * Usage: public_key_b64, private_key_b64 = crypto.P256.ecdsaKeypair()
    138  */
    139 int l_p256_ecdsa_keypair(lua_State *L) {
    140     uint8_t public_key[65];
    141     uint8_t private_key[32];
    142 
    143     p256_ecdsa_keypair(public_key, private_key);
    144 
    145     /* Encode to base64 */
    146     size_t pub_b64_len, priv_b64_len;
    147     char *pub_b64 = base64_encode(public_key, 65, &pub_b64_len);
    148     char *priv_b64 = base64_encode(private_key, 32, &priv_b64_len);
    149 
    150     if (!pub_b64 || !priv_b64) {
    151         free(pub_b64);
    152         free(priv_b64);
    153         return luaL_error(L, "Base64 encoding failed");
    154     }
    155 
    156     lua_pushlstring(L, pub_b64, pub_b64_len);
    157     lua_pushlstring(L, priv_b64, priv_b64_len);
    158 
    159     free(pub_b64);
    160     free(priv_b64);
    161 
    162     return 2;
    163 }
    164 
    165 /**
    166  * Sign message with P-256 ECDSA
    167  * Usage: signature_b64 = crypto.P256.ecdsaSign(message_hash, private_key_b64)
    168  */
    169 int l_p256_ecdsa_sign(lua_State *L) {
    170     size_t msg_hash_len, priv_key_len;
    171     const uint8_t *msg_hash = (const uint8_t*)luaL_checklstring(L, 1, &msg_hash_len);
    172     const char *priv_key_b64 = luaL_checklstring(L, 2, &priv_key_len);
    173 
    174     /* Check message hash length */
    175     if (msg_hash_len != 32) {
    176         return luaL_error(L, "Message hash must be 32 bytes (SHA-256)");
    177     }
    178 
    179     /* Decode private key */
    180     size_t priv_decoded_len;
    181     uint8_t *priv_decoded = base64_decode(priv_key_b64, priv_key_len, &priv_decoded_len);
    182     if (!priv_decoded || priv_decoded_len != 32) {
    183         free(priv_decoded);
    184         return luaL_error(L, "Invalid private key (expected 32 bytes)");
    185     }
    186 
    187     /* Sign */
    188     uint8_t signature[64];
    189     int result = p256_ecdsa_sign(signature, msg_hash, priv_decoded);
    190     free(priv_decoded);
    191 
    192     if (result != 0) {
    193         return luaL_error(L, "ECDSA signing failed");
    194     }
    195 
    196     /* Encode to base64 */
    197     size_t sig_b64_len;
    198     char *sig_b64 = base64_encode(signature, 64, &sig_b64_len);
    199     if (!sig_b64) {
    200         return luaL_error(L, "Base64 encoding failed");
    201     }
    202 
    203     lua_pushlstring(L, sig_b64, sig_b64_len);
    204     free(sig_b64);
    205 
    206     return 1;
    207 }
    208 
    209 /**
    210  * Verify P-256 ECDSA signature
    211  * Usage: valid = crypto.P256.ecdsaVerify(signature_b64, message_hash, public_key_b64)
    212  */
    213 int l_p256_ecdsa_verify(lua_State *L) {
    214     size_t sig_len, msg_hash_len, pub_key_len;
    215     const char *sig_b64 = luaL_checklstring(L, 1, &sig_len);
    216     const uint8_t *msg_hash = (const uint8_t*)luaL_checklstring(L, 2, &msg_hash_len);
    217     const char *pub_key_b64 = luaL_checklstring(L, 3, &pub_key_len);
    218 
    219     /* Check message hash length */
    220     if (msg_hash_len != 32) {
    221         return luaL_error(L, "Message hash must be 32 bytes (SHA-256)");
    222     }
    223 
    224     /* Decode signature */
    225     size_t sig_decoded_len;
    226     uint8_t *sig_decoded = base64_decode(sig_b64, sig_len, &sig_decoded_len);
    227     if (!sig_decoded || sig_decoded_len != 64) {
    228         free(sig_decoded);
    229         return luaL_error(L, "Invalid signature (expected 64 bytes)");
    230     }
    231 
    232     /* Decode public key */
    233     size_t pub_decoded_len;
    234     uint8_t *pub_decoded = base64_decode(pub_key_b64, pub_key_len, &pub_decoded_len);
    235     if (!pub_decoded || pub_decoded_len != 65) {
    236         free(sig_decoded);
    237         free(pub_decoded);
    238         return luaL_error(L, "Invalid public key (expected 65 bytes)");
    239     }
    240 
    241     /* Verify */
    242     int result = p256_ecdsa_verify(sig_decoded, msg_hash, pub_decoded);
    243     free(sig_decoded);
    244     free(pub_decoded);
    245 
    246     lua_pushboolean(L, result == 0);
    247     return 1;
    248 }