LCOV - code coverage report
Current view: top level - basic - siphash24.c (source / functions) Hit Total Coverage
Test: main_coverage.info Lines: 96 96 100.0 %
Date: 2019-08-22 15:41:25 Functions: 7 7 100.0 %

          Line data    Source code
       1             : /*
       2             :    SipHash reference C implementation
       3             : 
       4             :    Written in 2012 by
       5             :    Jean-Philippe Aumasson <jeanphilippe.aumasson@gmail.com>
       6             :    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 with
      13             :    this software. If not, see <http://creativecommons.org/publicdomain/zero/1.0/>.
      14             : 
      15             :    (Minimal changes made by Lennart Poettering, to make clean for inclusion in systemd)
      16             :    (Refactored by Tom Gundersen to split up in several functions and follow systemd
      17             :     coding style)
      18             : */
      19             : 
      20             : #include <stdio.h>
      21             : 
      22             : #include "macro.h"
      23             : #include "siphash24.h"
      24             : #include "unaligned.h"
      25             : 
      26    34282572 : static uint64_t rotate_left(uint64_t x, uint8_t b) {
      27    34282572 :         assert(b < 64);
      28             : 
      29    34282572 :         return (x << b) | (x >> (64 - b));
      30             : }
      31             : 
      32     5713762 : static void sipround(struct siphash *state) {
      33     5713762 :         assert(state);
      34             : 
      35     5713762 :         state->v0 += state->v1;
      36     5713762 :         state->v1 = rotate_left(state->v1, 13);
      37     5713762 :         state->v1 ^= state->v0;
      38     5713762 :         state->v0 = rotate_left(state->v0, 32);
      39     5713762 :         state->v2 += state->v3;
      40     5713762 :         state->v3 = rotate_left(state->v3, 16);
      41     5713762 :         state->v3 ^= state->v2;
      42     5713762 :         state->v0 += state->v3;
      43     5713762 :         state->v3 = rotate_left(state->v3, 21);
      44     5713762 :         state->v3 ^= state->v0;
      45     5713762 :         state->v2 += state->v1;
      46     5713762 :         state->v1 = rotate_left(state->v1, 17);
      47     5713762 :         state->v1 ^= state->v2;
      48     5713762 :         state->v2 = rotate_left(state->v2, 32);
      49     5713762 : }
      50             : 
      51      490111 : void siphash24_init(struct siphash *state, const uint8_t k[static 16]) {
      52             :         uint64_t k0, k1;
      53             : 
      54      490111 :         assert(state);
      55      490111 :         assert(k);
      56             : 
      57      490111 :         k0 = unaligned_read_le64(k);
      58      490111 :         k1 = unaligned_read_le64(k + 8);
      59             : 
      60      490111 :         *state = (struct siphash) {
      61             :                 /* "somepseudorandomlygeneratedbytes" */
      62      490111 :                 .v0 = 0x736f6d6570736575ULL ^ k0,
      63      490111 :                 .v1 = 0x646f72616e646f6dULL ^ k1,
      64      490111 :                 .v2 = 0x6c7967656e657261ULL ^ k0,
      65      490111 :                 .v3 = 0x7465646279746573ULL ^ k1,
      66             :                 .padding = 0,
      67             :                 .inlen = 0,
      68             :         };
      69      490111 : }
      70             : 
      71     1230467 : void siphash24_compress(const void *_in, size_t inlen, struct siphash *state) {
      72             : 
      73     1230467 :         const uint8_t *in = _in;
      74     1230467 :         const uint8_t *end = in + inlen;
      75     1230467 :         size_t left = state->inlen & 7;
      76             :         uint64_t m;
      77             : 
      78     1230467 :         assert(in);
      79     1230467 :         assert(state);
      80             : 
      81             :         /* Update total length */
      82     1230467 :         state->inlen += inlen;
      83             : 
      84             :         /* If padding exists, fill it out */
      85     1230467 :         if (left > 0) {
      86     2613545 :                 for ( ; in < end && left < 8; in ++, left ++)
      87     1977519 :                         state->padding |= ((uint64_t) *in) << (left * 8);
      88             : 
      89      636026 :                 if (in == end && left < 8)
      90             :                         /* We did not have enough input to fill out the padding completely */
      91      312627 :                         return;
      92             : 
      93             : #if ENABLE_DEBUG_SIPHASH
      94             :                 printf("(%3zu) v0 %08x %08x\n", state->inlen, (uint32_t) (state->v0 >> 32), (uint32_t) state->v0);
      95             :                 printf("(%3zu) v1 %08x %08x\n", state->inlen, (uint32_t) (state->v1 >> 32), (uint32_t) state->v1);
      96             :                 printf("(%3zu) v2 %08x %08x\n", state->inlen, (uint32_t) (state->v2 >> 32), (uint32_t) state->v2);
      97             :                 printf("(%3zu) v3 %08x %08x\n", state->inlen, (uint32_t) (state->v3 >> 32), (uint32_t) state->v3);
      98             :                 printf("(%3zu) compress padding %08x %08x\n", state->inlen, (uint32_t) (state->padding >> 32), (uint32_t)state->padding);
      99             : #endif
     100             : 
     101      323399 :                 state->v3 ^= state->padding;
     102      323399 :                 sipround(state);
     103      323399 :                 sipround(state);
     104      323399 :                 state->v0 ^= state->padding;
     105             : 
     106      323399 :                 state->padding = 0;
     107             :         }
     108             : 
     109      917840 :         end -= (state->inlen % sizeof(uint64_t));
     110             : 
     111     1980995 :         for ( ; in < end; in += 8) {
     112     1063155 :                 m = unaligned_read_le64(in);
     113             : #if ENABLE_DEBUG_SIPHASH
     114             :                 printf("(%3zu) v0 %08x %08x\n", state->inlen, (uint32_t) (state->v0 >> 32), (uint32_t) state->v0);
     115             :                 printf("(%3zu) v1 %08x %08x\n", state->inlen, (uint32_t) (state->v1 >> 32), (uint32_t) state->v1);
     116             :                 printf("(%3zu) v2 %08x %08x\n", state->inlen, (uint32_t) (state->v2 >> 32), (uint32_t) state->v2);
     117             :                 printf("(%3zu) v3 %08x %08x\n", state->inlen, (uint32_t) (state->v3 >> 32), (uint32_t) state->v3);
     118             :                 printf("(%3zu) compress %08x %08x\n", state->inlen, (uint32_t) (m >> 32), (uint32_t) m);
     119             : #endif
     120     1063155 :                 state->v3 ^= m;
     121     1063155 :                 sipround(state);
     122     1063155 :                 sipround(state);
     123     1063155 :                 state->v0 ^= m;
     124             :         }
     125             : 
     126      917840 :         left = state->inlen & 7;
     127      917840 :         switch (left) {
     128       26595 :                 case 7:
     129       26595 :                         state->padding |= ((uint64_t) in[6]) << 48;
     130             :                         _fallthrough_;
     131       80022 :                 case 6:
     132       80022 :                         state->padding |= ((uint64_t) in[5]) << 40;
     133             :                         _fallthrough_;
     134      132330 :                 case 5:
     135      132330 :                         state->padding |= ((uint64_t) in[4]) << 32;
     136             :                         _fallthrough_;
     137      173049 :                 case 4:
     138      173049 :                         state->padding |= ((uint64_t) in[3]) << 24;
     139             :                         _fallthrough_;
     140      268702 :                 case 3:
     141      268702 :                         state->padding |= ((uint64_t) in[2]) << 16;
     142             :                         _fallthrough_;
     143      338521 :                 case 2:
     144      338521 :                         state->padding |= ((uint64_t) in[1]) <<  8;
     145             :                         _fallthrough_;
     146      579191 :                 case 1:
     147      579191 :                         state->padding |= ((uint64_t) in[0]);
     148             :                         _fallthrough_;
     149      917840 :                 case 0:
     150      917840 :                         break;
     151             :         }
     152             : }
     153             : 
     154           7 : void siphash24_compress_boolean(bool in, struct siphash *state) {
     155           7 :         int i = in;
     156             : 
     157           7 :         siphash24_compress(&i, sizeof i, state);
     158           7 : }
     159             : 
     160      490109 : uint64_t siphash24_finalize(struct siphash *state) {
     161             :         uint64_t b;
     162             : 
     163      490109 :         assert(state);
     164             : 
     165      490109 :         b = state->padding | (((uint64_t) state->inlen) << 56);
     166             : 
     167             : #if ENABLE_DEBUG_SIPHASH
     168             :         printf("(%3zu) v0 %08x %08x\n", state->inlen, (uint32_t) (state->v0 >> 32), (uint32_t) state->v0);
     169             :         printf("(%3zu) v1 %08x %08x\n", state->inlen, (uint32_t) (state->v1 >> 32), (uint32_t) state->v1);
     170             :         printf("(%3zu) v2 %08x %08x\n", state->inlen, (uint32_t) (state->v2 >> 32), (uint32_t) state->v2);
     171             :         printf("(%3zu) v3 %08x %08x\n", state->inlen, (uint32_t) (state->v3 >> 32), (uint32_t) state->v3);
     172             :         printf("(%3zu) padding   %08x %08x\n", state->inlen, (uint32_t) (state->padding >> 32), (uint32_t) state->padding);
     173             : #endif
     174             : 
     175      490109 :         state->v3 ^= b;
     176      490109 :         sipround(state);
     177      490109 :         sipround(state);
     178      490109 :         state->v0 ^= b;
     179             : 
     180             : #if ENABLE_DEBUG_SIPHASH
     181             :         printf("(%3zu) v0 %08x %08x\n", state->inlen, (uint32_t) (state->v0 >> 32), (uint32_t) state->v0);
     182             :         printf("(%3zu) v1 %08x %08x\n", state->inlen, (uint32_t) (state->v1 >> 32), (uint32_t) state->v1);
     183             :         printf("(%3zu) v2 %08x %08x\n", state->inlen, (uint32_t) (state->v2 >> 32), (uint32_t) state->v2);
     184             :         printf("(%3zu) v3 %08x %08x\n", state->inlen, (uint32_t) (state->v3 >> 32), (uint32_t) state->v3);
     185             : #endif
     186      490109 :         state->v2 ^= 0xff;
     187             : 
     188      490109 :         sipround(state);
     189      490109 :         sipround(state);
     190      490109 :         sipround(state);
     191      490109 :         sipround(state);
     192             : 
     193      490109 :         return state->v0 ^ state->v1 ^ state->v2  ^ state->v3;
     194             : }
     195             : 
     196          24 : uint64_t siphash24(const void *in, size_t inlen, const uint8_t k[static 16]) {
     197             :         struct siphash state;
     198             : 
     199          24 :         assert(in);
     200          24 :         assert(k);
     201             : 
     202          24 :         siphash24_init(&state, k);
     203          24 :         siphash24_compress(in, inlen, &state);
     204             : 
     205          24 :         return siphash24_finalize(&state);
     206             : }

Generated by: LCOV version 1.14