123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225 |
- // Written in 2012 by Dmitry Chestnykh.
- //
- // To the extent possible under law, the author have dedicated all copyright
- // and related and neighboring rights to this software to the public domain
- // worldwide. This software is distributed without any warranty.
- // http://creativecommons.org/publicdomain/zero/1.0/
- //
- // Package siphash implements SipHash-2-4, a fast short-input PRF
- // created by Jean-Philippe Aumasson and Daniel J. Bernstein.
- package bbloom
- // Hash returns the 64-bit SipHash-2-4 of the given byte slice with two 64-bit
- // parts of 128-bit key: k0 and k1.
- func (bl Bloom) sipHash(p []byte) (l, h uint64) {
- // Initialization.
- v0 := uint64(8317987320269560794) // k0 ^ 0x736f6d6570736575
- v1 := uint64(7237128889637516672) // k1 ^ 0x646f72616e646f6d
- v2 := uint64(7816392314733513934) // k0 ^ 0x6c7967656e657261
- v3 := uint64(8387220255325274014) // k1 ^ 0x7465646279746573
- t := uint64(len(p)) << 56
- // Compression.
- for len(p) >= 8 {
- m := uint64(p[0]) | uint64(p[1])<<8 | uint64(p[2])<<16 | uint64(p[3])<<24 |
- uint64(p[4])<<32 | uint64(p[5])<<40 | uint64(p[6])<<48 | uint64(p[7])<<56
- v3 ^= m
- // Round 1.
- v0 += v1
- v1 = v1<<13 | v1>>51
- v1 ^= v0
- v0 = v0<<32 | v0>>32
- v2 += v3
- v3 = v3<<16 | v3>>48
- v3 ^= v2
- v0 += v3
- v3 = v3<<21 | v3>>43
- v3 ^= v0
- v2 += v1
- v1 = v1<<17 | v1>>47
- v1 ^= v2
- v2 = v2<<32 | v2>>32
- // Round 2.
- v0 += v1
- v1 = v1<<13 | v1>>51
- v1 ^= v0
- v0 = v0<<32 | v0>>32
- v2 += v3
- v3 = v3<<16 | v3>>48
- v3 ^= v2
- v0 += v3
- v3 = v3<<21 | v3>>43
- v3 ^= v0
- v2 += v1
- v1 = v1<<17 | v1>>47
- v1 ^= v2
- v2 = v2<<32 | v2>>32
- v0 ^= m
- p = p[8:]
- }
- // Compress last block.
- switch len(p) {
- case 7:
- t |= uint64(p[6]) << 48
- fallthrough
- case 6:
- t |= uint64(p[5]) << 40
- fallthrough
- case 5:
- t |= uint64(p[4]) << 32
- fallthrough
- case 4:
- t |= uint64(p[3]) << 24
- fallthrough
- case 3:
- t |= uint64(p[2]) << 16
- fallthrough
- case 2:
- t |= uint64(p[1]) << 8
- fallthrough
- case 1:
- t |= uint64(p[0])
- }
- v3 ^= t
- // Round 1.
- v0 += v1
- v1 = v1<<13 | v1>>51
- v1 ^= v0
- v0 = v0<<32 | v0>>32
- v2 += v3
- v3 = v3<<16 | v3>>48
- v3 ^= v2
- v0 += v3
- v3 = v3<<21 | v3>>43
- v3 ^= v0
- v2 += v1
- v1 = v1<<17 | v1>>47
- v1 ^= v2
- v2 = v2<<32 | v2>>32
- // Round 2.
- v0 += v1
- v1 = v1<<13 | v1>>51
- v1 ^= v0
- v0 = v0<<32 | v0>>32
- v2 += v3
- v3 = v3<<16 | v3>>48
- v3 ^= v2
- v0 += v3
- v3 = v3<<21 | v3>>43
- v3 ^= v0
- v2 += v1
- v1 = v1<<17 | v1>>47
- v1 ^= v2
- v2 = v2<<32 | v2>>32
- v0 ^= t
- // Finalization.
- v2 ^= 0xff
- // Round 1.
- v0 += v1
- v1 = v1<<13 | v1>>51
- v1 ^= v0
- v0 = v0<<32 | v0>>32
- v2 += v3
- v3 = v3<<16 | v3>>48
- v3 ^= v2
- v0 += v3
- v3 = v3<<21 | v3>>43
- v3 ^= v0
- v2 += v1
- v1 = v1<<17 | v1>>47
- v1 ^= v2
- v2 = v2<<32 | v2>>32
- // Round 2.
- v0 += v1
- v1 = v1<<13 | v1>>51
- v1 ^= v0
- v0 = v0<<32 | v0>>32
- v2 += v3
- v3 = v3<<16 | v3>>48
- v3 ^= v2
- v0 += v3
- v3 = v3<<21 | v3>>43
- v3 ^= v0
- v2 += v1
- v1 = v1<<17 | v1>>47
- v1 ^= v2
- v2 = v2<<32 | v2>>32
- // Round 3.
- v0 += v1
- v1 = v1<<13 | v1>>51
- v1 ^= v0
- v0 = v0<<32 | v0>>32
- v2 += v3
- v3 = v3<<16 | v3>>48
- v3 ^= v2
- v0 += v3
- v3 = v3<<21 | v3>>43
- v3 ^= v0
- v2 += v1
- v1 = v1<<17 | v1>>47
- v1 ^= v2
- v2 = v2<<32 | v2>>32
- // Round 4.
- v0 += v1
- v1 = v1<<13 | v1>>51
- v1 ^= v0
- v0 = v0<<32 | v0>>32
- v2 += v3
- v3 = v3<<16 | v3>>48
- v3 ^= v2
- v0 += v3
- v3 = v3<<21 | v3>>43
- v3 ^= v0
- v2 += v1
- v1 = v1<<17 | v1>>47
- v1 ^= v2
- v2 = v2<<32 | v2>>32
- // return v0 ^ v1 ^ v2 ^ v3
- hash := v0 ^ v1 ^ v2 ^ v3
- h = hash >> bl.shift
- l = hash << bl.shift >> bl.shift
- return l, h
- }
|