Coverage Report

Created: 2026-08-25 06:40

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