src/core/ngx_siphash.c - nginx-1.31.3 nginx/ @ 42f8df65b

Functions defined

Macros defined

Source code


  1. /*
  2. * Copyright (C) Nginx, Inc.
  3. */


  4. #include <ngx_config.h>
  5. #include <ngx_core.h>


  6. /*
  7. * SipHash-2-4 implementation based on the SipHash specification by
  8. * Jean-Philippe Aumasson and Daniel J. Bernstein.
  9. * https://eprint.iacr.org/2012/351.pdf
  10. */


  11. #define ngx_siphash_rotl(x, b)                                                \
  12.     (uint64_t) (((x) << (b)) | ((x) >> (64 - (b))))

  13. #define ngx_sipround                                                          \
  14.     do {                                                                      \
  15.         v0 += v1; v1 = ngx_siphash_rotl(v1, 13); v1 ^= v0;                    \
  16.         v0 = ngx_siphash_rotl(v0, 32);                                        \
  17.         v2 += v3; v3 = ngx_siphash_rotl(v3, 16); v3 ^= v2;                    \
  18.         v0 += v3; v3 = ngx_siphash_rotl(v3, 21); v3 ^= v0;                    \
  19.         v2 += v1; v1 = ngx_siphash_rotl(v1, 17); v1 ^= v2;                    \
  20.         v2 = ngx_siphash_rotl(v2, 32);                                        \
  21.     } while (0)


  22. uint64_t
  23. ngx_siphash(uint64_t k0, uint64_t k1, u_char *data, size_t len)
  24. {
  25.     u_char    *end;
  26.     size_t     remainder;
  27.     uint64_t   v0, v1, v2, v3, m;

  28.     v0 = k0 ^ 0x736f6d6570736575ULL;
  29.     v1 = k1 ^ 0x646f72616e646f6dULL;
  30.     v2 = k0 ^ 0x6c7967656e657261ULL;
  31.     v3 = k1 ^ 0x7465646279746573ULL;

  32.     remainder = len & 7;
  33.     end = data + len - remainder;

  34.     for ( /* void */ ; data != end; data += 8) {
  35.         ngx_memcpy(&m, data, 8);
  36.         v3 ^= m;
  37.         ngx_sipround;
  38.         ngx_sipround;
  39.         v0 ^= m;
  40.     }

  41.     m = (uint64_t) len << 56;

  42.     switch (remainder) {
  43.     case 7:
  44.         m |= (uint64_t) data[6] << 48;
  45.         /* fall through */
  46.     case 6:
  47.         m |= (uint64_t) data[5] << 40;
  48.         /* fall through */
  49.     case 5:
  50.         m |= (uint64_t) data[4] << 32;
  51.         /* fall through */
  52.     case 4:
  53.         m |= (uint64_t) data[3] << 24;
  54.         /* fall through */
  55.     case 3:
  56.         m |= (uint64_t) data[2] << 16;
  57.         /* fall through */
  58.     case 2:
  59.         m |= (uint64_t) data[1] << 8;
  60.         /* fall through */
  61.     case 1:
  62.         m |= (uint64_t) data[0];
  63.         break;
  64.     case 0:
  65.         break;
  66.     }

  67.     v3 ^= m;
  68.     ngx_sipround;
  69.     ngx_sipround;
  70.     v0 ^= m;

  71.     v2 ^= 0xff;
  72.     ngx_sipround;
  73.     ngx_sipround;
  74.     ngx_sipround;
  75.     ngx_sipround;

  76.     return v0 ^ v1 ^ v2 ^ v3;
  77. }