diff options
Diffstat (limited to 'vendor/github.com/dchest/siphash/siphash.go')
-rw-r--r-- | vendor/github.com/dchest/siphash/siphash.go | 318 |
1 files changed, 318 insertions, 0 deletions
diff --git a/vendor/github.com/dchest/siphash/siphash.go b/vendor/github.com/dchest/siphash/siphash.go new file mode 100644 index 0000000..4a3cb49 --- /dev/null +++ b/vendor/github.com/dchest/siphash/siphash.go @@ -0,0 +1,318 @@ +// Written in 2012-2014 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 siphash + +import "hash" + +const ( + // BlockSize is the block size of hash algorithm in bytes. + BlockSize = 8 + + // Size is the size of hash output in bytes. + Size = 8 + + // Size128 is the size of 128-bit hash output in bytes. + Size128 = 16 +) + +type digest struct { + v0, v1, v2, v3 uint64 // state + k0, k1 uint64 // two parts of key + x [8]byte // buffer for unprocessed bytes + nx int // number of bytes in buffer x + size int // output size in bytes (8 or 16) + t uint8 // message bytes counter (mod 256) +} + +// newDigest returns a new digest with the given output size in bytes (must be 8 or 16). +func newDigest(size int, key []byte) *digest { + if size != Size && size != Size128 { + panic("size must be 8 or 16") + } + d := new(digest) + d.k0 = uint64(key[0]) | uint64(key[1])<<8 | uint64(key[2])<<16 | uint64(key[3])<<24 | + uint64(key[4])<<32 | uint64(key[5])<<40 | uint64(key[6])<<48 | uint64(key[7])<<56 + d.k1 = uint64(key[8]) | uint64(key[9])<<8 | uint64(key[10])<<16 | uint64(key[11])<<24 | + uint64(key[12])<<32 | uint64(key[13])<<40 | uint64(key[14])<<48 | uint64(key[15])<<56 + d.size = size + d.Reset() + return d +} + +// New returns a new hash.Hash64 computing SipHash-2-4 with 16-byte key and 8-byte output. +func New(key []byte) hash.Hash64 { + return newDigest(Size, key) +} + +// New128 returns a new hash.Hash computing SipHash-2-4 with 16-byte key and 16-byte output. +// +// Note that 16-byte output is considered experimental by SipHash authors at this time. +func New128(key []byte) hash.Hash { + return newDigest(Size128, key) +} + +func (d *digest) Reset() { + d.v0 = d.k0 ^ 0x736f6d6570736575 + d.v1 = d.k1 ^ 0x646f72616e646f6d + d.v2 = d.k0 ^ 0x6c7967656e657261 + d.v3 = d.k1 ^ 0x7465646279746573 + d.t = 0 + d.nx = 0 + if d.size == Size128 { + d.v1 ^= 0xee + } +} + +func (d *digest) Size() int { return d.size } + +func (d *digest) BlockSize() int { return BlockSize } + +func (d *digest) Write(p []byte) (nn int, err error) { + nn = len(p) + d.t += uint8(nn) + if d.nx > 0 { + n := len(p) + if n > BlockSize-d.nx { + n = BlockSize - d.nx + } + d.nx += copy(d.x[d.nx:], p) + if d.nx == BlockSize { + once(d) + d.nx = 0 + } + p = p[n:] + } + if len(p) >= BlockSize { + n := len(p) &^ (BlockSize - 1) + blocks(d, p[:n]) + p = p[n:] + } + if len(p) > 0 { + d.nx = copy(d.x[:], p) + } + return +} + +func (d *digest) Sum64() uint64 { + for i := d.nx; i < BlockSize-1; i++ { + d.x[i] = 0 + } + d.x[7] = d.t + return finalize(d) +} + +func (d0 *digest) sum128() (r0, r1 uint64) { + // Make a copy of d0 so that caller can keep writing and summing. + d := *d0 + + for i := d.nx; i < BlockSize-1; i++ { + d.x[i] = 0 + } + d.x[7] = d.t + blocks(&d, d.x[:]) + + v0, v1, v2, v3 := d.v0, d.v1, d.v2, d.v3 + v2 ^= 0xee + + // Round 1. + v0 += v1 + v1 = v1<<13 | v1>>(64-13) + v1 ^= v0 + v0 = v0<<32 | v0>>(64-32) + + v2 += v3 + v3 = v3<<16 | v3>>(64-16) + v3 ^= v2 + + v0 += v3 + v3 = v3<<21 | v3>>(64-21) + v3 ^= v0 + + v2 += v1 + v1 = v1<<17 | v1>>(64-17) + v1 ^= v2 + v2 = v2<<32 | v2>>(64-32) + + // Round 2. + v0 += v1 + v1 = v1<<13 | v1>>(64-13) + v1 ^= v0 + v0 = v0<<32 | v0>>(64-32) + + v2 += v3 + v3 = v3<<16 | v3>>(64-16) + v3 ^= v2 + + v0 += v3 + v3 = v3<<21 | v3>>(64-21) + v3 ^= v0 + + v2 += v1 + v1 = v1<<17 | v1>>(64-17) + v1 ^= v2 + v2 = v2<<32 | v2>>(64-32) + + // Round 3. + v0 += v1 + v1 = v1<<13 | v1>>(64-13) + v1 ^= v0 + v0 = v0<<32 | v0>>(64-32) + + v2 += v3 + v3 = v3<<16 | v3>>(64-16) + v3 ^= v2 + + v0 += v3 + v3 = v3<<21 | v3>>(64-21) + v3 ^= v0 + + v2 += v1 + v1 = v1<<17 | v1>>(64-17) + v1 ^= v2 + v2 = v2<<32 | v2>>(64-32) + + // Round 4. + v0 += v1 + v1 = v1<<13 | v1>>(64-13) + v1 ^= v0 + v0 = v0<<32 | v0>>(64-32) + + v2 += v3 + v3 = v3<<16 | v3>>(64-16) + v3 ^= v2 + + v0 += v3 + v3 = v3<<21 | v3>>(64-21) + v3 ^= v0 + + v2 += v1 + v1 = v1<<17 | v1>>(64-17) + v1 ^= v2 + v2 = v2<<32 | v2>>(64-32) + + r0 = v0 ^ v1 ^ v2 ^ v3 + + v1 ^= 0xdd + + // Round 1. + v0 += v1 + v1 = v1<<13 | v1>>(64-13) + v1 ^= v0 + v0 = v0<<32 | v0>>(64-32) + + v2 += v3 + v3 = v3<<16 | v3>>(64-16) + v3 ^= v2 + + v0 += v3 + v3 = v3<<21 | v3>>(64-21) + v3 ^= v0 + + v2 += v1 + v1 = v1<<17 | v1>>(64-17) + v1 ^= v2 + v2 = v2<<32 | v2>>(64-32) + + // Round 2. + v0 += v1 + v1 = v1<<13 | v1>>(64-13) + v1 ^= v0 + v0 = v0<<32 | v0>>(64-32) + + v2 += v3 + v3 = v3<<16 | v3>>(64-16) + v3 ^= v2 + + v0 += v3 + v3 = v3<<21 | v3>>(64-21) + v3 ^= v0 + + v2 += v1 + v1 = v1<<17 | v1>>(64-17) + v1 ^= v2 + v2 = v2<<32 | v2>>(64-32) + + // Round 3. + v0 += v1 + v1 = v1<<13 | v1>>(64-13) + v1 ^= v0 + v0 = v0<<32 | v0>>(64-32) + + v2 += v3 + v3 = v3<<16 | v3>>(64-16) + v3 ^= v2 + + v0 += v3 + v3 = v3<<21 | v3>>(64-21) + v3 ^= v0 + + v2 += v1 + v1 = v1<<17 | v1>>(64-17) + v1 ^= v2 + v2 = v2<<32 | v2>>(64-32) + + // Round 4. + v0 += v1 + v1 = v1<<13 | v1>>(64-13) + v1 ^= v0 + v0 = v0<<32 | v0>>(64-32) + + v2 += v3 + v3 = v3<<16 | v3>>(64-16) + v3 ^= v2 + + v0 += v3 + v3 = v3<<21 | v3>>(64-21) + v3 ^= v0 + + v2 += v1 + v1 = v1<<17 | v1>>(64-17) + v1 ^= v2 + v2 = v2<<32 | v2>>(64-32) + + r1 = v0 ^ v1 ^ v2 ^ v3 + + return r0, r1 +} + +func (d *digest) Sum(in []byte) []byte { + if d.size == Size { + r := d.Sum64() + in = append(in, + byte(r), + byte(r>>8), + byte(r>>16), + byte(r>>24), + byte(r>>32), + byte(r>>40), + byte(r>>48), + byte(r>>56)) + } else { + r0, r1 := d.sum128() + in = append(in, + byte(r0), + byte(r0>>8), + byte(r0>>16), + byte(r0>>24), + byte(r0>>32), + byte(r0>>40), + byte(r0>>48), + byte(r0>>56), + byte(r1), + byte(r1>>8), + byte(r1>>16), + byte(r1>>24), + byte(r1>>32), + byte(r1>>40), + byte(r1>>48), + byte(r1>>56)) + } + return in +} |