Coverage Report

Created: 2026-05-30 06:53

next uncovered line (L), next uncovered region (R), next uncovered branch (B)
/rust/registry/src/index.crates.io-1949cf8c6b5b557f/siphasher-1.0.3/src/sip128.rs
Line
Count
Source
1
// Copyright 2012-2015 The Rust Project Developers. See the COPYRIGHT
2
// file at the top-level directory of this distribution and at
3
// http://rust-lang.org/COPYRIGHT.
4
//
5
// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
6
// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
7
// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
8
// option. This file may not be copied, modified, or distributed
9
// except according to those terms.
10
11
//! An implementation of SipHash with a 128-bit output.
12
13
use core::cmp;
14
use core::hash;
15
use core::hash::Hasher as _;
16
use core::marker::PhantomData;
17
use core::mem;
18
19
use crate::common::{compress, load_int_le, u8to64_le};
20
21
/// A 128-bit (2x64) hash output
22
#[derive(Debug, Clone, Copy, Default)]
23
#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
24
pub struct Hash128 {
25
    pub h1: u64,
26
    pub h2: u64,
27
}
28
29
impl PartialEq for Hash128 {
30
    /// Constant-time equality comparison to prevent timing attacks.
31
0
    fn eq(&self, other: &Self) -> bool {
32
0
        let x = (self.h1 ^ other.h1) | (self.h2 ^ other.h2);
33
0
        unsafe { core::ptr::read_volatile(&x) == 0 }
34
0
    }
35
}
36
37
impl Eq for Hash128 {}
38
39
impl From<u128> for Hash128 {
40
0
    fn from(v: u128) -> Self {
41
0
        Hash128 {
42
0
            h1: v as u64,
43
0
            h2: (v >> 64) as u64,
44
0
        }
45
0
    }
46
}
47
48
impl From<Hash128> for u128 {
49
0
    fn from(h: Hash128) -> u128 {
50
0
        (h.h1 as u128) | ((h.h2 as u128) << 64)
51
0
    }
52
}
53
54
/// An implementation of SipHash128 1-3.
55
#[derive(Debug, Clone, Copy, Default)]
56
#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
57
pub struct SipHasher13 {
58
    hasher: Hasher<Sip13Rounds>,
59
}
60
61
/// An implementation of SipHash128 2-4.
62
#[derive(Debug, Clone, Copy, Default)]
63
#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
64
pub struct SipHasher24 {
65
    hasher: Hasher<Sip24Rounds>,
66
}
67
68
/// An implementation of SipHash128 2-4.
69
///
70
/// SipHash is a general-purpose hashing function: it runs at a good
71
/// speed (competitive with Spooky and City) and permits strong _keyed_
72
/// hashing. This lets you key your hashtables from a strong RNG, such as
73
/// [`rand::os::OsRng`](https://doc.rust-lang.org/rand/rand/os/struct.OsRng.html).
74
///
75
/// Although the SipHash algorithm is considered to be generally strong,
76
/// it is not intended for cryptographic purposes. As such, all
77
/// cryptographic uses of this implementation are _strongly discouraged_.
78
#[derive(Debug, Clone, Copy, Default)]
79
#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
80
pub struct SipHasher(SipHasher24);
81
82
#[derive(Debug, Copy)]
83
#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
84
struct Hasher<S: Sip> {
85
    k0: u64,
86
    k1: u64,
87
    length: usize, // how many bytes we've processed
88
    state: State,  // hash State
89
    tail: u64,     // unprocessed bytes le
90
    ntail: usize,  // how many bytes in tail are valid
91
    _marker: PhantomData<S>,
92
}
93
94
#[derive(Debug, Clone, Copy)]
95
#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
96
struct State {
97
    // v0, v2 and v1, v3 show up in pairs in the algorithm,
98
    // and simd implementations of SipHash will use vectors
99
    // of v02 and v13. By placing them in this order in the struct,
100
    // the compiler can pick up on just a few simd optimizations by itself.
101
    v0: u64,
102
    v2: u64,
103
    v1: u64,
104
    v3: u64,
105
}
106
107
pub trait Hasher128 {
108
    /// Return a 128-bit hash
109
    fn finish128(&self) -> Hash128;
110
}
111
112
impl SipHasher {
113
    /// Creates a new `SipHasher` with the two initial keys set to 0.
114
    #[inline]
115
0
    pub fn new() -> SipHasher {
116
0
        SipHasher::new_with_keys(0, 0)
117
0
    }
118
119
    /// Creates a `SipHasher` that is keyed off the provided keys.
120
    #[inline]
121
0
    pub fn new_with_keys(key0: u64, key1: u64) -> SipHasher {
122
0
        SipHasher(SipHasher24::new_with_keys(key0, key1))
123
0
    }
124
125
    /// Creates a `SipHasher` from a 16 byte key.
126
0
    pub fn new_with_key(key: &[u8; 16]) -> SipHasher {
127
0
        let mut b0 = [0u8; 8];
128
0
        let mut b1 = [0u8; 8];
129
0
        b0.copy_from_slice(&key[0..8]);
130
0
        b1.copy_from_slice(&key[8..16]);
131
0
        let key0 = u64::from_le_bytes(b0);
132
0
        let key1 = u64::from_le_bytes(b1);
133
0
        Self::new_with_keys(key0, key1)
134
0
    }
135
136
    /// Get the keys used by this hasher
137
0
    pub fn keys(&self) -> (u64, u64) {
138
0
        (self.0.hasher.k0, self.0.hasher.k1)
139
0
    }
140
141
    /// Get the key used by this hasher as a 16 byte vector
142
0
    pub fn key(&self) -> [u8; 16] {
143
0
        let mut bytes = [0u8; 16];
144
0
        bytes[0..8].copy_from_slice(&self.0.hasher.k0.to_le_bytes());
145
0
        bytes[8..16].copy_from_slice(&self.0.hasher.k1.to_le_bytes());
146
0
        bytes
147
0
    }
148
149
    /// Hash a byte array - This is the easiest and safest way to use SipHash.
150
    #[inline]
151
0
    pub fn hash(&self, bytes: &[u8]) -> Hash128 {
152
0
        self.0.hasher.hash128(bytes)
153
0
    }
154
}
155
156
impl Hasher128 for SipHasher {
157
    /// Return a 128-bit hash
158
    #[inline]
159
0
    fn finish128(&self) -> Hash128 {
160
0
        self.0.finish128()
161
0
    }
162
}
163
164
impl SipHasher13 {
165
    /// Creates a new `SipHasher13` with the two initial keys set to 0.
166
    #[inline]
167
0
    pub fn new() -> SipHasher13 {
168
0
        SipHasher13::new_with_keys(0, 0)
169
0
    }
170
171
    /// Creates a `SipHasher13` that is keyed off the provided keys.
172
    #[inline]
173
3.08M
    pub fn new_with_keys(key0: u64, key1: u64) -> SipHasher13 {
174
3.08M
        SipHasher13 {
175
3.08M
            hasher: Hasher::new_with_keys(key0, key1),
176
3.08M
        }
177
3.08M
    }
Unexecuted instantiation: <siphasher::sip128::SipHasher13>::new_with_keys
Unexecuted instantiation: <siphasher::sip128::SipHasher13>::new_with_keys
<siphasher::sip128::SipHasher13>::new_with_keys
Line
Count
Source
173
3.08M
    pub fn new_with_keys(key0: u64, key1: u64) -> SipHasher13 {
174
3.08M
        SipHasher13 {
175
3.08M
            hasher: Hasher::new_with_keys(key0, key1),
176
3.08M
        }
177
3.08M
    }
178
179
    /// Creates a `SipHasher13` from a 16 byte key.
180
0
    pub fn new_with_key(key: &[u8; 16]) -> SipHasher13 {
181
0
        let mut b0 = [0u8; 8];
182
0
        let mut b1 = [0u8; 8];
183
0
        b0.copy_from_slice(&key[0..8]);
184
0
        b1.copy_from_slice(&key[8..16]);
185
0
        let key0 = u64::from_le_bytes(b0);
186
0
        let key1 = u64::from_le_bytes(b1);
187
0
        Self::new_with_keys(key0, key1)
188
0
    }
189
190
    /// Get the keys used by this hasher
191
0
    pub fn keys(&self) -> (u64, u64) {
192
0
        (self.hasher.k0, self.hasher.k1)
193
0
    }
194
195
    /// Get the key used by this hasher as a 16 byte vector
196
0
    pub fn key(&self) -> [u8; 16] {
197
0
        let mut bytes = [0u8; 16];
198
0
        bytes[0..8].copy_from_slice(&self.hasher.k0.to_le_bytes());
199
0
        bytes[8..16].copy_from_slice(&self.hasher.k1.to_le_bytes());
200
0
        bytes
201
0
    }
202
203
    /// Hash a byte array - This is the easiest and safest way to use SipHash.
204
    #[inline]
205
0
    pub fn hash(&self, bytes: &[u8]) -> Hash128 {
206
0
        self.hasher.hash128(bytes)
207
0
    }
208
}
209
210
impl Hasher128 for SipHasher13 {
211
    /// Return a 128-bit hash
212
    #[inline]
213
3.08M
    fn finish128(&self) -> Hash128 {
214
3.08M
        self.hasher.finish128()
215
3.08M
    }
Unexecuted instantiation: <siphasher::sip128::SipHasher13 as siphasher::sip128::Hasher128>::finish128
Unexecuted instantiation: <siphasher::sip128::SipHasher13 as siphasher::sip128::Hasher128>::finish128
<siphasher::sip128::SipHasher13 as siphasher::sip128::Hasher128>::finish128
Line
Count
Source
213
3.08M
    fn finish128(&self) -> Hash128 {
214
3.08M
        self.hasher.finish128()
215
3.08M
    }
216
}
217
218
impl SipHasher24 {
219
    /// Creates a new `SipHasher24` with the two initial keys set to 0.
220
    #[inline]
221
0
    pub fn new() -> SipHasher24 {
222
0
        SipHasher24::new_with_keys(0, 0)
223
0
    }
224
225
    /// Creates a `SipHasher24` that is keyed off the provided keys.
226
    #[inline]
227
0
    pub fn new_with_keys(key0: u64, key1: u64) -> SipHasher24 {
228
0
        SipHasher24 {
229
0
            hasher: Hasher::new_with_keys(key0, key1),
230
0
        }
231
0
    }
232
233
    /// Creates a `SipHasher24` from a 16 byte key.
234
0
    pub fn new_with_key(key: &[u8; 16]) -> SipHasher24 {
235
0
        let mut b0 = [0u8; 8];
236
0
        let mut b1 = [0u8; 8];
237
0
        b0.copy_from_slice(&key[0..8]);
238
0
        b1.copy_from_slice(&key[8..16]);
239
0
        let key0 = u64::from_le_bytes(b0);
240
0
        let key1 = u64::from_le_bytes(b1);
241
0
        Self::new_with_keys(key0, key1)
242
0
    }
243
244
    /// Get the keys used by this hasher
245
0
    pub fn keys(&self) -> (u64, u64) {
246
0
        (self.hasher.k0, self.hasher.k1)
247
0
    }
248
249
    /// Get the key used by this hasher as a 16 byte vector
250
0
    pub fn key(&self) -> [u8; 16] {
251
0
        let mut bytes = [0u8; 16];
252
0
        bytes[0..8].copy_from_slice(&self.hasher.k0.to_le_bytes());
253
0
        bytes[8..16].copy_from_slice(&self.hasher.k1.to_le_bytes());
254
0
        bytes
255
0
    }
256
257
    /// Hash a byte array - This is the easiest and safest way to use SipHash.
258
    #[inline]
259
0
    pub fn hash(&self, bytes: &[u8]) -> Hash128 {
260
0
        self.hasher.hash128(bytes)
261
0
    }
262
}
263
264
impl Hasher128 for SipHasher24 {
265
    /// Return a 128-bit hash
266
    #[inline]
267
0
    fn finish128(&self) -> Hash128 {
268
0
        self.hasher.finish128()
269
0
    }
270
}
271
272
impl<S: Sip> Hasher<S> {
273
    #[inline]
274
3.08M
    fn new_with_keys(key0: u64, key1: u64) -> Hasher<S> {
275
3.08M
        let mut state = Hasher {
276
3.08M
            k0: key0,
277
3.08M
            k1: key1,
278
3.08M
            length: 0,
279
3.08M
            state: State {
280
3.08M
                v0: 0,
281
3.08M
                v1: 0xee,
282
3.08M
                v2: 0,
283
3.08M
                v3: 0,
284
3.08M
            },
285
3.08M
            tail: 0,
286
3.08M
            ntail: 0,
287
3.08M
            _marker: PhantomData,
288
3.08M
        };
289
3.08M
        state.reset();
290
3.08M
        state
291
3.08M
    }
<siphasher::sip128::Hasher<siphasher::sip128::Sip13Rounds>>::new_with_keys
Line
Count
Source
274
3.08M
    fn new_with_keys(key0: u64, key1: u64) -> Hasher<S> {
275
3.08M
        let mut state = Hasher {
276
3.08M
            k0: key0,
277
3.08M
            k1: key1,
278
3.08M
            length: 0,
279
3.08M
            state: State {
280
3.08M
                v0: 0,
281
3.08M
                v1: 0xee,
282
3.08M
                v2: 0,
283
3.08M
                v3: 0,
284
3.08M
            },
285
3.08M
            tail: 0,
286
3.08M
            ntail: 0,
287
3.08M
            _marker: PhantomData,
288
3.08M
        };
289
3.08M
        state.reset();
290
3.08M
        state
291
3.08M
    }
Unexecuted instantiation: <siphasher::sip128::Hasher<siphasher::sip128::Sip24Rounds>>::new_with_keys
292
293
    #[inline]
294
3.08M
    fn reset(&mut self) {
295
3.08M
        self.length = 0;
296
3.08M
        self.state.v0 = self.k0 ^ 0x736f6d6570736575;
297
3.08M
        self.state.v1 = self.k1 ^ 0x646f72616e646f83;
298
3.08M
        self.state.v2 = self.k0 ^ 0x6c7967656e657261;
299
3.08M
        self.state.v3 = self.k1 ^ 0x7465646279746573;
300
3.08M
        self.ntail = 0;
301
3.08M
    }
<siphasher::sip128::Hasher<siphasher::sip128::Sip13Rounds>>::reset
Line
Count
Source
294
3.08M
    fn reset(&mut self) {
295
3.08M
        self.length = 0;
296
3.08M
        self.state.v0 = self.k0 ^ 0x736f6d6570736575;
297
3.08M
        self.state.v1 = self.k1 ^ 0x646f72616e646f83;
298
3.08M
        self.state.v2 = self.k0 ^ 0x6c7967656e657261;
299
3.08M
        self.state.v3 = self.k1 ^ 0x7465646279746573;
300
3.08M
        self.ntail = 0;
301
3.08M
    }
Unexecuted instantiation: <siphasher::sip128::Hasher<siphasher::sip128::Sip24Rounds>>::reset
302
303
    // A specialized write function for values with size <= 8.
304
    //
305
    // The hashing of multi-byte integers depends on endianness. E.g.:
306
    // - little-endian: `write_u32(0xDDCCBBAA)` == `write([0xAA, 0xBB, 0xCC, 0xDD])`
307
    // - big-endian:    `write_u32(0xDDCCBBAA)` == `write([0xDD, 0xCC, 0xBB, 0xAA])`
308
    //
309
    // This function does the right thing for little-endian hardware. On
310
    // big-endian hardware `x` must be byte-swapped first to give the right
311
    // behaviour. After any byte-swapping, the input must be zero-extended to
312
    // 64-bits. The caller is responsible for the byte-swapping and
313
    // zero-extension.
314
    #[inline]
315
0
    fn short_write<T>(&mut self, _x: T, x: u64) {
316
0
        let size = mem::size_of::<T>();
317
0
        self.length += size;
318
319
        // The original number must be zero-extended, not sign-extended.
320
0
        debug_assert!(if size < 8 { x >> (8 * size) == 0 } else { true });
321
322
        // The number of bytes needed to fill `self.tail`.
323
0
        let needed = 8 - self.ntail;
324
325
0
        self.tail |= x << (8 * self.ntail);
326
0
        if size < needed {
327
0
            self.ntail += size;
328
0
            return;
329
0
        }
330
331
        // `self.tail` is full, process it.
332
0
        self.state.v3 ^= self.tail;
333
0
        S::c_rounds(&mut self.state);
334
0
        self.state.v0 ^= self.tail;
335
336
0
        self.ntail = size - needed;
337
0
        self.tail = if needed < 8 { x >> (8 * needed) } else { 0 };
338
0
    }
339
340
    #[inline]
341
0
    fn hash128(&self, msg: &[u8]) -> Hash128 {
342
0
        if self.ntail != 0 {
343
0
            let mut hasher = self.clone();
344
0
            hasher.write(msg);
345
0
            return hasher.finish128();
346
0
        }
347
348
0
        let length = self.length + msg.len();
349
0
        let len = msg.len();
350
0
        let left = len & 0x7;
351
0
        let mut state = self.state;
352
0
        let mut i = 0;
353
354
0
        while i < len - left {
355
0
            let mi = unsafe { load_int_le!(msg, i, u64) };
356
357
0
            state.v3 ^= mi;
358
0
            S::c_rounds(&mut state);
359
0
            state.v0 ^= mi;
360
361
0
            i += 8;
362
        }
363
364
0
        let tail = unsafe { u8to64_le(msg, i, left) };
365
0
        Self::finish128_with_state(state, length, tail)
366
0
    }
367
368
    #[inline]
369
3.08M
    fn finish128_with_state(mut state: State, length: usize, tail: u64) -> Hash128 {
370
3.08M
        let b: u64 = ((length as u64 & 0xff) << 56) | tail;
371
372
3.08M
        state.v3 ^= b;
373
3.08M
        S::c_rounds(&mut state);
374
3.08M
        state.v0 ^= b;
375
376
3.08M
        state.v2 ^= 0xee;
377
3.08M
        S::d_rounds(&mut state);
378
3.08M
        let h1 = state.v0 ^ state.v1 ^ state.v2 ^ state.v3;
379
380
3.08M
        state.v1 ^= 0xdd;
381
3.08M
        S::d_rounds(&mut state);
382
3.08M
        let h2 = state.v0 ^ state.v1 ^ state.v2 ^ state.v3;
383
384
3.08M
        Hash128 { h1, h2 }
385
3.08M
    }
Unexecuted instantiation: <siphasher::sip128::Hasher<siphasher::sip128::Sip13Rounds>>::finish128_with_state
Unexecuted instantiation: <siphasher::sip128::Hasher<_>>::finish128_with_state
<siphasher::sip128::Hasher<siphasher::sip128::Sip13Rounds>>::finish128_with_state
Line
Count
Source
369
3.08M
    fn finish128_with_state(mut state: State, length: usize, tail: u64) -> Hash128 {
370
3.08M
        let b: u64 = ((length as u64 & 0xff) << 56) | tail;
371
372
3.08M
        state.v3 ^= b;
373
3.08M
        S::c_rounds(&mut state);
374
3.08M
        state.v0 ^= b;
375
376
3.08M
        state.v2 ^= 0xee;
377
3.08M
        S::d_rounds(&mut state);
378
3.08M
        let h1 = state.v0 ^ state.v1 ^ state.v2 ^ state.v3;
379
380
3.08M
        state.v1 ^= 0xdd;
381
3.08M
        S::d_rounds(&mut state);
382
3.08M
        let h2 = state.v0 ^ state.v1 ^ state.v2 ^ state.v3;
383
384
3.08M
        Hash128 { h1, h2 }
385
3.08M
    }
386
}
387
388
impl<S: Sip> Hasher<S> {
389
    #[inline]
390
3.08M
    pub fn finish128(&self) -> Hash128 {
391
3.08M
        Self::finish128_with_state(self.state, self.length, self.tail)
392
3.08M
    }
Unexecuted instantiation: <siphasher::sip128::Hasher<siphasher::sip128::Sip13Rounds>>::finish128
Unexecuted instantiation: <siphasher::sip128::Hasher<_>>::finish128
<siphasher::sip128::Hasher<siphasher::sip128::Sip13Rounds>>::finish128
Line
Count
Source
390
3.08M
    pub fn finish128(&self) -> Hash128 {
391
3.08M
        Self::finish128_with_state(self.state, self.length, self.tail)
392
3.08M
    }
393
}
394
395
impl hash::Hasher for SipHasher {
396
    #[inline]
397
0
    fn write(&mut self, msg: &[u8]) {
398
0
        self.0.write(msg)
399
0
    }
400
401
    #[inline]
402
0
    fn finish(&self) -> u64 {
403
0
        self.0.finish()
404
0
    }
405
406
    #[inline]
407
0
    fn write_usize(&mut self, i: usize) {
408
0
        self.0.write_usize(i);
409
0
    }
410
411
    #[inline]
412
0
    fn write_u8(&mut self, i: u8) {
413
0
        self.0.write_u8(i);
414
0
    }
415
416
    #[inline]
417
0
    fn write_u16(&mut self, i: u16) {
418
0
        self.0.write_u16(i);
419
0
    }
420
421
    #[inline]
422
0
    fn write_u32(&mut self, i: u32) {
423
0
        self.0.write_u32(i);
424
0
    }
425
426
    #[inline]
427
0
    fn write_u64(&mut self, i: u64) {
428
0
        self.0.write_u64(i);
429
0
    }
430
}
431
432
impl hash::Hasher for SipHasher13 {
433
    #[inline]
434
3.08M
    fn write(&mut self, msg: &[u8]) {
435
3.08M
        self.hasher.write(msg)
436
3.08M
    }
Unexecuted instantiation: <siphasher::sip128::SipHasher13 as core::hash::Hasher>::write
Unexecuted instantiation: <siphasher::sip128::SipHasher13 as core::hash::Hasher>::write
<siphasher::sip128::SipHasher13 as core::hash::Hasher>::write
Line
Count
Source
434
3.08M
    fn write(&mut self, msg: &[u8]) {
435
3.08M
        self.hasher.write(msg)
436
3.08M
    }
437
438
    #[inline]
439
0
    fn finish(&self) -> u64 {
440
0
        self.hasher.finish()
441
0
    }
442
443
    #[inline]
444
0
    fn write_usize(&mut self, i: usize) {
445
0
        self.hasher.write_usize(i);
446
0
    }
447
448
    #[inline]
449
0
    fn write_u8(&mut self, i: u8) {
450
0
        self.hasher.write_u8(i);
451
0
    }
452
453
    #[inline]
454
0
    fn write_u16(&mut self, i: u16) {
455
0
        self.hasher.write_u16(i);
456
0
    }
457
458
    #[inline]
459
0
    fn write_u32(&mut self, i: u32) {
460
0
        self.hasher.write_u32(i);
461
0
    }
462
463
    #[inline]
464
0
    fn write_u64(&mut self, i: u64) {
465
0
        self.hasher.write_u64(i);
466
0
    }
467
}
468
469
impl hash::Hasher for SipHasher24 {
470
    #[inline]
471
0
    fn write(&mut self, msg: &[u8]) {
472
0
        self.hasher.write(msg)
473
0
    }
474
475
    #[inline]
476
0
    fn finish(&self) -> u64 {
477
0
        self.hasher.finish()
478
0
    }
479
480
    #[inline]
481
0
    fn write_usize(&mut self, i: usize) {
482
0
        self.hasher.write_usize(i);
483
0
    }
484
485
    #[inline]
486
0
    fn write_u8(&mut self, i: u8) {
487
0
        self.hasher.write_u8(i);
488
0
    }
489
490
    #[inline]
491
0
    fn write_u16(&mut self, i: u16) {
492
0
        self.hasher.write_u16(i);
493
0
    }
494
495
    #[inline]
496
0
    fn write_u32(&mut self, i: u32) {
497
0
        self.hasher.write_u32(i);
498
0
    }
499
500
    #[inline]
501
0
    fn write_u64(&mut self, i: u64) {
502
0
        self.hasher.write_u64(i);
503
0
    }
504
}
505
506
impl<S: Sip> hash::Hasher for Hasher<S> {
507
    #[inline]
508
0
    fn write_usize(&mut self, i: usize) {
509
0
        self.short_write(i, i.to_le() as u64);
510
0
    }
511
512
    #[inline]
513
0
    fn write_u8(&mut self, i: u8) {
514
0
        self.short_write(i, i as u64);
515
0
    }
516
517
    #[inline]
518
0
    fn write_u16(&mut self, i: u16) {
519
0
        self.short_write(i, i.to_le() as u64);
520
0
    }
521
522
    #[inline]
523
0
    fn write_u32(&mut self, i: u32) {
524
0
        self.short_write(i, i.to_le() as u64);
525
0
    }
526
527
    #[inline]
528
0
    fn write_u64(&mut self, i: u64) {
529
0
        self.short_write(i, i.to_le());
530
0
    }
531
532
    #[inline]
533
3.08M
    fn write(&mut self, msg: &[u8]) {
534
3.08M
        let length = msg.len();
535
3.08M
        self.length += length;
536
537
3.08M
        let mut needed = 0;
538
539
3.08M
        if self.ntail != 0 {
540
0
            needed = 8 - self.ntail;
541
0
            self.tail |= unsafe { u8to64_le(msg, 0, cmp::min(length, needed)) } << (8 * self.ntail);
542
0
            if length < needed {
543
0
                self.ntail += length;
544
0
                return;
545
0
            } else {
546
0
                self.state.v3 ^= self.tail;
547
0
                S::c_rounds(&mut self.state);
548
0
                self.state.v0 ^= self.tail;
549
0
                self.ntail = 0;
550
0
            }
551
3.08M
        }
552
553
        // Buffered tail is now flushed, process new input.
554
3.08M
        let len = length - needed;
555
3.08M
        let left = len & 0x7;
556
557
3.08M
        let mut i = needed;
558
13.6M
        while i < len - left {
559
10.5M
            let mi = unsafe { load_int_le!(msg, i, u64) };
560
561
10.5M
            self.state.v3 ^= mi;
562
10.5M
            S::c_rounds(&mut self.state);
563
10.5M
            self.state.v0 ^= mi;
564
565
10.5M
            i += 8;
566
        }
567
568
3.08M
        self.tail = unsafe { u8to64_le(msg, i, left) };
569
3.08M
        self.ntail = left;
570
3.08M
    }
Unexecuted instantiation: <siphasher::sip128::Hasher<siphasher::sip128::Sip13Rounds> as core::hash::Hasher>::write
Unexecuted instantiation: <siphasher::sip128::Hasher<_> as core::hash::Hasher>::write
<siphasher::sip128::Hasher<siphasher::sip128::Sip13Rounds> as core::hash::Hasher>::write
Line
Count
Source
533
3.08M
    fn write(&mut self, msg: &[u8]) {
534
3.08M
        let length = msg.len();
535
3.08M
        self.length += length;
536
537
3.08M
        let mut needed = 0;
538
539
3.08M
        if self.ntail != 0 {
540
0
            needed = 8 - self.ntail;
541
0
            self.tail |= unsafe { u8to64_le(msg, 0, cmp::min(length, needed)) } << (8 * self.ntail);
542
0
            if length < needed {
543
0
                self.ntail += length;
544
0
                return;
545
0
            } else {
546
0
                self.state.v3 ^= self.tail;
547
0
                S::c_rounds(&mut self.state);
548
0
                self.state.v0 ^= self.tail;
549
0
                self.ntail = 0;
550
0
            }
551
3.08M
        }
552
553
        // Buffered tail is now flushed, process new input.
554
3.08M
        let len = length - needed;
555
3.08M
        let left = len & 0x7;
556
557
3.08M
        let mut i = needed;
558
13.6M
        while i < len - left {
559
10.5M
            let mi = unsafe { load_int_le!(msg, i, u64) };
560
561
10.5M
            self.state.v3 ^= mi;
562
10.5M
            S::c_rounds(&mut self.state);
563
10.5M
            self.state.v0 ^= mi;
564
565
10.5M
            i += 8;
566
        }
567
568
3.08M
        self.tail = unsafe { u8to64_le(msg, i, left) };
569
3.08M
        self.ntail = left;
570
3.08M
    }
571
572
    #[inline]
573
0
    fn finish(&self) -> u64 {
574
0
        self.finish128().h2
575
0
    }
576
}
577
578
impl<S: Sip> Clone for Hasher<S> {
579
    #[inline]
580
0
    fn clone(&self) -> Hasher<S> {
581
0
        Hasher {
582
0
            k0: self.k0,
583
0
            k1: self.k1,
584
0
            length: self.length,
585
0
            state: self.state,
586
0
            tail: self.tail,
587
0
            ntail: self.ntail,
588
0
            _marker: self._marker,
589
0
        }
590
0
    }
591
}
592
593
impl<S: Sip> Default for Hasher<S> {
594
    /// Creates a `Hasher<S>` with the two initial keys set to 0.
595
    #[inline]
596
0
    fn default() -> Hasher<S> {
597
0
        Hasher::new_with_keys(0, 0)
598
0
    }
599
}
600
601
#[doc(hidden)]
602
trait Sip {
603
    fn c_rounds(_: &mut State);
604
    fn d_rounds(_: &mut State);
605
}
606
607
#[derive(Debug, Clone, Copy, Default)]
608
struct Sip13Rounds;
609
610
impl Sip for Sip13Rounds {
611
    #[inline]
612
13.6M
    fn c_rounds(state: &mut State) {
613
13.6M
        compress!(state);
614
13.6M
    }
Unexecuted instantiation: <siphasher::sip128::Sip13Rounds as siphasher::sip128::Sip>::c_rounds
Unexecuted instantiation: <siphasher::sip128::Sip13Rounds as siphasher::sip128::Sip>::c_rounds
<siphasher::sip128::Sip13Rounds as siphasher::sip128::Sip>::c_rounds
Line
Count
Source
612
13.6M
    fn c_rounds(state: &mut State) {
613
13.6M
        compress!(state);
614
13.6M
    }
615
616
    #[inline]
617
6.17M
    fn d_rounds(state: &mut State) {
618
6.17M
        compress!(state);
619
6.17M
        compress!(state);
620
6.17M
        compress!(state);
621
6.17M
    }
Unexecuted instantiation: <siphasher::sip128::Sip13Rounds as siphasher::sip128::Sip>::d_rounds
Unexecuted instantiation: <siphasher::sip128::Sip13Rounds as siphasher::sip128::Sip>::d_rounds
<siphasher::sip128::Sip13Rounds as siphasher::sip128::Sip>::d_rounds
Line
Count
Source
617
6.17M
    fn d_rounds(state: &mut State) {
618
6.17M
        compress!(state);
619
6.17M
        compress!(state);
620
6.17M
        compress!(state);
621
6.17M
    }
622
}
623
624
#[derive(Debug, Clone, Copy, Default)]
625
struct Sip24Rounds;
626
627
impl Sip for Sip24Rounds {
628
    #[inline]
629
0
    fn c_rounds(state: &mut State) {
630
0
        compress!(state);
631
0
        compress!(state);
632
0
    }
633
634
    #[inline]
635
0
    fn d_rounds(state: &mut State) {
636
0
        compress!(state);
637
0
        compress!(state);
638
0
        compress!(state);
639
0
        compress!(state);
640
0
    }
641
}
642
643
impl Hash128 {
644
    /// Convert into a 16-bytes vector
645
0
    pub fn as_bytes(&self) -> [u8; 16] {
646
0
        let mut bytes = [0u8; 16];
647
0
        bytes[0..8].copy_from_slice(&self.h1.to_le_bytes());
648
0
        bytes[8..16].copy_from_slice(&self.h2.to_le_bytes());
649
0
        bytes
650
0
    }
651
652
    /// Convert into a `u128`
653
    #[inline]
654
0
    pub fn as_u128(&self) -> u128 {
655
0
        let h1 = self.h1.to_le();
656
0
        let h2 = self.h2.to_le();
657
0
        h1 as u128 | ((h2 as u128) << 64)
658
0
    }
659
660
    /// Convert into `(u64, u64)`
661
    #[inline]
662
0
    pub fn as_u64(&self) -> (u64, u64) {
663
0
        let h1 = self.h1.to_le();
664
0
        let h2 = self.h2.to_le();
665
0
        (h1, h2)
666
0
    }
667
}