luajitos

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

X25519.c (2027B)


      1 /*
      2  * X25519 - Elliptic Curve Diffie-Hellman using Curve25519
      3  * RFC 7748
      4  *
      5  * Fast, secure key exchange using Montgomery ladder
      6  */
      7 
      8 #include "X25519.h"
      9 #include <string.h>
     10 
     11 /* External functions from Curve25519.c */
     12 extern void curve25519_scalarmult_base(uint8_t *q, const uint8_t *n);
     13 extern void curve25519_scalarmult(uint8_t *q, const uint8_t *n, const uint8_t *p);
     14 
     15 /*
     16  * Generate X25519 public key from secret key
     17  *
     18  * Secret key should be 32 random bytes
     19  * This function clamps the secret key according to RFC 7748
     20  */
     21 void x25519_public_key(uint8_t public_key[32], const uint8_t secret_key[32]) {
     22     uint8_t clamped[32];
     23     memcpy(clamped, secret_key, 32);
     24 
     25     /* Clamp the secret key (RFC 7748 section 5) */
     26     clamped[0] &= 248;   /* Clear bits 0, 1, 2 */
     27     clamped[31] &= 127;  /* Clear bit 255 */
     28     clamped[31] |= 64;   /* Set bit 254 */
     29 
     30     /* Compute public key = secret * G (base point) */
     31     curve25519_scalarmult_base(public_key, clamped);
     32 
     33     /* Zero sensitive data */
     34     memset(clamped, 0, 32);
     35 }
     36 
     37 /*
     38  * Compute X25519 shared secret
     39  *
     40  * Returns 0 on success, -1 if the public key is invalid (all-zero result)
     41  * An all-zero result indicates a weak/invalid public key
     42  */
     43 int x25519_shared_secret(uint8_t shared_secret[32],
     44                          const uint8_t my_secret_key[32],
     45                          const uint8_t their_public_key[32]) {
     46     uint8_t clamped[32];
     47     memcpy(clamped, my_secret_key, 32);
     48 
     49     /* Clamp the secret key */
     50     clamped[0] &= 248;
     51     clamped[31] &= 127;
     52     clamped[31] |= 64;
     53 
     54     /* Compute shared secret = my_secret * their_public */
     55     curve25519_scalarmult(shared_secret, clamped, their_public_key);
     56 
     57     /* Zero sensitive data */
     58     memset(clamped, 0, 32);
     59 
     60     /* Check for all-zero result (weak public key) */
     61     uint8_t is_zero = 1;
     62     for (int i = 0; i < 32; i++) {
     63         is_zero &= (shared_secret[i] == 0);
     64     }
     65 
     66     if (is_zero) {
     67         memset(shared_secret, 0, 32);
     68         return -1;  /* Invalid public key */
     69     }
     70 
     71     return 0;
     72 }