Repository navigation
Expand file tree
/
Copy pathsiphash.go
More file actions
62 lines (58 loc) · 1.72 KB
/
Copy pathsiphash.go
File metadata and controls
62 lines (58 loc) · 1.72 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
package mipstack
import (
"encoding/binary"
"math/bits"
)
// sipHash24 implements SipHash-2-4, a keyed pseudorandom function designed
// for short inputs. MIPS uses it for RFC 6528 initial sequence numbers,
// SYN-cookie authentication, RFC 6056-style automatic port selection,
// REUSEPORT flow selection, automatic IPv6 Flow Labels, multicast report
// randomization, and destination-scoped ICMP error limiting. It is kept local
// so these features do not add another package's initialization graph.
func sipHash24(key [16]byte, message []byte) uint64 {
length := len(message)
k0 := binary.LittleEndian.Uint64(key[0:8])
k1 := binary.LittleEndian.Uint64(key[8:16])
v0 := uint64(0x736f6d6570736575) ^ k0
v1 := uint64(0x646f72616e646f6d) ^ k1
v2 := uint64(0x6c7967656e657261) ^ k0
v3 := uint64(0x7465646279746573) ^ k1
for len(message) >= 8 {
word := binary.LittleEndian.Uint64(message[:8])
v3 ^= word
sipHashRound(&v0, &v1, &v2, &v3)
sipHashRound(&v0, &v1, &v2, &v3)
v0 ^= word
message = message[8:]
}
last := uint64(length) << 56
for index, value := range message {
last |= uint64(value) << (8 * index)
}
v3 ^= last
sipHashRound(&v0, &v1, &v2, &v3)
sipHashRound(&v0, &v1, &v2, &v3)
v0 ^= last
v2 ^= 0xff
for round := 0; round < 4; round++ {
sipHashRound(&v0, &v1, &v2, &v3)
}
return v0 ^ v1 ^ v2 ^ v3
}
// sipHashRound is one directly transcribed SipHash compression round.
func sipHashRound(v0, v1, v2, v3 *uint64) {
*v0 += *v1
*v1 = bits.RotateLeft64(*v1, 13)
*v1 ^= *v0
*v0 = bits.RotateLeft64(*v0, 32)
*v2 += *v3
*v3 = bits.RotateLeft64(*v3, 16)
*v3 ^= *v2
*v0 += *v3
*v3 = bits.RotateLeft64(*v3, 21)
*v3 ^= *v0
*v2 += *v1
*v1 = bits.RotateLeft64(*v1, 17)
*v1 ^= *v2
*v2 = bits.RotateLeft64(*v2, 32)
}