| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132 |
- /*
- SipHash reference C implementation
- Copyright (c) 2012-2016 Jean-Philippe Aumasson
- <jeanphilippe.aumasson@gmail.com>
- Copyright (c) 2012-2014 Daniel J. Bernstein <djb@cr.yp.to>
- To the extent possible under law, the author(s) have dedicated all copyright
- and related and neighboring rights to this software to the public domain
- worldwide. This software is distributed without any warranty.
- You should have received a copy of the CC0 Public Domain Dedication along
- with
- this software. If not, see
- <http://creativecommons.org/publicdomain/zero/1.0/>.
- */
- #include <assert.h>
- #include <stdio.h>
- #include <string.h>
- #include "common.h"
- #include "endianess.h"
- #include "siphash.h"
- /* default: SipHash-2-4 */
- #define cROUNDS 2
- #define dROUNDS 4
- #define ROTL(x, b) (uint64_t)(((x) << (b)) | ((x) >> (64 - (b))))
- #define SIPROUND \
- do { \
- v0 += v1; \
- v1 = ROTL(v1, 13); \
- v1 ^= v0; \
- v0 = ROTL(v0, 32); \
- v2 += v3; \
- v3 = ROTL(v3, 16); \
- v3 ^= v2; \
- v0 += v3; \
- v3 = ROTL(v3, 21); \
- v3 ^= v0; \
- v2 += v1; \
- v1 = ROTL(v1, 17); \
- v1 ^= v2; \
- v2 = ROTL(v2, 32); \
- } while (0)
- int siphash(const uint8_t *in, const size_t inlen, const uint8_t *k,
- uint8_t *out, const size_t outlen) {
- uint64_t v0 = 0x736f6d6570736575ULL;
- uint64_t v1 = 0x646f72616e646f6dULL;
- uint64_t v2 = 0x6c7967656e657261ULL;
- uint64_t v3 = 0x7465646279746573ULL;
- uint64_t k0 = LOAD_U64_LITTLE(k);
- uint64_t k1 = LOAD_U64_LITTLE(k + 8);
- uint64_t m;
- const uint8_t *end = in + inlen - (inlen % sizeof(uint64_t));
- const int left = inlen & 7;
- uint64_t b = ((uint64_t)inlen) << 56;
-
- assert((outlen == 8) || (outlen == 16));
-
- v3 ^= k1;
- v2 ^= k0;
- v1 ^= k1;
- v0 ^= k0;
- if (outlen == 16)
- v1 ^= 0xee;
- for (; in != end; in += 8) {
- m = LOAD_U64_LITTLE(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 ^= outlen == 16 ? 0xEE : 0xFF;
- SIPROUND;
- SIPROUND;
- SIPROUND;
- SIPROUND;
- b = v0 ^ v1 ^ v2 ^ v3;
- STORE_U64_LITTLE(out, b);
- if (outlen == 16) {
- v1 ^= 0xdd;
- SIPROUND;
- SIPROUND;
- SIPROUND;
- SIPROUND;
- b = v0 ^ v1 ^ v2 ^ v3;
- STORE_U64_LITTLE(out + 8, b);
- }
- return 0;
- }
|