Coverage Report

Created: 2024-05-03 06:05

/builds/xfbs/passgen/src/util/siphash.c
Line
Count
Source (jump to first uncovered line)
1
/*
2
   SipHash reference C implementation
3
   Copyright (c) 2012-2021 Jean-Philippe Aumasson
4
   <jeanphilippe.aumasson@gmail.com>
5
   Copyright (c) 2012-2014 Daniel J. Bernstein <djb@cr.yp.to>
6
   To the extent possible under law, the author(s) have dedicated all copyright
7
   and related and neighboring rights to this software to the public domain
8
   worldwide. This software is distributed without any warranty.
9
   You should have received a copy of the CC0 Public Domain Dedication along
10
   with
11
   this software. If not, see
12
   <http://creativecommons.org/publicdomain/zero/1.0/>.
13
 */
14
15
#include "passgen/util/siphash.h"
16
#include <assert.h>
17
#include <stdint.h>
18
#include <stdio.h>
19
20
/* default: SipHash-2-4 */
21
#ifndef cROUNDS
22
116k
#define cROUNDS 2
23
#endif
24
#ifndef dROUNDS
25
193k
#define dROUNDS 4
26
#endif
27
28
1.39M
#define ROTL(x, b) (uint64_t)(((x) << (b)) | ((x) >> (64 - (b))))
29
30
#define U32TO8_LE(p, v)             \
31
77.3k
    (p)[0] = (uint8_t) ((v));       \
32
77.3k
    (p)[1] = (uint8_t) ((v) >> 8);  \
33
77.3k
    (p)[2] = (uint8_t) ((v) >> 16); \
34
77.3k
    (p)[3] = (uint8_t) ((v) >> 24);
35
36
#define U64TO8_LE(p, v)               \
37
38.6k
    U32TO8_LE((p), (uint32_t) ((v))); \
38
38.6k
    U32TO8_LE((p) + 4, (uint32_t) ((v) >> 32));
39
40
#define U8TO64_LE(p)                                             \
41
77.3k
    (((uint64_t) ((p)[0])) | ((uint64_t) ((p)[1]) << 8) |        \
42
77.3k
     ((uint64_t) ((p)[2]) << 16) | ((uint64_t) ((p)[3]) << 24) | \
43
77.3k
     ((uint64_t) ((p)[4]) << 32) | ((uint64_t) ((p)[5]) << 40) | \
44
77.3k
     ((uint64_t) ((p)[6]) << 48) | ((uint64_t) ((p)[7]) << 56))
45
46
#define SIPROUND           \
47
232k
    do {                   \
48
232k
        v0 += v1;          \
49
232k
        v1 = ROTL(v1, 13); \
50
232k
        v1 ^= v0;          \
51
232k
        v0 = ROTL(v0, 32); \
52
232k
        v2 += v3;          \
53
232k
        v3 = ROTL(v3, 16); \
54
232k
        v3 ^= v2;          \
55
232k
        v0 += v3;          \
56
232k
        v3 = ROTL(v3, 21); \
57
232k
        v3 ^= v0;          \
58
232k
        v2 += v1;          \
59
232k
        v1 = ROTL(v1, 17); \
60
232k
        v1 ^= v2;          \
61
232k
        v2 = ROTL(v2, 32); \
62
232k
    } while(0)
63
64
#ifdef DEBUG
65
#define TRACE                                            \
66
    do {                                                 \
67
        printf("(%3zu) v0 %016" PRIx64 "\n", inlen, v0); \
68
        printf("(%3zu) v1 %016" PRIx64 "\n", inlen, v1); \
69
        printf("(%3zu) v2 %016" PRIx64 "\n", inlen, v2); \
70
        printf("(%3zu) v3 %016" PRIx64 "\n", inlen, v3); \
71
    } while(0)
72
#else
73
#define TRACE
74
#endif
75
76
int passgen_siphash(
77
    const void *in,
78
    const size_t inlen,
79
    const void *k,
80
    uint8_t *out,
81
38.6k
    const size_t outlen) {
82
38.6k
    const unsigned char *ni = (const unsigned char *) in;
83
38.6k
    const unsigned char *kk = (const unsigned char *) k;
84
38.6k
85
38.6k
    assert((outlen == 8) || (outlen == 16));
86
38.6k
    uint64_t v0 = UINT64_C(0x736f6d6570736575);
87
38.6k
    uint64_t v1 = UINT64_C(0x646f72616e646f6d);
88
38.6k
    uint64_t v2 = UINT64_C(0x6c7967656e657261);
89
38.6k
    uint64_t v3 = UINT64_C(0x7465646279746573);
90
38.6k
    uint64_t k0 = U8TO64_LE(kk);
91
38.6k
    uint64_t k1 = U8TO64_LE(kk + 8);
92
38.6k
    uint64_t m;
93
38.6k
    int i;
94
38.6k
    const unsigned char *end = ni + inlen - (inlen % sizeof(uint64_t));
95
38.6k
    const int left = inlen & 7;
96
38.6k
    uint64_t b = ((uint64_t) inlen) << 56;
97
38.6k
    v3 ^= k1;
98
38.6k
    v2 ^= k0;
99
38.6k
    v1 ^= k1;
100
38.6k
    v0 ^= k0;
101
38.6k
102
38.6k
    if(outlen == 16) 
v1 ^= 0xee8
;
103
38.6k
104
38.6k
    for(; ni != end; 
ni += 82
) {
105
2
        m = U8TO64_LE(ni);
106
2
        v3 ^= m;
107
2
108
2
        TRACE;
109
6
        for(i = 0; i < cROUNDS; 
++i4
)
SIPROUND4
;
110
2
111
2
        v0 ^= m;
112
2
    }
113
38.6k
114
38.6k
    switch(left) {
115
5
        case 7:
116
5
            b |= ((uint64_t) ni[6]) << 48;
117
5
            // fall through
118
5
        case 6:
119
5
            b |= ((uint64_t) ni[5]) << 40;
120
5
            // fall through
121
57
        case 5:
122
57
            b |= ((uint64_t) ni[4]) << 32;
123
57
            // fall through
124
29.2k
        case 4:
125
29.2k
            b |= ((uint64_t) ni[3]) << 24;
126
29.2k
            // fall through
127
37.0k
        case 3:
128
37.0k
            b |= ((uint64_t) ni[2]) << 16;
129
37.0k
            // fall through
130
38.4k
        case 2:
131
38.4k
            b |= ((uint64_t) ni[1]) << 8;
132
38.4k
            // fall through
133
38.6k
        case 1:
134
38.6k
            b |= ((uint64_t) ni[0]);
135
38.6k
            break;
136
38.4k
        case 0:
137
2
            break;
138
38.6k
    }
139
38.6k
140
38.6k
    v3 ^= b;
141
38.6k
142
38.6k
    TRACE;
143
116k
    for(i = 0; i < cROUNDS; 
++i77.3k
)
SIPROUND77.3k
;
144
38.6k
145
38.6k
    v0 ^= b;
146
38.6k
147
38.6k
    if(outlen == 16)
148
8
        v2 ^= 0xee;
149
38.6k
    else
150
38.6k
        v2 ^= 0xff;
151
38.6k
152
38.6k
    TRACE;
153
193k
    for(i = 0; i < dROUNDS; 
++i154k
)
SIPROUND154k
;
154
38.6k
155
38.6k
    b = v0 ^ v1 ^ v2 ^ v3;
156
38.6k
    U64TO8_LE(out, b);
157
38.6k
158
38.6k
    if(outlen == 8) 
return 038.6k
;
159
8
160
8
    v1 ^= 0xdd;
161
8
162
8
    TRACE;
163
40
    for(i = 0; i < dROUNDS; 
++i32
)
SIPROUND32
;
164
8
165
8
    b = v0 ^ v1 ^ v2 ^ v3;
166
8
    U64TO8_LE(out + 8, b);
167
8
168
8
    return 0;
169
8
}