From b93a91f4f0effc1252aed3738603067d3b4e783c Mon Sep 17 00:00:00 2001 From: Mathias Berchtold Date: Thu, 3 Sep 2026 05:04:18 +0200 Subject: [PATCH 1/2] chacha20poly1305: uses native unaligned 32-bit little-endian loads/stores uses native unaligned 32-bit little-endian loads and stores on WebAssembly. - scalar and SIMD ChaCha20 improved by 0.82% and 0.23%, respectively; - scalar and SIMD-target Poly1305 improved by 35.32% and 34.44%; and - scalar and production SQLite page encryption improved by 3.91% and 13.21%. --- src/chacha20poly1305.c | 39 ++++++++++++++++++++++++++++----------- 1 file changed, 28 insertions(+), 11 deletions(-) diff --git a/src/chacha20poly1305.c b/src/chacha20poly1305.c index 86157dc0..30bd3600 100644 --- a/src/chacha20poly1305.c +++ b/src/chacha20poly1305.c @@ -13,12 +13,33 @@ #define ROL32(x, c) (((x) << (c)) | ((x) >> (32-(c)))) #define ROR32(x, c) (((x) >> (c)) | ((x) << (32-(c)))) -#define LOAD32_LE(p) \ - ( ((uint32_t)((p)[0]) << 0) \ - | ((uint32_t)((p)[1]) << 8) \ - | ((uint32_t)((p)[2]) << 16) \ - | ((uint32_t)((p)[3]) << 24) \ - ) +static inline uint32_t load32_le_(const void* p) +{ +#if defined(__wasm__) || (defined(__BYTE_ORDER__) && __BYTE_ORDER__ == __ORDER_LITTLE_ENDIAN__) + uint32_t v; + memcpy(&v, p, 4); + return v; +#else + const uint8_t* b = (const uint8_t*)p; + return (uint32_t)b[0] | (uint32_t)b[1] << 8 + | (uint32_t)b[2] << 16 | (uint32_t)b[3] << 24; +#endif +} + +static inline void store32_le_(void* p, uint32_t v) +{ +#if defined(__wasm__) || (defined(__BYTE_ORDER__) && __BYTE_ORDER__ == __ORDER_LITTLE_ENDIAN__) + memcpy(p, &v, 4); +#else + uint8_t* b = (uint8_t*)p; + b[0] = (uint8_t)(v); + b[1] = (uint8_t)(v >> 8); + b[2] = (uint8_t)(v >> 16); + b[3] = (uint8_t)(v >> 24); +#endif +} + +#define LOAD32_LE(p) load32_le_(p) #define LOAD32_BE(p) \ ( ((uint32_t)((p)[3]) << 0) \ | ((uint32_t)((p)[2]) << 8) \ @@ -26,11 +47,7 @@ | ((uint32_t)((p)[0]) << 24) \ ) -#define STORE32_LE(p, v) \ - (p)[0] = ((v) >> 0) & 0xFF; \ - (p)[1] = ((v) >> 8) & 0xFF; \ - (p)[2] = ((v) >> 16) & 0xFF; \ - (p)[3] = ((v) >> 24) & 0xFF; +#define STORE32_LE(p, v) store32_le_((p), (v)) #define STORE32_BE(p, v) \ (p)[3] = ((v) >> 0) & 0xFF; \ (p)[2] = ((v) >> 8) & 0xFF; \ From 10f6fb4014403e7536b3095c51fb66b7530438a7 Mon Sep 17 00:00:00 2001 From: Mathias Berchtold Date: Thu, 3 Sep 2026 16:51:34 +0200 Subject: [PATCH 2/2] Added check for_MSC_VER --- src/chacha20poly1305.c | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/src/chacha20poly1305.c b/src/chacha20poly1305.c index 30bd3600..369e7a7f 100644 --- a/src/chacha20poly1305.c +++ b/src/chacha20poly1305.c @@ -15,7 +15,8 @@ static inline uint32_t load32_le_(const void* p) { -#if defined(__wasm__) || (defined(__BYTE_ORDER__) && __BYTE_ORDER__ == __ORDER_LITTLE_ENDIAN__) +#if defined(__wasm__) || defined(_MSC_VER) \ + || (defined(__BYTE_ORDER__) && __BYTE_ORDER__ == __ORDER_LITTLE_ENDIAN__) uint32_t v; memcpy(&v, p, 4); return v; @@ -28,7 +29,8 @@ static inline uint32_t load32_le_(const void* p) static inline void store32_le_(void* p, uint32_t v) { -#if defined(__wasm__) || (defined(__BYTE_ORDER__) && __BYTE_ORDER__ == __ORDER_LITTLE_ENDIAN__) +#if defined(__wasm__) || defined(_MSC_VER) \ + || (defined(__BYTE_ORDER__) && __BYTE_ORDER__ == __ORDER_LITTLE_ENDIAN__) memcpy(p, &v, 4); #else uint8_t* b = (uint8_t*)p;