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