Coverage Report

Created: 2026-10-17 07:04

next uncovered line (L), next uncovered region (R), next uncovered branch (B)
/src/libzip/lib/siphash.c
Line
Count
Source
1
/*
2
   SipHash reference C implementation
3
4
   Copyright (c) 2012-2022 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
18
#include "siphash.h"
19
20
#include <string.h>
21
22
/* default: SipHash-2-4 */
23
#ifndef cROUNDS
24
233k
#define cROUNDS 2
25
#endif
26
#ifndef dROUNDS
27
177k
#define dROUNDS 4
28
#endif
29
30
1.78M
#define ROTL(x, b) (zip_uint64_t)(((x) << (b)) | ((x) >> (64 - (b))))
31
32
#define U32TO8_LE(p, v)                \
33
71.0k
    (p)[0] = (zip_uint8_t)((v));       \
34
71.0k
    (p)[1] = (zip_uint8_t)((v) >> 8);  \
35
71.0k
    (p)[2] = (zip_uint8_t)((v) >> 16); \
36
71.0k
    (p)[3] = (zip_uint8_t)((v) >> 24);
37
38
#define U64TO8_LE(p, v)                  \
39
35.5k
    U32TO8_LE((p), (zip_uint32_t)((v))); \
40
35.5k
    U32TO8_LE((p) + 4, (zip_uint32_t)((v) >> 32));
41
42
113k
#define U8TO64_LE(p) (((zip_uint64_t)((p)[0])) | ((zip_uint64_t)((p)[1]) << 8) | ((zip_uint64_t)((p)[2]) << 16) | ((zip_uint64_t)((p)[3]) << 24) | ((zip_uint64_t)((p)[4]) << 32) | ((zip_uint64_t)((p)[5]) << 40) | ((zip_uint64_t)((p)[6]) << 48) | ((zip_uint64_t)((p)[7]) << 56))
43
44
#define SIPROUND           \
45
297k
    do {                   \
46
297k
        v0 += v1;          \
47
297k
        v1 = ROTL(v1, 13); \
48
297k
        v1 ^= v0;          \
49
297k
        v0 = ROTL(v0, 32); \
50
297k
        v2 += v3;          \
51
297k
        v3 = ROTL(v3, 16); \
52
297k
        v3 ^= v2;          \
53
297k
        v0 += v3;          \
54
297k
        v3 = ROTL(v3, 21); \
55
297k
        v3 ^= v0;          \
56
297k
        v2 += v1;          \
57
297k
        v1 = ROTL(v1, 17); \
58
297k
        v1 ^= v2;          \
59
297k
        v2 = ROTL(v2, 32); \
60
297k
    } while (0)
61
62
/*
63
    Computes a SipHash value
64
*/
65
35.5k
zip_uint64_t siphash(const zip_uint8_t *data, const zip_uint8_t *key) {
66
35.5k
    const zip_uint8_t *ni = data;
67
35.5k
    const zip_uint8_t *kk = key;
68
35.5k
    size_t inlen = strlen((const char *)data);
69
35.5k
    zip_uint64_t out;
70
71
35.5k
    zip_uint64_t v0 = UINT64_C(0x736f6d6570736575);
72
35.5k
    zip_uint64_t v1 = UINT64_C(0x646f72616e646f6d);
73
35.5k
    zip_uint64_t v2 = UINT64_C(0x6c7967656e657261);
74
35.5k
    zip_uint64_t v3 = UINT64_C(0x7465646279746573);
75
35.5k
    zip_uint64_t k0 = U8TO64_LE(kk);
76
35.5k
    zip_uint64_t k1 = U8TO64_LE(kk + 8);
77
35.5k
    zip_uint64_t m;
78
35.5k
    int i;
79
35.5k
    const unsigned char *end = ni + inlen - (inlen % sizeof(zip_uint64_t));
80
35.5k
    const int left = inlen & 7;
81
35.5k
    zip_uint64_t b = ((zip_uint64_t)inlen) << 56;
82
35.5k
    v3 ^= k1;
83
35.5k
    v2 ^= k0;
84
35.5k
    v1 ^= k1;
85
35.5k
    v0 ^= k0;
86
87
77.9k
    for (; ni != end; ni += 8) {
88
42.4k
        m = U8TO64_LE(ni);
89
42.4k
        v3 ^= m;
90
91
127k
        for (i = 0; i < cROUNDS; ++i) {
92
84.8k
            SIPROUND;
93
84.8k
        }
94
95
42.4k
        v0 ^= m;
96
42.4k
    }
97
98
35.5k
    switch (left) {
99
1.67k
    case 7:
100
1.67k
        b |= ((zip_uint64_t)ni[6]) << 48;
101
        /* FALLTHRU */
102
2.45k
    case 6:
103
2.45k
        b |= ((zip_uint64_t)ni[5]) << 40;
104
        /* FALLTHRU */
105
5.76k
    case 5:
106
5.76k
        b |= ((zip_uint64_t)ni[4]) << 32;
107
        /* FALLTHRU */
108
6.31k
    case 4:
109
6.31k
        b |= ((zip_uint64_t)ni[3]) << 24;
110
        /* FALLTHRU */
111
6.92k
    case 3:
112
6.92k
        b |= ((zip_uint64_t)ni[2]) << 16;
113
        /* FALLTHRU */
114
7.85k
    case 2:
115
7.85k
        b |= ((zip_uint64_t)ni[1]) << 8;
116
        /* FALLTHRU */
117
8.69k
    case 1:
118
8.69k
        b |= ((zip_uint64_t)ni[0]);
119
8.69k
        break;
120
26.8k
    case 0:
121
26.8k
        break;
122
35.5k
    }
123
124
35.5k
    v3 ^= b;
125
126
106k
    for (i = 0; i < cROUNDS; ++i) {
127
71.0k
        SIPROUND;
128
71.0k
    }
129
130
35.5k
    v0 ^= b;
131
132
35.5k
    v2 ^= 0xff;
133
134
177k
    for (i = 0; i < dROUNDS; ++i) {
135
142k
        SIPROUND;
136
142k
    }
137
138
35.5k
    b = v0 ^ v1 ^ v2 ^ v3;
139
35.5k
    U64TO8_LE((zip_uint8_t *)&out, b);
140
141
35.5k
    return out;
142
35.5k
}