Coverage Report

Created: 2026-09-01 07:16

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
/* default: SipHash-2-4 */
21
#ifndef cROUNDS
22
266k
#define cROUNDS 2
23
#endif
24
#ifndef dROUNDS
25
173k
#define dROUNDS 4
26
#endif
27
28
1.90M
#define ROTL(x, b) (zip_uint64_t)(((x) << (b)) | ((x) >> (64 - (b))))
29
30
#define U32TO8_LE(p, v)                \
31
69.5k
    (p)[0] = (zip_uint8_t)((v));       \
32
69.5k
    (p)[1] = (zip_uint8_t)((v) >> 8);  \
33
69.5k
    (p)[2] = (zip_uint8_t)((v) >> 16); \
34
69.5k
    (p)[3] = (zip_uint8_t)((v) >> 24);
35
36
#define U64TO8_LE(p, v)                  \
37
34.7k
    U32TO8_LE((p), (zip_uint32_t)((v))); \
38
34.7k
    U32TO8_LE((p) + 4, (zip_uint32_t)((v) >> 32));
39
40
123k
#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))
41
42
#define SIPROUND           \
43
317k
    do {                   \
44
317k
        v0 += v1;          \
45
317k
        v1 = ROTL(v1, 13); \
46
317k
        v1 ^= v0;          \
47
317k
        v0 = ROTL(v0, 32); \
48
317k
        v2 += v3;          \
49
317k
        v3 = ROTL(v3, 16); \
50
317k
        v3 ^= v2;          \
51
317k
        v0 += v3;          \
52
317k
        v3 = ROTL(v3, 21); \
53
317k
        v3 ^= v0;          \
54
317k
        v2 += v1;          \
55
317k
        v1 = ROTL(v1, 17); \
56
317k
        v1 ^= v2;          \
57
317k
        v2 = ROTL(v2, 32); \
58
317k
    } while (0)
59
60
/*
61
    Computes a SipHash value
62
*/
63
34.7k
zip_uint64_t siphash(const zip_uint8_t *data, const zip_uint8_t *key) {
64
34.7k
    const zip_uint8_t *ni = data;
65
34.7k
    const zip_uint8_t *kk = key;
66
34.7k
    size_t inlen = strlen((const char *)data);
67
34.7k
    zip_uint64_t out;
68
69
34.7k
    zip_uint64_t v0 = UINT64_C(0x736f6d6570736575);
70
34.7k
    zip_uint64_t v1 = UINT64_C(0x646f72616e646f6d);
71
34.7k
    zip_uint64_t v2 = UINT64_C(0x6c7967656e657261);
72
34.7k
    zip_uint64_t v3 = UINT64_C(0x7465646279746573);
73
34.7k
    zip_uint64_t k0 = U8TO64_LE(kk);
74
34.7k
    zip_uint64_t k1 = U8TO64_LE(kk + 8);
75
34.7k
    zip_uint64_t m;
76
34.7k
    int i;
77
34.7k
    const unsigned char *end = ni + inlen - (inlen % sizeof(zip_uint64_t));
78
34.7k
    const int left = inlen & 7;
79
34.7k
    zip_uint64_t b = ((zip_uint64_t)inlen) << 56;
80
34.7k
    v3 ^= k1;
81
34.7k
    v2 ^= k0;
82
34.7k
    v1 ^= k1;
83
34.7k
    v0 ^= k0;
84
85
88.9k
    for (; ni != end; ni += 8) {
86
54.2k
        m = U8TO64_LE(ni);
87
54.2k
        v3 ^= m;
88
89
162k
        for (i = 0; i < cROUNDS; ++i) {
90
108k
            SIPROUND;
91
108k
        }
92
93
54.2k
        v0 ^= m;
94
54.2k
    }
95
96
34.7k
    switch (left) {
97
2.55k
    case 7:
98
2.55k
        b |= ((zip_uint64_t)ni[6]) << 48;
99
        /* FALLTHRU */
100
3.35k
    case 6:
101
3.35k
        b |= ((zip_uint64_t)ni[5]) << 40;
102
        /* FALLTHRU */
103
8.56k
    case 5:
104
8.56k
        b |= ((zip_uint64_t)ni[4]) << 32;
105
        /* FALLTHRU */
106
9.30k
    case 4:
107
9.30k
        b |= ((zip_uint64_t)ni[3]) << 24;
108
        /* FALLTHRU */
109
10.1k
    case 3:
110
10.1k
        b |= ((zip_uint64_t)ni[2]) << 16;
111
        /* FALLTHRU */
112
11.3k
    case 2:
113
11.3k
        b |= ((zip_uint64_t)ni[1]) << 8;
114
        /* FALLTHRU */
115
12.1k
    case 1:
116
12.1k
        b |= ((zip_uint64_t)ni[0]);
117
12.1k
        break;
118
22.6k
    case 0:
119
22.6k
        break;
120
34.7k
    }
121
122
34.7k
    v3 ^= b;
123
124
104k
    for (i = 0; i < cROUNDS; ++i) {
125
69.5k
        SIPROUND;
126
69.5k
    }
127
128
34.7k
    v0 ^= b;
129
130
34.7k
    v2 ^= 0xff;
131
132
173k
    for (i = 0; i < dROUNDS; ++i) {
133
139k
        SIPROUND;
134
139k
    }
135
136
34.7k
    b = v0 ^ v1 ^ v2 ^ v3;
137
34.7k
    U64TO8_LE((zip_uint8_t *)&out, b);
138
139
34.7k
    return out;
140
34.7k
}