"Fossies" - the Fresh Open Source Software Archive

Member "nsd-4.3.7/siphash.c" (22 Jul 2021, 5774 Bytes) of package /linux/misc/dns/nsd-4.3.7.tar.gz:


As a special service "Fossies" has tried to format the requested source page into HTML format using (guessed) C and C++ source code syntax highlighting (style: standard) with prefixed line numbers and code folding option. Alternatively you can here view or download the uninterpreted source code file. For more information about "siphash.c" see the Fossies "Dox" file reference documentation.

    1 /*
    2    SipHash reference C implementation
    3 
    4    Copyright (c) 2012-2016 Jean-Philippe Aumasson
    5    <jeanphilippe.aumasson@gmail.com>
    6    Copyright (c) 2012-2014 Daniel J. Bernstein <djb@cr.yp.to>
    7 
    8    To the extent possible under law, the author(s) have dedicated all copyright
    9    and related and neighboring rights to this software to the public domain
   10    worldwide. This software is distributed without any warranty.
   11 
   12    You should have received a copy of the CC0 Public Domain Dedication along
   13    with
   14    this software. If not, see
   15    <http://creativecommons.org/publicdomain/zero/1.0/>.
   16  */
   17 #include <assert.h>
   18 #include <stdint.h>
   19 #include <stdio.h>
   20 #include <string.h>
   21 
   22 /* default: SipHash-2-4 */
   23 #define cROUNDS 2
   24 #define dROUNDS 4
   25 
   26 #define ROTL(x, b) (uint64_t)(((x) << (b)) | ((x) >> (64 - (b))))
   27 
   28 #define U32TO8_LE(p, v)                                                        \
   29     (p)[0] = (uint8_t)((v));                                                   \
   30     (p)[1] = (uint8_t)((v) >> 8);                                              \
   31     (p)[2] = (uint8_t)((v) >> 16);                                             \
   32     (p)[3] = (uint8_t)((v) >> 24);
   33 
   34 #define U64TO8_LE(p, v)                                                        \
   35     U32TO8_LE((p), (uint32_t)((v)));                                           \
   36     U32TO8_LE((p) + 4, (uint32_t)((v) >> 32));
   37 
   38 #define U8TO64_LE(p)                                                           \
   39     (((uint64_t)((p)[0])) | ((uint64_t)((p)[1]) << 8) |                        \
   40      ((uint64_t)((p)[2]) << 16) | ((uint64_t)((p)[3]) << 24) |                 \
   41      ((uint64_t)((p)[4]) << 32) | ((uint64_t)((p)[5]) << 40) |                 \
   42      ((uint64_t)((p)[6]) << 48) | ((uint64_t)((p)[7]) << 56))
   43 
   44 #define SIPROUND                                                               \
   45     do {                                                                       \
   46         v0 += v1;                                                              \
   47         v1 = ROTL(v1, 13);                                                     \
   48         v1 ^= v0;                                                              \
   49         v0 = ROTL(v0, 32);                                                     \
   50         v2 += v3;                                                              \
   51         v3 = ROTL(v3, 16);                                                     \
   52         v3 ^= v2;                                                              \
   53         v0 += v3;                                                              \
   54         v3 = ROTL(v3, 21);                                                     \
   55         v3 ^= v0;                                                              \
   56         v2 += v1;                                                              \
   57         v1 = ROTL(v1, 17);                                                     \
   58         v1 ^= v2;                                                              \
   59         v2 = ROTL(v2, 32);                                                     \
   60     } while (0)
   61 
   62 #ifdef DEBUG
   63 #define TRACE                                                                  \
   64     do {                                                                       \
   65         printf("(%3d) v0 %08x %08x\n", (int)inlen, (uint32_t)(v0 >> 32),       \
   66                (uint32_t)v0);                                                  \
   67         printf("(%3d) v1 %08x %08x\n", (int)inlen, (uint32_t)(v1 >> 32),       \
   68                (uint32_t)v1);                                                  \
   69         printf("(%3d) v2 %08x %08x\n", (int)inlen, (uint32_t)(v2 >> 32),       \
   70                (uint32_t)v2);                                                  \
   71         printf("(%3d) v3 %08x %08x\n", (int)inlen, (uint32_t)(v3 >> 32),       \
   72                (uint32_t)v3);                                                  \
   73     } while (0)
   74 #else
   75 #define TRACE
   76 #endif
   77 
   78 int siphash(const uint8_t *in, const size_t inlen, const uint8_t *k,
   79             uint8_t *out, const size_t outlen) {
   80     uint64_t v0 = 0x736f6d6570736575ULL;
   81     uint64_t v1 = 0x646f72616e646f6dULL;
   82     uint64_t v2 = 0x6c7967656e657261ULL;
   83     uint64_t v3 = 0x7465646279746573ULL;
   84     uint64_t k0 = U8TO64_LE(k);
   85     uint64_t k1 = U8TO64_LE(k + 8);
   86     uint64_t m;
   87     int i;
   88     const uint8_t *end = in + inlen - (inlen % sizeof(uint64_t));
   89     const int left = inlen & 7;
   90     uint64_t b = ((uint64_t)inlen) << 56;
   91     v3 ^= k1;
   92     v2 ^= k0;
   93     v1 ^= k1;
   94     v0 ^= k0;
   95 
   96     assert((outlen == 8) || (outlen == 16));
   97     if (outlen == 16)
   98         v1 ^= 0xee;
   99 
  100     for (; in != end; in += 8) {
  101         m = U8TO64_LE(in);
  102         v3 ^= m;
  103 
  104         TRACE;
  105         for (i = 0; i < cROUNDS; ++i)
  106             SIPROUND;
  107 
  108         v0 ^= m;
  109     }
  110 
  111     switch (left) {
  112     case 7:
  113         b |= ((uint64_t)in[6]) << 48;
  114     /* fallthrough */
  115     case 6:
  116         b |= ((uint64_t)in[5]) << 40;
  117     /* fallthrough */
  118     case 5:
  119         b |= ((uint64_t)in[4]) << 32;
  120     /* fallthrough */
  121     case 4:
  122         b |= ((uint64_t)in[3]) << 24;
  123     /* fallthrough */
  124     case 3:
  125         b |= ((uint64_t)in[2]) << 16;
  126     /* fallthrough */
  127     case 2:
  128         b |= ((uint64_t)in[1]) << 8;
  129     /* fallthrough */
  130     case 1:
  131         b |= ((uint64_t)in[0]);
  132         break;
  133     case 0:
  134         break;
  135     }
  136 
  137     v3 ^= b;
  138 
  139     TRACE;
  140     for (i = 0; i < cROUNDS; ++i)
  141         SIPROUND;
  142 
  143     v0 ^= b;
  144 
  145     if (outlen == 16)
  146         v2 ^= 0xee;
  147     else
  148         v2 ^= 0xff;
  149 
  150     TRACE;
  151     for (i = 0; i < dROUNDS; ++i)
  152         SIPROUND;
  153 
  154     b = v0 ^ v1 ^ v2 ^ v3;
  155     U64TO8_LE(out, b);
  156 
  157     if (outlen == 8)
  158         return 0;
  159 
  160     v1 ^= 0xdd;
  161 
  162     TRACE;
  163     for (i = 0; i < dROUNDS; ++i)
  164         SIPROUND;
  165 
  166     b = v0 ^ v1 ^ v2 ^ v3;
  167     U64TO8_LE(out + 8, b);
  168 
  169     return 0;
  170 }