Coverage Report

Created: 2026-10-08 06:28

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