From 49c57dfe0ad6d975cd30e2525269c8c783159d7d Mon Sep 17 00:00:00 2001 From: Frank Denis Date: Fri, 26 Feb 2016 13:15:36 +0100 Subject: [PATCH] Faster HChaCha20 --- .../crypto_core/hchacha20/core_hchacha20.c | 80 +++++++++++++------ .../crypto_core/hchacha20/core_hchacha20.h | 14 ---- 2 files changed, 56 insertions(+), 38 deletions(-) diff --git a/src/libsodium/crypto_core/hchacha20/core_hchacha20.c b/src/libsodium/crypto_core/hchacha20/core_hchacha20.c index 93c190a3..13e67396 100644 --- a/src/libsodium/crypto_core/hchacha20/core_hchacha20.c +++ b/src/libsodium/crypto_core/hchacha20/core_hchacha20.c @@ -1,10 +1,42 @@ #include #include +#include #include "core_hchacha20.h" #include "crypto_core_hchacha20.h" +static inline uint32_t +load32(const void *src) +{ +#ifdef NATIVE_LITTLE_ENDIAN + uint32_t w; + memcpy(&w, src, sizeof w); + return w; +#else + const uint8_t *p = (const uint8_t *) src; + uint32_t w = *p++; + w |= (uint32_t)(*p++) << 8; + w |= (uint32_t)(*p++) << 16; + w |= (uint32_t)(*p++) << 24; + return w; +#endif +} + +static inline void +store32(void *dst, uint32_t w) +{ +#ifdef NATIVE_LITTLE_ENDIAN + memcpy(dst, &w, sizeof w); +#else + uint8_t *p = (uint8_t *) dst; + *p++ = (uint8_t) w; w >>= 8; + *p++ = (uint8_t) w; w >>= 8; + *p++ = (uint8_t) w; w >>= 8; + *p++ = (uint8_t) w; +#endif +} + int crypto_core_hchacha20(unsigned char *out, const unsigned char *in, const unsigned char *k, const unsigned char *c) @@ -19,23 +51,23 @@ crypto_core_hchacha20(unsigned char *out, const unsigned char *in, x2 = U32C(0x79622d32); x3 = U32C(0x6b206574); } else { - x0 = U8TO32_LITTLE(c + 0); - x1 = U8TO32_LITTLE(c + 4); - x2 = U8TO32_LITTLE(c + 8); - x3 = U8TO32_LITTLE(c + 12); + x0 = load32(c + 0); + x1 = load32(c + 4); + x2 = load32(c + 8); + x3 = load32(c + 12); } - x4 = U8TO32_LITTLE(k + 0); - x5 = U8TO32_LITTLE(k + 4); - x6 = U8TO32_LITTLE(k + 8); - x7 = U8TO32_LITTLE(k + 12); - x8 = U8TO32_LITTLE(k + 16); - x9 = U8TO32_LITTLE(k + 20); - x10 = U8TO32_LITTLE(k + 24); - x11 = U8TO32_LITTLE(k + 28); - x12 = U8TO32_LITTLE(in + 0); - x13 = U8TO32_LITTLE(in + 4); - x14 = U8TO32_LITTLE(in + 8); - x15 = U8TO32_LITTLE(in + 12); + x4 = load32(k + 0); + x5 = load32(k + 4); + x6 = load32(k + 8); + x7 = load32(k + 12); + x8 = load32(k + 16); + x9 = load32(k + 20); + x10 = load32(k + 24); + x11 = load32(k + 28); + x12 = load32(in + 0); + x13 = load32(in + 4); + x14 = load32(in + 8); + x15 = load32(in + 12); for (i = 0; i < 10; i++) { QUARTERROUND(x0, x4, x8, x12); @@ -48,14 +80,14 @@ crypto_core_hchacha20(unsigned char *out, const unsigned char *in, QUARTERROUND(x3, x4, x9, x14); } - U32TO8_LITTLE(out + 0, x0); - U32TO8_LITTLE(out + 4, x1); - U32TO8_LITTLE(out + 8, x2); - U32TO8_LITTLE(out + 12, x3); - U32TO8_LITTLE(out + 16, x12); - U32TO8_LITTLE(out + 20, x13); - U32TO8_LITTLE(out + 24, x14); - U32TO8_LITTLE(out + 28, x15); + store32(out + 0, x0); + store32(out + 4, x1); + store32(out + 8, x2); + store32(out + 12, x3); + store32(out + 16, x12); + store32(out + 20, x13); + store32(out + 24, x14); + store32(out + 28, x15); return 0; } diff --git a/src/libsodium/crypto_core/hchacha20/core_hchacha20.h b/src/libsodium/crypto_core/hchacha20/core_hchacha20.h index 12aac7df..c1419f3c 100644 --- a/src/libsodium/crypto_core/hchacha20/core_hchacha20.h +++ b/src/libsodium/crypto_core/hchacha20/core_hchacha20.h @@ -9,20 +9,6 @@ #define ROTL32(v, n) (U32V((v) << (n)) | ((v) >> (32 - (n)))) -#define U8TO32_LITTLE(p) \ - (((uint32_t)((p)[0]) ) | \ - ((uint32_t)((p)[1]) << 8) | \ - ((uint32_t)((p)[2]) << 16) | \ - ((uint32_t)((p)[3]) << 24)) - -#define U32TO8_LITTLE(p, v) \ - do { \ - (p)[0] = U8V((v) ); \ - (p)[1] = U8V((v) >> 8); \ - (p)[2] = U8V((v) >> 16); \ - (p)[3] = U8V((v) >> 24); \ - } while (0) - #define ROTATE(v, c) (ROTL32(v, c)) #define XOR(v, w) ((v) ^ (w)) #define PLUS(v, w) (U32V((v) + (w)))