LCOV - code coverage report
Current view: top level - src/util - siphash.c (source / functions) Hit Total Coverage
Test: passgen-test.info Lines: 56 56 100.0 %
Date: 2024-05-03 06:05:14 Functions: 1 1 100.0 %

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

Generated by: LCOV version 1.14