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 }