Dilithium_Lua.c (9099B)
1 /* 2 * Dilithium_Lua.c - Lua bindings for CRYSTALS-Dilithium post-quantum signatures 3 */ 4 5 #include "Dilithium_Lua.h" 6 #include "Dilithium.h" 7 #include <string.h> 8 #include <stdlib.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 13 /* ============================================================================ 14 * Dilithium2 Lua Bindings 15 * ========================================================================= */ 16 17 /* dilithium2.keypair() - Generate Dilithium2 keypair */ 18 int l_dilithium2_keypair(lua_State *L) { 19 uint8_t public_key[DILITHIUM2_PUBLIC_KEY_BYTES]; 20 uint8_t secret_key[DILITHIUM2_SECRET_KEY_BYTES]; 21 22 /* Generate keypair */ 23 if (dilithium2_keypair(public_key, secret_key) != 0) { 24 memset(secret_key, 0, DILITHIUM2_SECRET_KEY_BYTES); 25 return luaL_error(L, "Dilithium2 keypair generation failed"); 26 } 27 28 /* Encode to base64 */ 29 size_t pub_b64_len, sec_b64_len; 30 char *pub_b64 = base64_encode(public_key, DILITHIUM2_PUBLIC_KEY_BYTES, &pub_b64_len); 31 char *sec_b64 = base64_encode(secret_key, DILITHIUM2_SECRET_KEY_BYTES, &sec_b64_len); 32 33 /* Zero sensitive data */ 34 memset(secret_key, 0, DILITHIUM2_SECRET_KEY_BYTES); 35 36 if (!pub_b64 || !sec_b64) { 37 free(pub_b64); 38 free(sec_b64); 39 return luaL_error(L, "Base64 encoding failed"); 40 } 41 42 /* Return public_key, secret_key */ 43 lua_pushlstring(L, pub_b64, pub_b64_len); 44 lua_pushlstring(L, sec_b64, sec_b64_len); 45 46 free(pub_b64); 47 free(sec_b64); 48 return 2; 49 } 50 51 /* dilithium2.sign(message, secret_key) - Sign message */ 52 int l_dilithium2_sign(lua_State *L) { 53 size_t message_len, secret_len; 54 const uint8_t *message = (const uint8_t*)luaL_checklstring(L, 1, &message_len); 55 const uint8_t *secret_key = (const uint8_t*)luaL_checklstring(L, 2, &secret_len); 56 57 if (secret_len != DILITHIUM2_SECRET_KEY_BYTES) { 58 return luaL_error(L, "Secret key must be %d bytes", DILITHIUM2_SECRET_KEY_BYTES); 59 } 60 61 uint8_t signature[DILITHIUM2_SIGNATURE_BYTES]; 62 size_t signature_len; 63 64 /* Sign message */ 65 if (dilithium2_sign(signature, &signature_len, message, message_len, secret_key) != 0) { 66 return luaL_error(L, "Dilithium2 signing failed"); 67 } 68 69 /* Encode to base64 */ 70 size_t sig_b64_len; 71 char *sig_b64 = base64_encode(signature, signature_len, &sig_b64_len); 72 73 if (!sig_b64) { 74 return luaL_error(L, "Base64 encoding failed"); 75 } 76 77 lua_pushlstring(L, sig_b64, sig_b64_len); 78 free(sig_b64); 79 return 1; 80 } 81 82 /* dilithium2.verify(message, signature, public_key) - Verify signature */ 83 int l_dilithium2_verify(lua_State *L) { 84 size_t message_len, signature_len, public_len; 85 const uint8_t *message = (const uint8_t*)luaL_checklstring(L, 1, &message_len); 86 const uint8_t *signature = (const uint8_t*)luaL_checklstring(L, 2, &signature_len); 87 const uint8_t *public_key = (const uint8_t*)luaL_checklstring(L, 3, &public_len); 88 89 if (signature_len != DILITHIUM2_SIGNATURE_BYTES) { 90 return luaL_error(L, "Signature must be %d bytes", DILITHIUM2_SIGNATURE_BYTES); 91 } 92 93 if (public_len != DILITHIUM2_PUBLIC_KEY_BYTES) { 94 return luaL_error(L, "Public key must be %d bytes", DILITHIUM2_PUBLIC_KEY_BYTES); 95 } 96 97 /* Verify signature */ 98 int result = dilithium2_verify(signature, signature_len, message, message_len, public_key); 99 100 lua_pushboolean(L, result == 0); 101 return 1; 102 } 103 104 /* ============================================================================ 105 * Dilithium3 Lua Bindings (RECOMMENDED) 106 * ========================================================================= */ 107 108 int l_dilithium3_keypair(lua_State *L) { 109 uint8_t public_key[DILITHIUM3_PUBLIC_KEY_BYTES]; 110 uint8_t secret_key[DILITHIUM3_SECRET_KEY_BYTES]; 111 112 if (dilithium3_keypair(public_key, secret_key) != 0) { 113 memset(secret_key, 0, DILITHIUM3_SECRET_KEY_BYTES); 114 return luaL_error(L, "Dilithium3 keypair generation failed"); 115 } 116 117 size_t pub_b64_len, sec_b64_len; 118 char *pub_b64 = base64_encode(public_key, DILITHIUM3_PUBLIC_KEY_BYTES, &pub_b64_len); 119 char *sec_b64 = base64_encode(secret_key, DILITHIUM3_SECRET_KEY_BYTES, &sec_b64_len); 120 121 memset(secret_key, 0, DILITHIUM3_SECRET_KEY_BYTES); 122 123 if (!pub_b64 || !sec_b64) { 124 free(pub_b64); 125 free(sec_b64); 126 return luaL_error(L, "Base64 encoding failed"); 127 } 128 129 lua_pushlstring(L, pub_b64, pub_b64_len); 130 lua_pushlstring(L, sec_b64, sec_b64_len); 131 132 free(pub_b64); 133 free(sec_b64); 134 return 2; 135 } 136 137 int l_dilithium3_sign(lua_State *L) { 138 size_t message_len, secret_len; 139 const uint8_t *message = (const uint8_t*)luaL_checklstring(L, 1, &message_len); 140 const uint8_t *secret_key = (const uint8_t*)luaL_checklstring(L, 2, &secret_len); 141 142 if (secret_len != DILITHIUM3_SECRET_KEY_BYTES) { 143 return luaL_error(L, "Secret key must be %d bytes", DILITHIUM3_SECRET_KEY_BYTES); 144 } 145 146 uint8_t signature[DILITHIUM3_SIGNATURE_BYTES]; 147 size_t signature_len; 148 149 if (dilithium3_sign(signature, &signature_len, message, message_len, secret_key) != 0) { 150 return luaL_error(L, "Dilithium3 signing failed"); 151 } 152 153 size_t sig_b64_len; 154 char *sig_b64 = base64_encode(signature, signature_len, &sig_b64_len); 155 156 if (!sig_b64) { 157 return luaL_error(L, "Base64 encoding failed"); 158 } 159 160 lua_pushlstring(L, sig_b64, sig_b64_len); 161 free(sig_b64); 162 return 1; 163 } 164 165 int l_dilithium3_verify(lua_State *L) { 166 size_t message_len, signature_len, public_len; 167 const uint8_t *message = (const uint8_t*)luaL_checklstring(L, 1, &message_len); 168 const uint8_t *signature = (const uint8_t*)luaL_checklstring(L, 2, &signature_len); 169 const uint8_t *public_key = (const uint8_t*)luaL_checklstring(L, 3, &public_len); 170 171 if (signature_len != DILITHIUM3_SIGNATURE_BYTES) { 172 return luaL_error(L, "Signature must be %d bytes", DILITHIUM3_SIGNATURE_BYTES); 173 } 174 175 if (public_len != DILITHIUM3_PUBLIC_KEY_BYTES) { 176 return luaL_error(L, "Public key must be %d bytes", DILITHIUM3_PUBLIC_KEY_BYTES); 177 } 178 179 int result = dilithium3_verify(signature, signature_len, message, message_len, public_key); 180 181 lua_pushboolean(L, result == 0); 182 return 1; 183 } 184 185 /* ============================================================================ 186 * Dilithium5 Lua Bindings 187 * ========================================================================= */ 188 189 int l_dilithium5_keypair(lua_State *L) { 190 uint8_t public_key[DILITHIUM5_PUBLIC_KEY_BYTES]; 191 uint8_t secret_key[DILITHIUM5_SECRET_KEY_BYTES]; 192 193 if (dilithium5_keypair(public_key, secret_key) != 0) { 194 memset(secret_key, 0, DILITHIUM5_SECRET_KEY_BYTES); 195 return luaL_error(L, "Dilithium5 keypair generation failed"); 196 } 197 198 size_t pub_b64_len, sec_b64_len; 199 char *pub_b64 = base64_encode(public_key, DILITHIUM5_PUBLIC_KEY_BYTES, &pub_b64_len); 200 char *sec_b64 = base64_encode(secret_key, DILITHIUM5_SECRET_KEY_BYTES, &sec_b64_len); 201 202 memset(secret_key, 0, DILITHIUM5_SECRET_KEY_BYTES); 203 204 if (!pub_b64 || !sec_b64) { 205 free(pub_b64); 206 free(sec_b64); 207 return luaL_error(L, "Base64 encoding failed"); 208 } 209 210 lua_pushlstring(L, pub_b64, pub_b64_len); 211 lua_pushlstring(L, sec_b64, sec_b64_len); 212 213 free(pub_b64); 214 free(sec_b64); 215 return 2; 216 } 217 218 int l_dilithium5_sign(lua_State *L) { 219 size_t message_len, secret_len; 220 const uint8_t *message = (const uint8_t*)luaL_checklstring(L, 1, &message_len); 221 const uint8_t *secret_key = (const uint8_t*)luaL_checklstring(L, 2, &secret_len); 222 223 if (secret_len != DILITHIUM5_SECRET_KEY_BYTES) { 224 return luaL_error(L, "Secret key must be %d bytes", DILITHIUM5_SECRET_KEY_BYTES); 225 } 226 227 uint8_t signature[DILITHIUM5_SIGNATURE_BYTES]; 228 size_t signature_len; 229 230 if (dilithium5_sign(signature, &signature_len, message, message_len, secret_key) != 0) { 231 return luaL_error(L, "Dilithium5 signing failed"); 232 } 233 234 size_t sig_b64_len; 235 char *sig_b64 = base64_encode(signature, signature_len, &sig_b64_len); 236 237 if (!sig_b64) { 238 return luaL_error(L, "Base64 encoding failed"); 239 } 240 241 lua_pushlstring(L, sig_b64, sig_b64_len); 242 free(sig_b64); 243 return 1; 244 } 245 246 int l_dilithium5_verify(lua_State *L) { 247 size_t message_len, signature_len, public_len; 248 const uint8_t *message = (const uint8_t*)luaL_checklstring(L, 1, &message_len); 249 const uint8_t *signature = (const uint8_t*)luaL_checklstring(L, 2, &signature_len); 250 const uint8_t *public_key = (const uint8_t*)luaL_checklstring(L, 3, &public_len); 251 252 if (signature_len != DILITHIUM5_SIGNATURE_BYTES) { 253 return luaL_error(L, "Signature must be %d bytes", DILITHIUM5_SIGNATURE_BYTES); 254 } 255 256 if (public_len != DILITHIUM5_PUBLIC_KEY_BYTES) { 257 return luaL_error(L, "Public key must be %d bytes", DILITHIUM5_PUBLIC_KEY_BYTES); 258 } 259 260 int result = dilithium5_verify(signature, signature_len, message, message_len, public_key); 261 262 lua_pushboolean(L, result == 0); 263 return 1; 264 }