33#define ED25519_NO_SEED 1
44#include < ed_25519.h>
55
6+ // For ESP32, we use libsodium for cryptographic operations to reduce stack usage
7+ #ifdef USE_ESP32_ENCRYPTION
8+ #include < sodium.h>
9+ #endif
10+
611namespace mesh {
712
813Identity::Identity () {
@@ -14,7 +19,14 @@ Identity::Identity(const char* pub_hex) {
1419}
1520
1621bool Identity::verify (const uint8_t * sig, const uint8_t * message, int msg_len) const {
17- return ed25519_verify (sig, message, msg_len, pub_key);
22+ #ifdef USE_ESP32_ENCRYPTION
23+ // Using libsodium for verification on ESP32 to reduce stack usage
24+ // This function performs signature verification with much lower stack requirements
25+ // than the default implementation
26+ return crypto_sign_ed25519_verify_detached (sig, message, msg_len, pub_key) == 0 ;
27+ #else
28+ return ed25519_verify (sig, message, msg_len, pub_key);
29+ #endif
1830}
1931
2032bool Identity::readFrom (Stream& s) {
@@ -32,14 +44,29 @@ void Identity::printTo(Stream& s) const {
3244LocalIdentity::LocalIdentity () {
3345 memset (prv_key, 0 , sizeof (prv_key));
3446}
47+
3548LocalIdentity::LocalIdentity (const char * prv_hex, const char * pub_hex) : Identity(pub_hex) {
3649 Utils::fromHex (prv_key, PRV_KEY_SIZE, prv_hex);
3750}
3851
3952LocalIdentity::LocalIdentity (RNG* rng) {
4053 uint8_t seed[SEED_SIZE];
4154 rng->random (seed, SEED_SIZE);
42- ed25519_create_keypair (pub_key, prv_key, seed);
55+
56+ #ifdef USE_ESP32_ENCRYPTION
57+ // Use libsodium for keypair generation on ESP32 to reduce stack usage
58+ // NOTE: Format differences between implementations:
59+ // - The current ed25519 implementation (orlp/ed25519) uses a 64-byte private key format
60+ // - Libsodium also uses a 64-byte format for Ed25519 secret keys, where:
61+ // * First 32 bytes: the actual private key seed
62+ // * Last 32 bytes: the corresponding public key
63+
64+ // Generate keypair using libsodium with the provided seed
65+ // This avoids the deep stack usage of the default implementation
66+ crypto_sign_ed25519_seed_keypair (pub_key, prv_key, seed);
67+ #else
68+ ed25519_create_keypair (pub_key, prv_key, seed);
69+ #endif
4370}
4471
4572bool LocalIdentity::readFrom (Stream& s) {
@@ -77,17 +104,51 @@ void LocalIdentity::readFrom(const uint8_t* src, size_t len) {
77104 memcpy (pub_key, &src[PRV_KEY_SIZE], PUB_KEY_SIZE);
78105 } else if (len == PRV_KEY_SIZE) {
79106 memcpy (prv_key, src, PRV_KEY_SIZE);
80- // now need to re-calculate the pub_key
81- ed25519_derive_pub (pub_key, prv_key);
107+
108+ #ifdef USE_ESP32_ENCRYPTION
109+ // In libsodium, the private key already contains the public key in its last 32 bytes
110+ // We can just extract it directly, avoiding the expensive derivation calculation
111+ // This significantly reduces stack usage on ESP32
112+ memcpy (pub_key, prv_key + 32 , 32 );
113+ #else
114+ // now need to re-calculate the pub_key
115+ ed25519_derive_pub (pub_key, prv_key);
116+ #endif
82117 }
83118}
84119
85120void LocalIdentity::sign (uint8_t * sig, const uint8_t * message, int msg_len) const {
86- ed25519_sign (sig, message, msg_len, pub_key, prv_key);
121+ #ifdef USE_ESP32_ENCRYPTION
122+ // Use libsodium for signing on ESP32 to reduce stack usage
123+ // The libsodium implementation uses less stack space than the default ed25519 implementation
124+ crypto_sign_ed25519_detached (sig, NULL , message, msg_len, prv_key);
125+ #else
126+ ed25519_sign (sig, message, msg_len, pub_key, prv_key);
127+ #endif
87128}
88129
89130void LocalIdentity::calcSharedSecret (uint8_t * secret, const uint8_t * other_pub_key) {
90- ed25519_key_exchange (secret, other_pub_key, prv_key);
131+ #ifdef USE_ESP32_ENCRYPTION
132+ // NOTE: To calculate a shared secret with Ed25519 keys and libsodium, we need to:
133+ // 1. Convert the Ed25519 keys to Curve25519 (X25519) format
134+ // 2. Perform the key exchange using the converted keys
135+ //
136+ // The default implementation handles this conversion internally,
137+ // but with libsodium we need to do these steps explicitly.
138+ // This approach uses less stack space compared to the original implementation.
139+
140+ unsigned char x25519_pk[crypto_scalarmult_curve25519_BYTES];
141+ unsigned char x25519_sk[crypto_scalarmult_curve25519_BYTES];
142+
143+ // Convert Ed25519 keys to Curve25519 keys for ECDH
144+ crypto_sign_ed25519_pk_to_curve25519 (x25519_pk, other_pub_key);
145+ crypto_sign_ed25519_sk_to_curve25519 (x25519_sk, prv_key);
146+
147+ // Calculate shared secret using X25519
148+ crypto_scalarmult_curve25519 (secret, x25519_sk, x25519_pk);
149+ #else
150+ ed25519_key_exchange (secret, other_pub_key, prv_key);
151+ #endif
91152}
92153
93154}
0 commit comments