From 4d5c3976db76f1f9370c0afe4709a40fc50261eb Mon Sep 17 00:00:00 2001 From: Frank Denis Date: Fri, 26 Feb 2016 11:38:48 +0100 Subject: [PATCH] Add HChaCha20 --- src/libsodium/Makefile.am | 2 + .../crypto_core/hchacha20/core_hchacha20.c | 85 +++++++++++++++++++ .../crypto_core/hchacha20/core_hchacha20.h | 38 +++++++++ src/libsodium/include/Makefile.am | 1 + src/libsodium/include/sodium.h | 1 + .../include/sodium/crypto_core_hchacha20.h | 35 ++++++++ 6 files changed, 162 insertions(+) create mode 100644 src/libsodium/crypto_core/hchacha20/core_hchacha20.c create mode 100644 src/libsodium/crypto_core/hchacha20/core_hchacha20.h create mode 100644 src/libsodium/include/sodium/crypto_core_hchacha20.h diff --git a/src/libsodium/Makefile.am b/src/libsodium/Makefile.am index a37c2a96..553af852 100644 --- a/src/libsodium/Makefile.am +++ b/src/libsodium/Makefile.am @@ -168,6 +168,8 @@ endif if !MINIMAL libsodium_la_SOURCES += \ + crypto_core/hchacha20/core_hchacha20.c \ + crypto_core/hchacha20/core_hchacha20.h \ crypto_core/salsa2012/ref/core_salsa2012.c \ crypto_core/salsa2012/core_salsa2012_api.c \ crypto_core/salsa208/ref/core_salsa208.c \ diff --git a/src/libsodium/crypto_core/hchacha20/core_hchacha20.c b/src/libsodium/crypto_core/hchacha20/core_hchacha20.c new file mode 100644 index 00000000..b5e376b7 --- /dev/null +++ b/src/libsodium/crypto_core/hchacha20/core_hchacha20.c @@ -0,0 +1,85 @@ + +#include +#include + +#include "core_hchacha20.h" +#include "crypto_core_hchacha20.h" + +static const unsigned char sigma[16] = { + 'e', 'x', 'p', 'a', 'n', 'd', ' ', '3', '2', '-', 'b', 'y', 't', 'e', ' ', 'k' +}; + +int +crypto_core_hchacha20(unsigned char *out, const unsigned char *in, + const unsigned char *k, const unsigned char *c) +{ + int i; + uint32_t x0, x1, x2, x3, x4, x5, x6, x7; + uint32_t x8, x9, x10, x11, x12, x13, x14, x15; + + if (c == NULL) { + c = sigma; + } + x0 = U8TO32_LITTLE(c + 0); + x1 = U8TO32_LITTLE(c + 4); + x2 = U8TO32_LITTLE(c + 8); + x3 = U8TO32_LITTLE(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); + + for (i = 0; i < 10; i++) { + QUARTERROUND(x0, x4, x8, x12); + QUARTERROUND(x1, x5, x9, x13); + QUARTERROUND(x2, x6, x10, x14); + QUARTERROUND(x3, x7, x11, x15); + QUARTERROUND(x0, x5, x10, x15); + QUARTERROUND(x1, x6, x11, x12); + QUARTERROUND(x2, x7, x8, x13); + 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); + + return 0; +} + +size_t +crypto_core_hchacha20_outputbytes(void) +{ + return crypto_core_hchacha20_OUTPUTBYTES; +} + +size_t +crypto_core_hchacha20_inputbytes(void) +{ + return crypto_core_hchacha20_INPUTBYTES; +} + +size_t +crypto_core_hchacha20_keybytes(void) +{ + return crypto_core_hchacha20_KEYBYTES; +} + +size_t +crypto_core_hchacha20_constbytes(void) +{ + return crypto_core_hchacha20_CONSTBYTES; +} diff --git a/src/libsodium/crypto_core/hchacha20/core_hchacha20.h b/src/libsodium/crypto_core/hchacha20/core_hchacha20.h new file mode 100644 index 00000000..12aac7df --- /dev/null +++ b/src/libsodium/crypto_core/hchacha20/core_hchacha20.h @@ -0,0 +1,38 @@ +#ifndef core_hchacha20_H +#define core_hchacha20_H + +#define U8C(v) (v##U) +#define U32C(v) (v##U) + +#define U8V(v) ((uint8_t)(v) & U8C(0xFF)) +#define U32V(v) ((uint32_t)(v) & U32C(0xFFFFFFFF)) + +#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))) + +#define QUARTERROUND(a, b, c, d) \ + do { \ + a = PLUS(a, b); d = ROTATE(XOR(d, a), 16); \ + c = PLUS(c, d); b = ROTATE(XOR(b, c), 12); \ + a = PLUS(a, b); d = ROTATE(XOR(d, a), 8); \ + c = PLUS(c, d); b = ROTATE(XOR(b, c), 7); \ + } while(0) + +#endif diff --git a/src/libsodium/include/Makefile.am b/src/libsodium/include/Makefile.am index bbaa9601..05b8ae8f 100644 --- a/src/libsodium/include/Makefile.am +++ b/src/libsodium/include/Makefile.am @@ -10,6 +10,7 @@ SODIUM_EXPORT = \ sodium/crypto_auth_hmacsha512256.h \ sodium/crypto_box.h \ sodium/crypto_box_curve25519xsalsa20poly1305.h \ + sodium/crypto_core_hchacha20.h \ sodium/crypto_core_hsalsa20.h \ sodium/crypto_core_salsa20.h \ sodium/crypto_core_salsa2012.h \ diff --git a/src/libsodium/include/sodium.h b/src/libsodium/include/sodium.h index b944861d..ea0c247c 100644 --- a/src/libsodium/include/sodium.h +++ b/src/libsodium/include/sodium.h @@ -12,6 +12,7 @@ #include "sodium/crypto_box.h" #include "sodium/crypto_box_curve25519xsalsa20poly1305.h" #include "sodium/crypto_core_hsalsa20.h" +#include "sodium/crypto_core_hchacha20.h" #include "sodium/crypto_core_salsa20.h" #include "sodium/crypto_core_salsa2012.h" #include "sodium/crypto_core_salsa208.h" diff --git a/src/libsodium/include/sodium/crypto_core_hchacha20.h b/src/libsodium/include/sodium/crypto_core_hchacha20.h new file mode 100644 index 00000000..05e5670c --- /dev/null +++ b/src/libsodium/include/sodium/crypto_core_hchacha20.h @@ -0,0 +1,35 @@ +#ifndef crypto_core_hchacha20_H +#define crypto_core_hchacha20_H + +#include +#include "export.h" + +#ifdef __cplusplus +extern "C" { +#endif + +#define crypto_core_hchacha20_OUTPUTBYTES 32U +SODIUM_EXPORT +size_t crypto_core_hchacha20_outputbytes(void); + +#define crypto_core_hchacha20_INPUTBYTES 16U +SODIUM_EXPORT +size_t crypto_core_hchacha20_inputbytes(void); + +#define crypto_core_hchacha20_KEYBYTES 32U +SODIUM_EXPORT +size_t crypto_core_hchacha20_keybytes(void); + +#define crypto_core_hchacha20_CONSTBYTES 16U +SODIUM_EXPORT +size_t crypto_core_hchacha20_constbytes(void); + +SODIUM_EXPORT +int crypto_core_hchacha20(unsigned char *out, const unsigned char *in, + const unsigned char *k, const unsigned char *c); + +#ifdef __cplusplus +} +#endif + +#endif