1// +build !arm,!amd64 appengine gccgo
2// Written in 2012 by Dmitry Chestnykh.
3// Modifications 2014 for 128-bit hash function by Damian Gryski.
4//
5// To the extent possible under law, the authors 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 128-bit SipHash-2-4 of the given byte slice with two 64-bit
13// parts of 128-bit key: k0 and k1.
14//
15// Note that 128-bit SipHash is considered experimental by SipHash authors at this time.
16func Hash128(k0, k1 uint64, p []byte) (uint64, uint64) {
17	// Initialization.
18	v0 := k0 ^ 0x736f6d6570736575
19	v1 := k1 ^ 0x646f72616e646f6d
20	v2 := k0 ^ 0x6c7967656e657261
21	v3 := k1 ^ 0x7465646279746573
22	t := uint64(len(p)) << 56
23
24	v1 ^= 0xee
25
26	// Compression.
27	for len(p) >= BlockSize {
28		m := uint64(p[0]) | uint64(p[1])<<8 | uint64(p[2])<<16 | uint64(p[3])<<24 |
29			uint64(p[4])<<32 | uint64(p[5])<<40 | uint64(p[6])<<48 | uint64(p[7])<<56
30		v3 ^= m
31
32		// Round 1.
33		v0 += v1
34		v1 = v1<<13 | v1>>(64-13)
35		v1 ^= v0
36		v0 = v0<<32 | v0>>(64-32)
37
38		v2 += v3
39		v3 = v3<<16 | v3>>(64-16)
40		v3 ^= v2
41
42		v0 += v3
43		v3 = v3<<21 | v3>>(64-21)
44		v3 ^= v0
45
46		v2 += v1
47		v1 = v1<<17 | v1>>(64-17)
48		v1 ^= v2
49		v2 = v2<<32 | v2>>(64-32)
50
51		// Round 2.
52		v0 += v1
53		v1 = v1<<13 | v1>>(64-13)
54		v1 ^= v0
55		v0 = v0<<32 | v0>>(64-32)
56
57		v2 += v3
58		v3 = v3<<16 | v3>>(64-16)
59		v3 ^= v2
60
61		v0 += v3
62		v3 = v3<<21 | v3>>(64-21)
63		v3 ^= v0
64
65		v2 += v1
66		v1 = v1<<17 | v1>>(64-17)
67		v1 ^= v2
68		v2 = v2<<32 | v2>>(64-32)
69
70		v0 ^= m
71		p = p[BlockSize:]
72	}
73
74	// Compress last block.
75	switch len(p) {
76	case 7:
77		t |= uint64(p[6]) << 48
78		fallthrough
79	case 6:
80		t |= uint64(p[5]) << 40
81		fallthrough
82	case 5:
83		t |= uint64(p[4]) << 32
84		fallthrough
85	case 4:
86		t |= uint64(p[3]) << 24
87		fallthrough
88	case 3:
89		t |= uint64(p[2]) << 16
90		fallthrough
91	case 2:
92		t |= uint64(p[1]) << 8
93		fallthrough
94	case 1:
95		t |= uint64(p[0])
96	}
97
98	v3 ^= t
99
100	// Round 1.
101	v0 += v1
102	v1 = v1<<13 | v1>>(64-13)
103	v1 ^= v0
104	v0 = v0<<32 | v0>>(64-32)
105
106	v2 += v3
107	v3 = v3<<16 | v3>>(64-16)
108	v3 ^= v2
109
110	v0 += v3
111	v3 = v3<<21 | v3>>(64-21)
112	v3 ^= v0
113
114	v2 += v1
115	v1 = v1<<17 | v1>>(64-17)
116	v1 ^= v2
117	v2 = v2<<32 | v2>>(64-32)
118
119	// Round 2.
120	v0 += v1
121	v1 = v1<<13 | v1>>(64-13)
122	v1 ^= v0
123	v0 = v0<<32 | v0>>(64-32)
124
125	v2 += v3
126	v3 = v3<<16 | v3>>(64-16)
127	v3 ^= v2
128
129	v0 += v3
130	v3 = v3<<21 | v3>>(64-21)
131	v3 ^= v0
132
133	v2 += v1
134	v1 = v1<<17 | v1>>(64-17)
135	v1 ^= v2
136	v2 = v2<<32 | v2>>(64-32)
137
138	v0 ^= t
139
140	// Finalization.
141	v2 ^= 0xee
142
143	// Round 1.
144	v0 += v1
145	v1 = v1<<13 | v1>>(64-13)
146	v1 ^= v0
147	v0 = v0<<32 | v0>>(64-32)
148
149	v2 += v3
150	v3 = v3<<16 | v3>>(64-16)
151	v3 ^= v2
152
153	v0 += v3
154	v3 = v3<<21 | v3>>(64-21)
155	v3 ^= v0
156
157	v2 += v1
158	v1 = v1<<17 | v1>>(64-17)
159	v1 ^= v2
160	v2 = v2<<32 | v2>>(64-32)
161
162	// Round 2.
163	v0 += v1
164	v1 = v1<<13 | v1>>(64-13)
165	v1 ^= v0
166	v0 = v0<<32 | v0>>(64-32)
167
168	v2 += v3
169	v3 = v3<<16 | v3>>(64-16)
170	v3 ^= v2
171
172	v0 += v3
173	v3 = v3<<21 | v3>>(64-21)
174	v3 ^= v0
175
176	v2 += v1
177	v1 = v1<<17 | v1>>(64-17)
178	v1 ^= v2
179	v2 = v2<<32 | v2>>(64-32)
180
181	// Round 3.
182	v0 += v1
183	v1 = v1<<13 | v1>>(64-13)
184	v1 ^= v0
185	v0 = v0<<32 | v0>>(64-32)
186
187	v2 += v3
188	v3 = v3<<16 | v3>>(64-16)
189	v3 ^= v2
190
191	v0 += v3
192	v3 = v3<<21 | v3>>(64-21)
193	v3 ^= v0
194
195	v2 += v1
196	v1 = v1<<17 | v1>>(64-17)
197	v1 ^= v2
198	v2 = v2<<32 | v2>>(64-32)
199
200	// Round 4.
201	v0 += v1
202	v1 = v1<<13 | v1>>(64-13)
203	v1 ^= v0
204	v0 = v0<<32 | v0>>(64-32)
205
206	v2 += v3
207	v3 = v3<<16 | v3>>(64-16)
208	v3 ^= v2
209
210	v0 += v3
211	v3 = v3<<21 | v3>>(64-21)
212	v3 ^= v0
213
214	v2 += v1
215	v1 = v1<<17 | v1>>(64-17)
216	v1 ^= v2
217	v2 = v2<<32 | v2>>(64-32)
218
219	r0 := v0 ^ v1 ^ v2 ^ v3
220
221	v1 ^= 0xdd
222
223	// Round 1.
224	v0 += v1
225	v1 = v1<<13 | v1>>(64-13)
226	v1 ^= v0
227	v0 = v0<<32 | v0>>(64-32)
228
229	v2 += v3
230	v3 = v3<<16 | v3>>(64-16)
231	v3 ^= v2
232
233	v0 += v3
234	v3 = v3<<21 | v3>>(64-21)
235	v3 ^= v0
236
237	v2 += v1
238	v1 = v1<<17 | v1>>(64-17)
239	v1 ^= v2
240	v2 = v2<<32 | v2>>(64-32)
241
242	// Round 2.
243	v0 += v1
244	v1 = v1<<13 | v1>>(64-13)
245	v1 ^= v0
246	v0 = v0<<32 | v0>>(64-32)
247
248	v2 += v3
249	v3 = v3<<16 | v3>>(64-16)
250	v3 ^= v2
251
252	v0 += v3
253	v3 = v3<<21 | v3>>(64-21)
254	v3 ^= v0
255
256	v2 += v1
257	v1 = v1<<17 | v1>>(64-17)
258	v1 ^= v2
259	v2 = v2<<32 | v2>>(64-32)
260
261	// Round 3.
262	v0 += v1
263	v1 = v1<<13 | v1>>(64-13)
264	v1 ^= v0
265	v0 = v0<<32 | v0>>(64-32)
266
267	v2 += v3
268	v3 = v3<<16 | v3>>(64-16)
269	v3 ^= v2
270
271	v0 += v3
272	v3 = v3<<21 | v3>>(64-21)
273	v3 ^= v0
274
275	v2 += v1
276	v1 = v1<<17 | v1>>(64-17)
277	v1 ^= v2
278	v2 = v2<<32 | v2>>(64-32)
279
280	// Round 4.
281	v0 += v1
282	v1 = v1<<13 | v1>>(64-13)
283	v1 ^= v0
284	v0 = v0<<32 | v0>>(64-32)
285
286	v2 += v3
287	v3 = v3<<16 | v3>>(64-16)
288	v3 ^= v2
289
290	v0 += v3
291	v3 = v3<<21 | v3>>(64-21)
292	v3 ^= v0
293
294	v2 += v1
295	v1 = v1<<17 | v1>>(64-17)
296	v1 ^= v2
297	v2 = v2<<32 | v2>>(64-32)
298
299	r1 := v0 ^ v1 ^ v2 ^ v3
300
301	return r0, r1
302}
303