diff --git a/src/libsodium/Makefile.am b/src/libsodium/Makefile.am index ec22345a..83c53e83 100644 --- a/src/libsodium/Makefile.am +++ b/src/libsodium/Makefile.am @@ -69,6 +69,7 @@ libsodium_la_SOURCES = \ crypto_shorthash/crypto_shorthash.c \ crypto_shorthash/siphash24/shorthash_siphash24.c \ crypto_shorthash/siphash24/ref/shorthash_siphash24_ref.c \ + crypto_shorthash/siphash24/ref/shorthash_siphash_ref.h \ crypto_sign/crypto_sign.c \ crypto_sign/ed25519/sign_ed25519.c \ crypto_sign/ed25519/ref10/keypair.c \ @@ -159,6 +160,8 @@ libsodium_la_SOURCES += \ crypto_core/salsa208/core_salsa208.c \ crypto_core/salsa208/ref/core_salsa208_ref.c \ crypto_secretbox/xchacha20poly1305/secretbox_xchacha20poly1305.c \ + crypto_shorthash/siphash24/shorthash_siphashx24.c \ + crypto_shorthash/siphash24/ref/shorthash_siphashx24_ref.c \ crypto_sign/ed25519/ref10/obsolete.c \ crypto_stream/aes128ctr/nacl/afternm_aes128ctr.c \ crypto_stream/aes128ctr/nacl/beforenm_aes128ctr.c \ diff --git a/src/libsodium/crypto_shorthash/siphash24/ref/shorthash_siphash24_ref.c b/src/libsodium/crypto_shorthash/siphash24/ref/shorthash_siphash24_ref.c index b84e6219..0c173d4c 100644 --- a/src/libsodium/crypto_shorthash/siphash24/ref/shorthash_siphash24_ref.c +++ b/src/libsodium/crypto_shorthash/siphash24/ref/shorthash_siphash24_ref.c @@ -1,23 +1,6 @@ #include "crypto_shorthash_siphash24.h" #include "private/common.h" - -#define SIPROUND \ - do { \ - v0 += v1; \ - v1 = ROTL64(v1, 13); \ - v1 ^= v0; \ - v0 = ROTL64(v0, 32); \ - v2 += v3; \ - v3 = ROTL64(v3, 16); \ - v3 ^= v2; \ - v0 += v3; \ - v3 = ROTL64(v3, 21); \ - v3 ^= v0; \ - v2 += v1; \ - v1 = ROTL64(v1, 17); \ - v1 ^= v2; \ - v2 = ROTL64(v2, 32); \ - } while (0) +#include "shorthash_siphash_ref.h" int crypto_shorthash_siphash24(unsigned char *out, const unsigned char *in, @@ -34,12 +17,12 @@ crypto_shorthash_siphash24(unsigned char *out, const unsigned char *in, uint64_t m; const uint8_t *end = in + inlen - (inlen % sizeof(uint64_t)); const int left = inlen & 7; - b = ((uint64_t) inlen) << 56; + + b = ((uint64_t) inlen) << 56; v3 ^= k1; v2 ^= k0; v1 ^= k1; v0 ^= k0; - for (; in != end; in += 8) { m = LOAD64_LE(in); v3 ^= m; diff --git a/src/libsodium/crypto_shorthash/siphash24/ref/shorthash_siphash_ref.h b/src/libsodium/crypto_shorthash/siphash24/ref/shorthash_siphash_ref.h new file mode 100644 index 00000000..3f9a38b5 --- /dev/null +++ b/src/libsodium/crypto_shorthash/siphash24/ref/shorthash_siphash_ref.h @@ -0,0 +1,24 @@ +#ifndef shorthash_siphash_H +#define shorthash_siphash_H + +#include "private/common.h" + +#define SIPROUND \ + do { \ + v0 += v1; \ + v1 = ROTL64(v1, 13); \ + v1 ^= v0; \ + v0 = ROTL64(v0, 32); \ + v2 += v3; \ + v3 = ROTL64(v3, 16); \ + v3 ^= v2; \ + v0 += v3; \ + v3 = ROTL64(v3, 21); \ + v3 ^= v0; \ + v2 += v1; \ + v1 = ROTL64(v1, 17); \ + v1 ^= v2; \ + v2 = ROTL64(v2, 32); \ + } while (0) + +#endif diff --git a/src/libsodium/crypto_shorthash/siphash24/ref/shorthash_siphashx24_ref.c b/src/libsodium/crypto_shorthash/siphash24/ref/shorthash_siphashx24_ref.c new file mode 100644 index 00000000..20480d0d --- /dev/null +++ b/src/libsodium/crypto_shorthash/siphash24/ref/shorthash_siphashx24_ref.c @@ -0,0 +1,71 @@ +#include "crypto_shorthash_siphash24.h" +#include "private/common.h" +#include "shorthash_siphash_ref.h" + +int +crypto_shorthash_siphashx24(unsigned char *out, const unsigned char *in, + unsigned long long inlen, const unsigned char *k) +{ + uint64_t v0 = 0x736f6d6570736575ULL; + uint64_t v1 = 0x646f72616e646f83ULL; + uint64_t v2 = 0x6c7967656e657261ULL; + uint64_t v3 = 0x7465646279746573ULL; + uint64_t b; + uint64_t k0 = LOAD64_LE(k); + uint64_t k1 = LOAD64_LE(k + 8); + uint64_t m; + const uint8_t *end = in + inlen - (inlen % sizeof(uint64_t)); + const int left = inlen & 7; + + b = ((uint64_t) inlen) << 56; + v3 ^= k1; + v2 ^= k0; + v1 ^= k1; + v0 ^= k0; + for (; in != end; in += 8) { + m = LOAD64_LE(in); + v3 ^= m; + SIPROUND; + SIPROUND; + v0 ^= m; + } + switch (left) { + case 7: + b |= ((uint64_t) in[6]) << 48; + case 6: + b |= ((uint64_t) in[5]) << 40; + case 5: + b |= ((uint64_t) in[4]) << 32; + case 4: + b |= ((uint64_t) in[3]) << 24; + case 3: + b |= ((uint64_t) in[2]) << 16; + case 2: + b |= ((uint64_t) in[1]) << 8; + case 1: + b |= ((uint64_t) in[0]); + break; + case 0: + break; + } + v3 ^= b; + SIPROUND; + SIPROUND; + v0 ^= b; + v2 ^= 0xee; + SIPROUND; + SIPROUND; + SIPROUND; + SIPROUND; + b = v0 ^ v1 ^ v2 ^ v3; + STORE64_LE(out, b); + v1 ^= 0xdd; + SIPROUND; + SIPROUND; + SIPROUND; + SIPROUND; + b = v0 ^ v1 ^ v2 ^ v3; + STORE64_LE(out + 8, b); + + return 0; +} diff --git a/src/libsodium/crypto_shorthash/siphash24/shorthash_siphashx24.c b/src/libsodium/crypto_shorthash/siphash24/shorthash_siphashx24.c new file mode 100644 index 00000000..2d487dbb --- /dev/null +++ b/src/libsodium/crypto_shorthash/siphash24/shorthash_siphashx24.c @@ -0,0 +1,11 @@ +#include "crypto_shorthash_siphash24.h" + +size_t +crypto_shorthash_siphashx24_bytes(void) { + return crypto_shorthash_siphashx24_BYTES; +} + +size_t +crypto_shorthash_siphashx24_keybytes(void) { + return crypto_shorthash_siphashx24_KEYBYTES; +} diff --git a/src/libsodium/include/sodium/crypto_shorthash_siphash24.h b/src/libsodium/include/sodium/crypto_shorthash_siphash24.h index 181b5ee7..c2d469ec 100644 --- a/src/libsodium/include/sodium/crypto_shorthash_siphash24.h +++ b/src/libsodium/include/sodium/crypto_shorthash_siphash24.h @@ -11,6 +11,8 @@ extern "C" { #endif +/* -- 64-bit output -- */ + #define crypto_shorthash_siphash24_BYTES 8U SODIUM_EXPORT size_t crypto_shorthash_siphash24_bytes(void); @@ -23,6 +25,20 @@ SODIUM_EXPORT int crypto_shorthash_siphash24(unsigned char *out, const unsigned char *in, unsigned long long inlen, const unsigned char *k); +/* -- 128-bit output -- */ + +#define crypto_shorthash_siphashx24_BYTES 16U +SODIUM_EXPORT +size_t crypto_shorthash_siphashx24_bytes(void); + +#define crypto_shorthash_siphashx24_KEYBYTES 16U +SODIUM_EXPORT +size_t crypto_shorthash_siphashx24_keybytes(void); + +SODIUM_EXPORT +int crypto_shorthash_siphashx24(unsigned char *out, const unsigned char *in, + unsigned long long inlen, const unsigned char *k); + #ifdef __cplusplus } #endif