Skip to content

Commit ed320ac

Browse files
Alex WoldenAlex Wolden
authored andcommitted
add libsodium
1 parent 21ba611 commit ed320ac

File tree

2 files changed

+72
-12
lines changed

2 files changed

+72
-12
lines changed

platformio.ini

Lines changed: 5 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -342,6 +342,7 @@ build_flags =
342342
-D RADIO_CLASS=CustomSX1276
343343
-D WRAPPER_CLASS=CustomSX1276Wrapper
344344
-D LORA_TX_POWER=20
345+
-D USE_ESP32_ENCRYPTION=true
345346

346347
; =============
347348
[LilyGo_T3S3_sx1262]
@@ -376,11 +377,9 @@ build_flags =
376377
-D ADVERT_LAT=-37.0
377378
-D ADVERT_LON=145.0
378379
-D ADMIN_PASSWORD="\"password\""
379-
-D MESH_PACKET_LOGGING=1
380-
-D MESH_DEBUG=1
381-
-D CORE_DEBUG_LEVEL=3
382-
-D SPI_MAX_DMA_LEN=1024
383-
-D BLE_TASK_SIZE=4096
380+
; -D MESH_PACKET_LOGGING=1
381+
; -D MESH_DEBUG=1
382+
; -D CORE_DEBUG_LEVEL=3
384383

385384
[env:LilyGo_T3_sx1276_terminal_chat]
386385
extends = LilyGo_T3_sx1276
@@ -417,7 +416,7 @@ build_flags =
417416
-D MAX_CONTACTS=100
418417
-D MAX_GROUP_CHANNELS=1
419418
-D BLE_PIN_CODE=123456
420-
-D BLE_DEBUG_LOGGING=1
419+
; -D BLE_DEBUG_LOGGING=1
421420
; -D ENABLE_PRIVATE_KEY_IMPORT=1
422421
; -D ENABLE_PRIVATE_KEY_EXPORT=1
423422
; -D MESH_PACKET_LOGGING=1

src/Identity.cpp

Lines changed: 67 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,11 @@
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+
611
namespace mesh {
712

813
Identity::Identity() {
@@ -14,7 +19,14 @@ Identity::Identity(const char* pub_hex) {
1419
}
1520

1621
bool 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

2032
bool Identity::readFrom(Stream& s) {
@@ -32,14 +44,29 @@ void Identity::printTo(Stream& s) const {
3244
LocalIdentity::LocalIdentity() {
3345
memset(prv_key, 0, sizeof(prv_key));
3446
}
47+
3548
LocalIdentity::LocalIdentity(const char* prv_hex, const char* pub_hex) : Identity(pub_hex) {
3649
Utils::fromHex(prv_key, PRV_KEY_SIZE, prv_hex);
3750
}
3851

3952
LocalIdentity::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

4572
bool 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

85120
void 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

89130
void 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

Comments
 (0)