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