[Pkg-privacy-commits] [golang-siphash-dev] 08/23: Add Hash() function for better speed and simplicity.

Ximin Luo infinity0 at moszumanska.debian.org
Sat Aug 22 12:55:53 UTC 2015


This is an automated email from the git hooks/post-receive script.

infinity0 pushed a commit to branch master
in repository golang-siphash-dev.

commit d314cd26fe2dfccbe4660aa80ee2d1588191731a
Author: Dmitry Chestnykh <dmitry at codingrobots.com>
Date:   Thu Jun 21 15:36:02 2012 +0200

    Add Hash() function for better speed and simplicity.
---
 hash.go         | 108 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++
 siphash_test.go |  73 ++++++++++++++++++++++++++++++++++----
 2 files changed, 175 insertions(+), 6 deletions(-)

diff --git a/hash.go b/hash.go
new file mode 100644
index 0000000..86e4912
--- /dev/null
+++ b/hash.go
@@ -0,0 +1,108 @@
+package siphash
+
+// 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 Hash(k0, k1 uint64, p []byte) uint64 {
+	// Initialization.
+	v0 := k0 ^ 0x736f6d6570736575
+	v1 := k1 ^ 0x646f72616e646f6d
+	v2 := k0 ^ 0x6c7967656e657261
+	v3 := k1 ^ 0x7465646279746573
+	t := uint64(len(p)) << 56
+
+	// Compression.
+	for len(p) >= BlockSize {
+		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
+		for i := 0; i < CRounds; i++ {
+			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)
+		}
+		v0 ^= m
+		p = p[BlockSize:]
+	}
+
+	// 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
+	for i := 0; i < CRounds; i++ {
+		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)
+	}
+	v0 ^= t
+
+	// Finalization.
+	v2 ^= 0xff
+	for i := 0; i < DRounds; i++ {
+		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)
+	}
+	return v0 ^ v1 ^ v2 ^ v3
+}
diff --git a/siphash_test.go b/siphash_test.go
index 7873b53..e7f5a10 100644
--- a/siphash_test.go
+++ b/siphash_test.go
@@ -67,20 +67,81 @@ func TestSum(t *testing.T) {
 	}
 }
 
+func TestHash(t *testing.T) {
+	var k0, k1 uint64
+	for i, v := range golden {
+		k0 = binary.LittleEndian.Uint64(v.k[0:8])
+		k1 = binary.LittleEndian.Uint64(v.k[8:16])
+		if sum := Hash(k0, k1, v.m); sum != v.r {
+			t.Errorf(`%d: expected "%x", got "%x"`, i, v.r, sum)
+		}
+	}
+}
+
 var key = zeroKey
+var key0, key1 uint64
 var bench = New(key)
 var buf = make([]byte, 8<<10)
 
 func BenchmarkHash8(b *testing.B) {
 	b.SetBytes(8)
 	for i := 0; i < b.N; i++ {
+		Hash(key0, key1, buf[:8])
+	}
+}
+
+func BenchmarkHash16(b *testing.B) {
+	b.SetBytes(16)
+	for i := 0; i < b.N; i++ {
+		Hash(key0, key1, buf[:16])
+	}
+}
+
+func BenchmarkHash40(b *testing.B) {
+	b.SetBytes(40)
+	for i := 0; i < b.N; i++ {
+		Hash(key0, key1, buf[:40])
+	}
+}
+
+func BenchmarkHash64(b *testing.B) {
+	b.SetBytes(64)
+	for i := 0; i < b.N; i++ {
+		Hash(key0, key1, buf[:64])
+	}
+}
+
+func BenchmarkHash128(b *testing.B) {
+	b.SetBytes(128)
+	for i := 0; i < b.N; i++ {
+		Hash(key0, key1, buf[:128])
+	}
+}
+
+func BenchmarkHash1K(b *testing.B) {
+	b.SetBytes(1024)
+	for i := 0; i < b.N; i++ {
+		Hash(key0, key1, buf[:1024])
+	}
+}
+
+func BenchmarkHash8K(b *testing.B) {
+	b.SetBytes(int64(len(buf)))
+	for i := 0; i < b.N; i++ {
+		Hash(key0, key1, buf)
+	}
+}
+
+func BenchmarkFull8(b *testing.B) {
+	b.SetBytes(8)
+	for i := 0; i < b.N; i++ {
 		bench.Reset()
 		bench.Write(buf[:8])
 		bench.Sum64()
 	}
 }
 
-func BenchmarkHash16(b *testing.B) {
+func BenchmarkFull16(b *testing.B) {
 	b.SetBytes(16)
 	for i := 0; i < b.N; i++ {
 		bench.Reset()
@@ -89,7 +150,7 @@ func BenchmarkHash16(b *testing.B) {
 	}
 }
 
-func BenchmarkHash40(b *testing.B) {
+func BenchmarkFull40(b *testing.B) {
 	b.SetBytes(24)
 	for i := 0; i < b.N; i++ {
 		bench.Reset()
@@ -98,7 +159,7 @@ func BenchmarkHash40(b *testing.B) {
 	}
 }
 
-func BenchmarkHash64(b *testing.B) {
+func BenchmarkFull64(b *testing.B) {
 	b.SetBytes(64)
 	for i := 0; i < b.N; i++ {
 		bench.Reset()
@@ -107,7 +168,7 @@ func BenchmarkHash64(b *testing.B) {
 	}
 }
 
-func BenchmarkHash128(b *testing.B) {
+func BenchmarkFull128(b *testing.B) {
 	b.SetBytes(128)
 	for i := 0; i < b.N; i++ {
 		bench.Reset()
@@ -116,7 +177,7 @@ func BenchmarkHash128(b *testing.B) {
 	}
 }
 
-func BenchmarkHash1K(b *testing.B) {
+func BenchmarkFull1K(b *testing.B) {
 	b.SetBytes(1024)
 	for i := 0; i < b.N; i++ {
 		bench.Reset()
@@ -125,7 +186,7 @@ func BenchmarkHash1K(b *testing.B) {
 	}
 }
 
-func BenchmarkHash8K(b *testing.B) {
+func BenchmarkFull8K(b *testing.B) {
 	b.SetBytes(int64(len(buf)))
 	for i := 0; i < b.N; i++ {
 		bench.Reset()

-- 
Alioth's /usr/local/bin/git-commit-notice on /srv/git.debian.org/git/pkg-privacy/packages/golang-siphash-dev.git



More information about the Pkg-privacy-commits mailing list