1// +build !arm,!amd64 appengine gccgo
2
3// Written in 2012 by Dmitry Chestnykh.
4//
5// To the extent possible under law, the author have dedicated all copyright
6// and related and neighboring rights to this software to the public domain
7// worldwide. This software is distributed without any warranty.
8// http://creativecommons.org/publicdomain/zero/1.0/
9
10package siphash
11
12// Hash returns the 64-bit SipHash-2-4 of the given byte slice with two 64-bit
13// parts of 128-bit key: k0 and k1.
14func Hash(k0, k1 uint64, p []byte) uint64 {
15	// Initialization.
16	v0 := k0 ^ 0x736f6d6570736575
17	v1 := k1 ^ 0x646f72616e646f6d
18	v2 := k0 ^ 0x6c7967656e657261
19	v3 := k1 ^ 0x7465646279746573
20	t := uint64(len(p)) << 56
21
22	// Compression.
23	for len(p) >= BlockSize {
24		m := uint64(p[0]) | uint64(p[1])<<8 | uint64(p[2])<<16 | uint64(p[3])<<24 |
25			uint64(p[4])<<32 | uint64(p[5])<<40 | uint64(p[6])<<48 | uint64(p[7])<<56
26		v3 ^= m
27
28		// Round 1.
29		v0 += v1
30		v1 = v1<<13 | v1>>(64-13)
31		v1 ^= v0
32		v0 = v0<<32 | v0>>(64-32)
33
34		v2 += v3
35		v3 = v3<<16 | v3>>(64-16)
36		v3 ^= v2
37
38		v0 += v3
39		v3 = v3<<21 | v3>>(64-21)
40		v3 ^= v0
41
42		v2 += v1
43		v1 = v1<<17 | v1>>(64-17)
44		v1 ^= v2
45		v2 = v2<<32 | v2>>(64-32)
46
47		// Round 2.
48		v0 += v1
49		v1 = v1<<13 | v1>>(64-13)
50		v1 ^= v0
51		v0 = v0<<32 | v0>>(64-32)
52
53		v2 += v3
54		v3 = v3<<16 | v3>>(64-16)
55		v3 ^= v2
56
57		v0 += v3
58		v3 = v3<<21 | v3>>(64-21)
59		v3 ^= v0
60
61		v2 += v1
62		v1 = v1<<17 | v1>>(64-17)
63		v1 ^= v2
64		v2 = v2<<32 | v2>>(64-32)
65
66		v0 ^= m
67		p = p[BlockSize:]
68	}
69
70	// Compress last block.
71	switch len(p) {
72	case 7:
73		t |= uint64(p[6]) << 48
74		fallthrough
75	case 6:
76		t |= uint64(p[5]) << 40
77		fallthrough
78	case 5:
79		t |= uint64(p[4]) << 32
80		fallthrough
81	case 4:
82		t |= uint64(p[3]) << 24
83		fallthrough
84	case 3:
85		t |= uint64(p[2]) << 16
86		fallthrough
87	case 2:
88		t |= uint64(p[1]) << 8
89		fallthrough
90	case 1:
91		t |= uint64(p[0])
92	}
93
94	v3 ^= t
95
96	// Round 1.
97	v0 += v1
98	v1 = v1<<13 | v1>>(64-13)
99	v1 ^= v0
100	v0 = v0<<32 | v0>>(64-32)
101
102	v2 += v3
103	v3 = v3<<16 | v3>>(64-16)
104	v3 ^= v2
105
106	v0 += v3
107	v3 = v3<<21 | v3>>(64-21)
108	v3 ^= v0
109
110	v2 += v1
111	v1 = v1<<17 | v1>>(64-17)
112	v1 ^= v2
113	v2 = v2<<32 | v2>>(64-32)
114
115	// Round 2.
116	v0 += v1
117	v1 = v1<<13 | v1>>(64-13)
118	v1 ^= v0
119	v0 = v0<<32 | v0>>(64-32)
120
121	v2 += v3
122	v3 = v3<<16 | v3>>(64-16)
123	v3 ^= v2
124
125	v0 += v3
126	v3 = v3<<21 | v3>>(64-21)
127	v3 ^= v0
128
129	v2 += v1
130	v1 = v1<<17 | v1>>(64-17)
131	v1 ^= v2
132	v2 = v2<<32 | v2>>(64-32)
133
134	v0 ^= t
135
136	// Finalization.
137	v2 ^= 0xff
138
139	// Round 1.
140	v0 += v1
141	v1 = v1<<13 | v1>>(64-13)
142	v1 ^= v0
143	v0 = v0<<32 | v0>>(64-32)
144
145	v2 += v3
146	v3 = v3<<16 | v3>>(64-16)
147	v3 ^= v2
148
149	v0 += v3
150	v3 = v3<<21 | v3>>(64-21)
151	v3 ^= v0
152
153	v2 += v1
154	v1 = v1<<17 | v1>>(64-17)
155	v1 ^= v2
156	v2 = v2<<32 | v2>>(64-32)
157
158	// Round 2.
159	v0 += v1
160	v1 = v1<<13 | v1>>(64-13)
161	v1 ^= v0
162	v0 = v0<<32 | v0>>(64-32)
163
164	v2 += v3
165	v3 = v3<<16 | v3>>(64-16)
166	v3 ^= v2
167
168	v0 += v3
169	v3 = v3<<21 | v3>>(64-21)
170	v3 ^= v0
171
172	v2 += v1
173	v1 = v1<<17 | v1>>(64-17)
174	v1 ^= v2
175	v2 = v2<<32 | v2>>(64-32)
176
177	// Round 3.
178	v0 += v1
179	v1 = v1<<13 | v1>>(64-13)
180	v1 ^= v0
181	v0 = v0<<32 | v0>>(64-32)
182
183	v2 += v3
184	v3 = v3<<16 | v3>>(64-16)
185	v3 ^= v2
186
187	v0 += v3
188	v3 = v3<<21 | v3>>(64-21)
189	v3 ^= v0
190
191	v2 += v1
192	v1 = v1<<17 | v1>>(64-17)
193	v1 ^= v2
194	v2 = v2<<32 | v2>>(64-32)
195
196	// Round 4.
197	v0 += v1
198	v1 = v1<<13 | v1>>(64-13)
199	v1 ^= v0
200	v0 = v0<<32 | v0>>(64-32)
201
202	v2 += v3
203	v3 = v3<<16 | v3>>(64-16)
204	v3 ^= v2
205
206	v0 += v3
207	v3 = v3<<21 | v3>>(64-21)
208	v3 ^= v0
209
210	v2 += v1
211	v1 = v1<<17 | v1>>(64-17)
212	v1 ^= v2
213	v2 = v2<<32 | v2>>(64-32)
214
215	return v0 ^ v1 ^ v2 ^ v3
216}
217