├── keccak ├── KeccakF-1600-opt64-settings.h ├── KeccakF-1600-int-set.h ├── LICENSE ├── README.md ├── keccak.go ├── KeccakF-1600-interface.h ├── KeccakNISTInterface.c ├── KeccakSponge.h ├── KeccakNISTInterface.h ├── KeccakF-1600-unrolling.macros.h ├── brg_endian.h ├── keccak_test.go └── KeccakSponge.c ├── gomap ├── add.go ├── unaligned1.go ├── unaligned2.go ├── hash32.go └── hash64.go ├── threefish ├── Makefile └── threefish.go ├── go.mod ├── farm ├── README ├── bench_test.go ├── basics.go ├── platform.go ├── COPYING ├── farmhashmk.go ├── farmhashuo.go ├── gitlog.txt ├── farmhashna.go ├── farmhashcc.go └── farm_test.go ├── .gitignore ├── metro ├── gitlog.txt ├── README ├── metro_test.go ├── metro64.go └── metro128.go ├── siphash ├── hash_asm.go ├── README.md ├── hash_amd64.s ├── hash.go ├── hash128_amd64.s ├── hash128.go └── siphash.go ├── LICENSE ├── murmur3 ├── murmur64.go ├── LICENSE ├── murmur.go ├── murmur32.go ├── murmur128.go ├── README.md └── murmur_test.go ├── nullhash └── nullhash.go ├── go.sum ├── mahash └── mahash8v64.go ├── crapwow └── crapwow.go ├── nhash └── nhash.go ├── sbox └── sbox.go ├── keccakpg ├── keccak.go └── keccak_test.go ├── siphashpg └── siphash.go ├── jenkins └── jenkins_test.go └── hashtable └── hashtable.go /keccak/KeccakF-1600-opt64-settings.h: -------------------------------------------------------------------------------- 1 | #define Unrolling 24 2 | #define UseBebigokimisa 3 | //#define UseSSE 4 | //#define UseOnlySIMD64 5 | //#define UseMMX 6 | -------------------------------------------------------------------------------- /gomap/add.go: -------------------------------------------------------------------------------- 1 | package gomap 2 | 3 | import "unsafe" 4 | 5 | func add(p unsafe.Pointer, amt int) unsafe.Pointer { 6 | return unsafe.Pointer(uintptr(p) + uintptr(amt)) 7 | } -------------------------------------------------------------------------------- /keccak/KeccakF-1600-int-set.h: -------------------------------------------------------------------------------- 1 | #define ProvideFast576 2 | #define ProvideFast832 3 | #define ProvideFast1024 4 | #define ProvideFast1088 5 | #define ProvideFast1152 6 | #define ProvideFast1344 7 | -------------------------------------------------------------------------------- /threefish/Makefile: -------------------------------------------------------------------------------- 1 | include $(GOROOT)/src/Make.inc 2 | 3 | TARG=crypto/threefish 4 | GOFILES= \ 5 | threefish.go \ 6 | threefish256.go \ 7 | threefish512.go \ 8 | threefish1024.go 9 | 10 | include $(GOROOT)/src/Make.pkg 11 | -------------------------------------------------------------------------------- /go.mod: -------------------------------------------------------------------------------- 1 | module leb.io/hashland 2 | 3 | go 1.16 4 | 5 | require ( 6 | github.com/jzelinskie/whirlpool v0.0.0-20201016144138-0675e54bb004 7 | github.com/minio/blake2b-simd v0.0.0-20160723061019-3f5f724cb5b1 8 | leb.io/aeshash v0.1.0 9 | leb.io/cuckoo v0.1.2 10 | leb.io/hrff v0.1.0 11 | ) 12 | -------------------------------------------------------------------------------- /farm/README: -------------------------------------------------------------------------------- 1 | go-farm: Google's FarmHash in pure Go 2 | 3 | This is a (mechanical) translation of the non-SSE4/non-AESNI hash functions from FarmHash. 4 | 5 | For more information on FarmHash, please see https://code.google.com/p/farmhash 6 | 7 | For a cgo library wrapping the C++ one, please see https://github.com/dgryski/go-farmhash 8 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | # Compiled Object files, Static and Dynamic libs (Shared Objects) 2 | *.o 3 | *.a 4 | *.so 5 | 6 | # Folders 7 | _obj 8 | _test 9 | 10 | # Architecture specific extensions/prefixes 11 | *.[568vq] 12 | [568vq].out 13 | 14 | *.cgo1.go 15 | *.cgo2.c 16 | _cgo_defun.c 17 | _cgo_gotypes.go 18 | _cgo_export.* 19 | 20 | _testmain.go 21 | -------------------------------------------------------------------------------- /farm/bench_test.go: -------------------------------------------------------------------------------- 1 | package farm 2 | 3 | import "testing" 4 | 5 | func BenchmarkShort(b *testing.B) { 6 | 7 | buf := make([]byte, 32) 8 | 9 | for i := 0; i < b.N; i++ { 10 | Hash32(buf) 11 | } 12 | } 13 | 14 | func BenchmarkHash64(b *testing.B) { 15 | 16 | buf := make([]byte, 2048) 17 | 18 | for i := 0; i < b.N; i++ { 19 | Hash64(buf) 20 | } 21 | } 22 | -------------------------------------------------------------------------------- /metro/gitlog.txt: -------------------------------------------------------------------------------- 1 | commit d5cb643948fbb1a699e6da1426f0dba75fe3bb8e 2 | Author: Damian Gryski 3 | Date: Mon Jun 8 05:49:25 2015 +0200 4 | 5 | add official test vectors 6 | 7 | commit 07ea97f54349b2a3c8ff09373968078129b09b21 8 | Author: Damian Gryski 9 | Date: Thu May 28 15:29:33 2015 +0200 10 | 11 | inital import 12 | -------------------------------------------------------------------------------- /gomap/unaligned1.go: -------------------------------------------------------------------------------- 1 | // Copyright 2014 The Go Authors. All rights reserved. 2 | // Use of this source code is governed by a BSD-style 3 | // license that can be found in the LICENSE file. 4 | 5 | // +build 386 amd64 amd64p32 6 | 7 | package gomap 8 | 9 | import "unsafe" 10 | 11 | func readUnaligned32(p unsafe.Pointer) uint32 { 12 | return *(*uint32)(p) 13 | } 14 | 15 | func readUnaligned64(p unsafe.Pointer) uint64 { 16 | return *(*uint64)(p) 17 | } 18 | 19 | -------------------------------------------------------------------------------- /gomap/unaligned2.go: -------------------------------------------------------------------------------- 1 | // Copyright 2014 The Go Authors. All rights reserved. 2 | // Use of this source code is governed by a BSD-style 3 | // license that can be found in the LICENSE file. 4 | 5 | // +build arm ppc64 ppc64le 6 | 7 | package gomap 8 | 9 | import "unsafe" 10 | 11 | //Note: These routines perform the read with an unspecified endianness. 12 | func readUnaligned32(p unsafe.Pointer) uint32 { 13 | q := (*[4]byte)(p) 14 | return uint32(q[0]) + uint32(q[1])<<8 + uint32(q[2])<<16 + uint32(q[3])<<24 15 | } 16 | 17 | func readUnaligned64(p unsafe.Pointer) uint64 { 18 | q := (*[8]byte)(p) 19 | return uint64(q[0]) + uint64(q[1])<<8 + uint64(q[2])<<16 + uint64(q[3])<<24 + uint64(q[4])<<32 + uint64(q[5])<<40 + uint64(q[6])<<48 + uint64(q[7])<<56 20 | } 21 | 22 | -------------------------------------------------------------------------------- /farm/basics.go: -------------------------------------------------------------------------------- 1 | package farm 2 | 3 | // Some primes between 2^63 and 2^64 for various uses. 4 | const k0 uint64 = 0xc3a5c85c97cb3127 5 | const k1 uint64 = 0xb492b66fbe98f273 6 | const k2 uint64 = 0x9ae16a3b2f90404f 7 | 8 | // Magic numbers for 32-bit hashing. Copied from Murmur3. 9 | const c1 uint32 = 0xcc9e2d51 10 | const c2 uint32 = 0x1b873593 11 | 12 | // A 32-bit to 32-bit integer hash copied from Murmur3. 13 | func fmix(h uint32) uint32 { 14 | h ^= h >> 16 15 | h *= 0x85ebca6b 16 | h ^= h >> 13 17 | h *= 0xc2b2ae35 18 | h ^= h >> 16 19 | return h 20 | } 21 | 22 | func mur(a, h uint32) uint32 { 23 | // Helper from Murmur3 for combining two 32-bit values. 24 | a *= c1 25 | a = rotate32(a, 17) 26 | a *= c2 27 | h ^= a 28 | h = rotate32(h, 19) 29 | return h*5 + 0xe6546b64 30 | } 31 | -------------------------------------------------------------------------------- /siphash/hash_asm.go: -------------------------------------------------------------------------------- 1 | // +build amd64,!appengine 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 | 10 | // This file contains a function definition for use with assembly implementations of Hash() 11 | 12 | package siphash 13 | 14 | // Hash returns the 64-bit SipHash-2-4 of the given byte slice with two 64-bit 15 | // parts of 128-bit key: k0 and k1. 16 | func Hash(k0, k1 uint64, b []byte) uint64 17 | 18 | // Hash returns the 128-bit SipHash-2-4 of the given byte slice with two 64-bit 19 | // parts of 128-bit key: k0 and k1. 20 | func Hash128(k0, k1 uint64, b []byte) (uint64, uint64) 21 | -------------------------------------------------------------------------------- /farm/platform.go: -------------------------------------------------------------------------------- 1 | package farm 2 | 3 | func rotate32(val uint32, shift uint) uint32 { 4 | // Avoid shifting by 32: doing so yields an undefined result. 5 | if shift == 0 { 6 | return val 7 | } 8 | return ((val >> shift) | (val << (32 - shift))) 9 | } 10 | 11 | func rotate64(val uint64, shift uint) uint64 { 12 | // Avoid shifting by 64: doing so yields an undefined result. 13 | if shift == 0 { 14 | return val 15 | } 16 | return ((val >> shift) | (val << (64 - shift))) 17 | } 18 | 19 | func fetch32(s []byte, idx int) uint32 { 20 | return uint32(s[idx+0]) | uint32(s[idx+1])<<8 | uint32(s[idx+2])<<16 | uint32(s[idx+3])<<24 21 | } 22 | 23 | func fetch64(s []byte, idx int) uint64 { 24 | return uint64(s[idx+0]) | uint64(s[idx+1])<<8 | uint64(s[idx+2])<<16 | uint64(s[idx+3])<<24 | 25 | uint64(s[idx+4])<<32 | uint64(s[idx+5])<<40 | uint64(s[idx+6])<<48 | uint64(s[idx+7])<<56 26 | } 27 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | The MIT License (MIT) 2 | 3 | Copyright (c) 2014 Lawrence E. Bakst 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. 22 | 23 | -------------------------------------------------------------------------------- /murmur3/murmur64.go: -------------------------------------------------------------------------------- 1 | package murmur3 2 | 3 | import ( 4 | "hash" 5 | ) 6 | 7 | // Make sure interfaces are correctly implemented. 8 | var ( 9 | _ hash.Hash = new(digest64) 10 | _ hash.Hash64 = new(digest64) 11 | _ bmixer = new(digest64) 12 | ) 13 | 14 | // digest64 is half a digest128. 15 | type digest64 digest128 16 | 17 | func New64() hash.Hash64 { 18 | d := (*digest64)(New128().(*digest128)) 19 | return d 20 | } 21 | 22 | func (d *digest64) Sum(b []byte) []byte { 23 | h1 := d.h1 24 | return append(b, 25 | byte(h1>>56), byte(h1>>48), byte(h1>>40), byte(h1>>32), 26 | byte(h1>>24), byte(h1>>16), byte(h1>>8), byte(h1)) 27 | } 28 | 29 | func (d *digest64) Sum64() uint64 { 30 | h1, _ := (*digest128)(d).Sum128() 31 | return h1 32 | } 33 | 34 | // Sum64 returns the MurmurHash3 sum of data. It is equivalent to the 35 | // following sequence (without the extra burden and the extra allocation): 36 | // hasher := New64() 37 | // hasher.Write(data) 38 | // return hasher.Sum64() 39 | func Sum64(data []byte) uint64 { 40 | d := &digest128{h1: 0, h2: 0} 41 | d.tail = d.bmix(data) 42 | d.clen = len(data) 43 | h1, _ := d.Sum128() 44 | return h1 45 | } 46 | -------------------------------------------------------------------------------- /keccak/LICENSE: -------------------------------------------------------------------------------- 1 | Copyright (c) 2013 Barry Allard 2 | 3 | Except for keccak_test.go, .h and .c files are licensed seperately 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in 13 | all copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 21 | THE SOFTWARE. 22 | -------------------------------------------------------------------------------- /farm/COPYING: -------------------------------------------------------------------------------- 1 | As this is a highly derivative work, I have placed it under the same license as the original implementation: 2 | 3 | // Copyright (c) 2014 Damian Gryski 4 | // 5 | // Permission is hereby granted, free of charge, to any person obtaining a copy 6 | // of this software and associated documentation files (the "Software"), to deal 7 | // in the Software without restriction, including without limitation the rights 8 | // to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | // copies of the Software, and to permit persons to whom the Software is 10 | // furnished to do so, subject to the following conditions: 11 | // 12 | // The above copyright notice and this permission notice shall be included in 13 | // all copies or substantial portions of the Software. 14 | // 15 | // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 21 | // THE SOFTWARE. 22 | 23 | -------------------------------------------------------------------------------- /metro/README: -------------------------------------------------------------------------------- 1 | MetroHash 2 | 3 | This package is a mechanical translation of the reference C++ code for 4 | MetroHash, available at https://github.com/jandrewrogers/MetroHash 5 | 6 | I claim no additional copyright over the original implementation. 7 | 8 | The MIT License (MIT) 9 | 10 | Copyright (c) 2015 J. Andrew Rogers 11 | 12 | Permission is hereby granted, free of charge, to any person obtaining a copy 13 | of this software and associated documentation files (the "Software"), to deal 14 | in the Software without restriction, including without limitation the rights 15 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 16 | copies of the Software, and to permit persons to whom the Software is 17 | furnished to do so, subject to the following conditions: 18 | 19 | The above copyright notice and this permission notice shall be included in all 20 | copies or substantial portions of the Software. 21 | 22 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 23 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 24 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 25 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 26 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 27 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 28 | SOFTWARE. 29 | -------------------------------------------------------------------------------- /murmur3/LICENSE: -------------------------------------------------------------------------------- 1 | Copyright 2013, Sébastien Paolacci. 2 | All rights reserved. 3 | 4 | Redistribution and use in source and binary forms, with or without 5 | modification, are permitted provided that the following conditions are met: 6 | * Redistributions of source code must retain the above copyright 7 | notice, this list of conditions and the following disclaimer. 8 | * Redistributions in binary form must reproduce the above copyright 9 | notice, this list of conditions and the following disclaimer in the 10 | documentation and/or other materials provided with the distribution. 11 | * Neither the name of the library nor the 12 | names of its contributors may be used to endorse or promote products 13 | derived from this software without specific prior written permission. 14 | 15 | THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND 16 | ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED 17 | WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE 18 | DISCLAIMED. IN NO EVENT SHALL BE LIABLE FOR ANY 19 | DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES 20 | (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; 21 | LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND 22 | ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 23 | (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS 24 | SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 25 | -------------------------------------------------------------------------------- /keccak/README.md: -------------------------------------------------------------------------------- 1 | # TL;DR 2 | ## 10x faster than https://github.com/ebfe/keccak 3 | 4 | ### Usage 5 | 6 | ```go 7 | import "github.com/steakknife/keccak" 8 | 9 | ... 10 | 11 | h := keccak.New256() 12 | h.Write([]byte("Awesome")) 13 | keccakhash := h.Sum(nil) 14 | ``` 15 | 16 | ### keccak cgo 17 | 18 | PASS 19 | BenchmarkKeccak224Write1MiB 100 11056848 ns/op 20 | BenchmarkKeccak224Sum 500000 3870 ns/op 21 | BenchmarkKeccak256Write1MiB 100 10845596 ns/op 22 | BenchmarkKeccak256Sum 500000 4010 ns/op 23 | BenchmarkKeccak384Write1MiB 100 15315352 ns/op 24 | BenchmarkKeccak384Sum 500000 4004 ns/op 25 | BenchmarkKeccak512Write1MiB 100 21881999 ns/op 26 | BenchmarkKeccak512Sum 500000 3807 ns/op 27 | ok 28 | 29 | ### https://github.com/ebfe/keccak 30 | 31 | PASS 32 | BenchmarkKeccak224Write1MiB 20 116710461 ns/op 33 | BenchmarkKeccak224Sum 100000 17185 ns/op 34 | BenchmarkKeccak256Write1MiB 20 117566765 ns/op 35 | BenchmarkKeccak256Sum 100000 17011 ns/op 36 | BenchmarkKeccak384Write1MiB 10 160507004 ns/op 37 | BenchmarkKeccak384Sum 100000 17076 ns/op 38 | BenchmarkKeccak512Write1MiB 10 229374464 ns/op 39 | BenchmarkKeccak512Sum 100000 17011 ns/op 40 | ok 41 | 42 | ### optimized 64-bit implementation borrowed from http://csrc.nist.gov/groups/ST/hash/sha-3/Round3/documents/Keccak_FinalRnd.zip 43 | ### tests borrowed from https://github.com/ebfe/keccak 44 | -------------------------------------------------------------------------------- /keccak/keccak.go: -------------------------------------------------------------------------------- 1 | package keccak 2 | 3 | // #include "KeccakNISTInterface.h" 4 | import "C" 5 | import ( 6 | "errors" 7 | "hash" 8 | "unsafe" 9 | ) 10 | 11 | type keccak struct { 12 | hashState C.hashState 13 | bitlen C.int 14 | dataLength C.DataLength 15 | } 16 | 17 | func newKeccak(bitlen int) hash.Hash { 18 | k := &keccak{bitlen: C.int(bitlen)} 19 | k.Reset() 20 | return k 21 | } 22 | 23 | /* 24 | func NewCustom(bits, rounds int) hash.Hash { 25 | return newKeccak(bits, rounds) 26 | } 27 | */ 28 | 29 | func New224() hash.Hash { 30 | return newKeccak(224) 31 | } 32 | 33 | func New256() hash.Hash { 34 | return newKeccak(256) 35 | } 36 | 37 | func New384() hash.Hash { 38 | return newKeccak(384) 39 | } 40 | 41 | func New512() hash.Hash { 42 | return newKeccak(512) 43 | } 44 | 45 | func (k *keccak) Write(b []byte) (int, error) { 46 | n := len(b) 47 | if n == 0 { 48 | return 0, nil 49 | } 50 | dl := C.DataLength(n * 8) 51 | p := (*C.BitSequence)(unsafe.Pointer(&b[0])) 52 | if C.Update(&k.hashState, p, dl) != C.SUCCESS { 53 | return 0, errors.New("keccak write error") 54 | } 55 | return n, nil 56 | } 57 | 58 | func (k *keccak) Sum(b []byte) []byte { 59 | k0 := *k 60 | buf := make([]byte, k.Size(), k.Size()) 61 | p := (*C.BitSequence)(unsafe.Pointer(&buf[0])) 62 | if C.Final(&k0.hashState, p) != C.SUCCESS { 63 | panic("keccak sum error") 64 | } 65 | return append(b, buf...) 66 | } 67 | 68 | func (k *keccak) Reset() { 69 | C.Init(&k.hashState, k.bitlen) 70 | } 71 | 72 | func (k keccak) BlockSize() int { 73 | return 200 - 2*k.Size() 74 | } 75 | 76 | func (k keccak) Size() int { 77 | return int(k.bitlen) / 8 78 | } 79 | -------------------------------------------------------------------------------- /metro/metro_test.go: -------------------------------------------------------------------------------- 1 | package metro 2 | 3 | import ( 4 | "encoding/binary" 5 | "encoding/hex" 6 | "testing" 7 | ) 8 | 9 | // From src/testvector.h 10 | 11 | var key63 = []byte("012345678901234567890123456789012345678901234567890123456789012") 12 | 13 | func Test64(t *testing.T) { 14 | 15 | tests := []struct { 16 | f func([]byte, uint32) uint64 17 | which int 18 | seed uint32 19 | want string 20 | }{ 21 | {Hash64_1, 1, 0, "658F044F5C730E40"}, 22 | {Hash64_2, 2, 0, "073CAAB960623211"}, 23 | {Hash64_1, 1, 1, "AE49EBB0A856537B"}, 24 | {Hash64_2, 2, 1, "CF518E9CF58402C0"}, 25 | } 26 | 27 | for _, tt := range tests { 28 | want, _ := hex.DecodeString(tt.want) 29 | want64 := binary.LittleEndian.Uint64(want) 30 | if got := tt.f(key63, tt.seed); got != want64 { 31 | t.Errorf("Hash64_%d(%q, %d)=%x, want %x\n", tt.which, key63, tt.seed, got, want64) 32 | } 33 | } 34 | } 35 | 36 | func Test128(t *testing.T) { 37 | 38 | tests := []struct { 39 | f func([]byte, uint32) (uint64, uint64) 40 | which int 41 | seed uint32 42 | want string 43 | }{ 44 | {Hash128_1, 1, 0, "ED9997ED9D0A8B0FF3F266399477788F"}, 45 | {Hash128_2, 2, 0, "7BBA6FE119CF35D45507EDF3505359AB"}, 46 | {Hash128_1, 1, 1, "DDA6BA67F7DE755EFDF6BEABECCFD1F4"}, 47 | {Hash128_2, 2, 1, "2DA6AF149A5CDBC12B09DB0846D69EF0"}, 48 | } 49 | 50 | for _, tt := range tests { 51 | want, _ := hex.DecodeString(tt.want) 52 | want64a := binary.LittleEndian.Uint64(want) 53 | want64b := binary.LittleEndian.Uint64(want[8:]) 54 | if gota, gotb := tt.f(key63, tt.seed); gota != want64a || gotb != want64b { 55 | t.Errorf("Hash128_%d(%q, %d)=(%x, %x), want (%x, %x)\n", tt.which, key63, tt.seed, gota, gotb, want64a, want64b) 56 | } 57 | } 58 | } 59 | -------------------------------------------------------------------------------- /murmur3/murmur.go: -------------------------------------------------------------------------------- 1 | // Copyright 2013, Sébastien Paolacci. All rights reserved. 2 | // Use of this source code is governed by a BSD-style 3 | // license that can be found in the LICENSE file. 4 | 5 | /* 6 | Native (and fast) implementation of Austin Appleby's MurmurHash3. 7 | 8 | Package murmur3 implements Austin Appleby's non-cryptographic MurmurHash3. 9 | 10 | Reference implementation: 11 | http://code.google.com/p/smhasher/wiki/MurmurHash3 12 | 13 | History, characteristics and (legacy) perfs: 14 | https://sites.google.com/site/murmurhash/ 15 | https://sites.google.com/site/murmurhash/statistics 16 | */ 17 | package murmur3 18 | 19 | type bmixer interface { 20 | bmix(p []byte) (tail []byte) 21 | Size() (n int) 22 | reset() 23 | } 24 | 25 | type digest struct { 26 | clen int // Digested input cumulative length. 27 | tail []byte // 0 to Size()-1 bytes view of `buf'. 28 | buf [16]byte // Expected (but not required) to be Size() large. 29 | bmixer 30 | } 31 | 32 | func (d *digest) BlockSize() int { return 1 } 33 | 34 | func (d *digest) Write(p []byte) (n int, err error) { 35 | n = len(p) 36 | d.clen += n 37 | 38 | if len(d.tail) > 0 { 39 | // Stick back pending bytes. 40 | nfree := d.Size() - len(d.tail) // nfree ∈ [1, d.Size()-1]. 41 | if nfree < len(p) { 42 | // One full block can be formed. 43 | block := append(d.tail, p[:nfree]...) 44 | p = p[nfree:] 45 | _ = d.bmix(block) // No tail. 46 | } else { 47 | // Tail's buf is large enough to prevent reallocs. 48 | p = append(d.tail, p...) 49 | } 50 | } 51 | 52 | d.tail = d.bmix(p) 53 | 54 | // Keep own copy of the 0 to Size()-1 pending bytes. 55 | nn := copy(d.buf[:], d.tail) 56 | d.tail = d.buf[:nn] 57 | 58 | return n, nil 59 | } 60 | 61 | func (d *digest) Reset() { 62 | d.clen = 0 63 | d.tail = nil 64 | d.bmixer.reset() 65 | } 66 | -------------------------------------------------------------------------------- /keccak/KeccakF-1600-interface.h: -------------------------------------------------------------------------------- 1 | /* 2 | The Keccak sponge function, designed by Guido Bertoni, Joan Daemen, 3 | Michaël Peeters and Gilles Van Assche. For more information, feedback or 4 | questions, please refer to our website: http://keccak.noekeon.org/ 5 | 6 | Implementation by the designers, 7 | hereby denoted as "the implementer". 8 | 9 | To the extent possible under law, the implementer has waived all copyright 10 | and related or neighboring rights to the source code in this file. 11 | http://creativecommons.org/publicdomain/zero/1.0/ 12 | */ 13 | 14 | #ifndef _KeccakPermutationInterface_h_ 15 | #define _KeccakPermutationInterface_h_ 16 | 17 | #include "KeccakF-1600-int-set.h" 18 | 19 | void KeccakInitialize( void ); 20 | void KeccakInitializeState(unsigned char *state); 21 | void KeccakPermutation(unsigned char *state); 22 | #ifdef ProvideFast576 23 | void KeccakAbsorb576bits(unsigned char *state, const unsigned char *data); 24 | #endif 25 | #ifdef ProvideFast832 26 | void KeccakAbsorb832bits(unsigned char *state, const unsigned char *data); 27 | #endif 28 | #ifdef ProvideFast1024 29 | void KeccakAbsorb1024bits(unsigned char *state, const unsigned char *data); 30 | #endif 31 | #ifdef ProvideFast1088 32 | void KeccakAbsorb1088bits(unsigned char *state, const unsigned char *data); 33 | #endif 34 | #ifdef ProvideFast1152 35 | void KeccakAbsorb1152bits(unsigned char *state, const unsigned char *data); 36 | #endif 37 | #ifdef ProvideFast1344 38 | void KeccakAbsorb1344bits(unsigned char *state, const unsigned char *data); 39 | #endif 40 | void KeccakAbsorb(unsigned char *state, const unsigned char *data, unsigned int laneCount); 41 | #ifdef ProvideFast1024 42 | void KeccakExtract1024bits(const unsigned char *state, unsigned char *data); 43 | #endif 44 | void KeccakExtract(const unsigned char *state, unsigned char *data, unsigned int laneCount); 45 | 46 | #endif 47 | -------------------------------------------------------------------------------- /siphash/README.md: -------------------------------------------------------------------------------- 1 | SipHash (Go) 2 | ============ 3 | 4 | [![Build Status](https://travis-ci.org/dchest/siphash.svg)](https://travis-ci.org/dchest/siphash) 5 | 6 | Go implementation of SipHash-2-4, a fast short-input PRF created by 7 | Jean-Philippe Aumasson and Daniel J. Bernstein (http://131002.net/siphash/). 8 | 9 | 10 | ## Installation 11 | 12 | $ go get github.com/dchest/siphash 13 | 14 | 15 | Supported Go 1.1 and later. 16 | 17 | ## Usage 18 | 19 | import "github.com/dchest/siphash" 20 | 21 | There are two ways to use this package. 22 | The slower one is to use the standard hash.Hash64 interface: 23 | 24 | h := siphash.New(key) 25 | h.Write([]byte("Hello")) 26 | sum := h.Sum(nil) // returns 8-byte []byte 27 | 28 | or 29 | 30 | sum64 := h.Sum64() // returns uint64 31 | 32 | The faster one is to use Hash() function, which takes two uint64 parts of 33 | 16-byte key and a byte slice, and returns uint64 hash: 34 | 35 | sum64 := siphash.Hash(key0, key1, []byte("Hello")) 36 | 37 | The keys and output are little-endian. 38 | 39 | 40 | ## Functions 41 | 42 | ### func Hash(k0, k1 uint64, p []byte) uint64 43 | 44 | Hash returns the 64-bit SipHash-2-4 of the given byte slice with two 45 | 64-bit parts of 128-bit key: k0 and k1. 46 | 47 | ### func Hash128(k0, k1 uint64, p []byte) (uint64, uint64) 48 | 49 | Hash128 returns the 128-bit SipHash-2-4 of the given byte slice with two 50 | 64-bit parts of 128-bit key: k0 and k1. 51 | 52 | Note that 128-bit SipHash is considered experimental by SipHash authors at this time. 53 | 54 | ### func New(key []byte) hash.Hash64 55 | 56 | New returns a new hash.Hash64 computing SipHash-2-4 with 16-byte key. 57 | 58 | ### func New128(key []byte) hash.Hash 59 | 60 | New128 returns a new hash.Hash computing SipHash-2-4 with 16-byte key and 16-byte output. 61 | 62 | Note that 16-byte output is considered experimental by SipHash authors at this time. 63 | 64 | 65 | ## Public domain dedication 66 | 67 | Written by Dmitry Chestnykh and Damian Gryski. 68 | 69 | To the extent possible under law, the authors have dedicated all copyright 70 | and related and neighboring rights to this software to the public domain 71 | worldwide. This software is distributed without any warranty. 72 | http://creativecommons.org/publicdomain/zero/1.0/ 73 | -------------------------------------------------------------------------------- /keccak/KeccakNISTInterface.c: -------------------------------------------------------------------------------- 1 | /* 2 | The Keccak sponge function, designed by Guido Bertoni, Joan Daemen, 3 | Michaël Peeters and Gilles Van Assche. For more information, feedback or 4 | questions, please refer to our website: http://keccak.noekeon.org/ 5 | 6 | Implementation by the designers, 7 | hereby denoted as "the implementer". 8 | 9 | To the extent possible under law, the implementer has waived all copyright 10 | and related or neighboring rights to the source code in this file. 11 | http://creativecommons.org/publicdomain/zero/1.0/ 12 | */ 13 | 14 | #include 15 | #include "KeccakNISTInterface.h" 16 | #include "KeccakF-1600-interface.h" 17 | 18 | HashReturn Init(hashState *state, int hashbitlen) 19 | { 20 | switch(hashbitlen) { 21 | case 0: // Default parameters, arbitrary length output 22 | InitSponge((spongeState*)state, 1024, 576); 23 | break; 24 | case 224: 25 | InitSponge((spongeState*)state, 1152, 448); 26 | break; 27 | case 256: 28 | InitSponge((spongeState*)state, 1088, 512); 29 | break; 30 | case 384: 31 | InitSponge((spongeState*)state, 832, 768); 32 | break; 33 | case 512: 34 | InitSponge((spongeState*)state, 576, 1024); 35 | break; 36 | default: 37 | return BAD_HASHLEN; 38 | } 39 | state->fixedOutputLength = hashbitlen; 40 | return SUCCESS; 41 | } 42 | 43 | HashReturn Update(hashState *state, const BitSequence *data, DataLength databitlen) 44 | { 45 | if ((databitlen % 8) == 0) 46 | return Absorb((spongeState*)state, data, databitlen); 47 | else { 48 | HashReturn ret = Absorb((spongeState*)state, data, databitlen - (databitlen % 8)); 49 | if (ret == SUCCESS) { 50 | unsigned char lastByte; 51 | // Align the last partial byte to the least significant bits 52 | lastByte = data[databitlen/8] >> (8 - (databitlen % 8)); 53 | return Absorb((spongeState*)state, &lastByte, databitlen % 8); 54 | } 55 | else 56 | return ret; 57 | } 58 | } 59 | 60 | HashReturn Final(hashState *state, BitSequence *hashval) 61 | { 62 | return Squeeze(state, hashval, state->fixedOutputLength); 63 | } 64 | 65 | -------------------------------------------------------------------------------- /nullhash/nullhash.go: -------------------------------------------------------------------------------- 1 | package nullhash 2 | 3 | import ( 4 | "hash" 5 | "leb.io/hashland/nhash" 6 | ) 7 | 8 | func Nullhash(b []byte, seed uint64) uint64 { 9 | return 0 10 | } 11 | 12 | type nullhashstate struct { 13 | ctr uint64 14 | } 15 | 16 | func (n *nullhashstate) Size() int { 17 | return 8 18 | } 19 | 20 | func (n *nullhashstate) BlockSize() int { 21 | return 8 22 | } 23 | 24 | func (n *nullhashstate) NumSeedBytes() int { 25 | return 8 26 | } 27 | 28 | func (n *nullhashstate) Write(b []byte) (int, error) { 29 | return len(b), nil 30 | } 31 | 32 | func (n *nullhashstate) Sum(b []byte) []byte { 33 | 34 | buf := make([]byte, 8, 8) 35 | buf = buf[:] 36 | return append(b, buf...) 37 | } 38 | 39 | func (n *nullhashstate) Sum64() uint64 { 40 | n.ctr++ 41 | return n.ctr 42 | } 43 | 44 | func (n *nullhashstate) Reset() { 45 | } 46 | 47 | func (n *nullhashstate) Hash64(b []byte, seeds ...uint64) uint64 { 48 | n.ctr++ 49 | return n.ctr 50 | } 51 | 52 | func (n *nullhashstate) Hash64S(b []byte, seed uint64) uint64 { 53 | n.ctr++ 54 | return n.ctr 55 | } 56 | 57 | func New() hash.Hash64 { 58 | var n nullhashstate 59 | return &n 60 | } 61 | 62 | func NewF64() nhash.HashF64 { 63 | var n nullhashstate 64 | return &n 65 | } 66 | 67 | /* 68 | // initial results are even worse than I thought 69 | // nullhash: 1.135146477s 70 | // Hash64 with seed: 59.690928864s 71 | // Hash64 no seed: 3.684813561s 72 | 73 | const n = 1000000000 74 | var b = make([]byte, 100, 100) 75 | var seed uint64 76 | var intf = New() 77 | 78 | func b1() time.Duration { 79 | start := time.Now() 80 | for i:= 0; i < n; i++ { 81 | nullhash(b, seed) 82 | } 83 | stop := time.Now() 84 | return tdiff(start, stop) 85 | } 86 | 87 | func b2() time.Duration { 88 | start := time.Now() 89 | for i:= 0; i < n; i++ { 90 | intf.Hash64(b, seed) 91 | } 92 | stop := time.Now() 93 | return tdiff(start, stop) 94 | } 95 | 96 | func b3() time.Duration { 97 | start := time.Now() 98 | for i := 0; i < n; i++ { 99 | intf.Hash64(b) 100 | } 101 | stop := time.Now() 102 | return tdiff(start, stop) 103 | } 104 | 105 | func main() { 106 | fmt.Printf("nullhash: ") 107 | t1 := b1() 108 | fmt.Printf("%v\n", t1) 109 | fmt.Printf("Hash64 with seed: ") 110 | t2 := b2() 111 | fmt.Printf("%v\n", t2) 112 | fmt.Printf("Hash64 no seed: ") 113 | t3 := b3() 114 | fmt.Printf("%v\n", t3) 115 | } 116 | */ 117 | -------------------------------------------------------------------------------- /farm/farmhashmk.go: -------------------------------------------------------------------------------- 1 | package farm 2 | 3 | func hash32Len5to12(s []byte, seed uint32) uint32 { 4 | slen := len(s) 5 | a := uint32(len(s)) 6 | b := uint32(len(s) * 5) 7 | c := uint32(9) 8 | d := b + seed 9 | a += fetch32(s, 0) 10 | b += fetch32(s, slen-4) 11 | c += fetch32(s, ((slen >> 1) & 4)) 12 | return fmix(seed ^ mur(c, mur(b, mur(a, d)))) 13 | } 14 | 15 | func Hash32(s []byte) uint32 { 16 | 17 | slen := len(s) 18 | 19 | if slen <= 24 { 20 | if slen <= 12 { 21 | if slen <= 4 { 22 | return hash32Len0to4(s, 0) 23 | } 24 | return hash32Len5to12(s, 0) 25 | } 26 | return hash32Len13to24Seed(s, 0) 27 | } 28 | 29 | // len > 24 30 | h := uint32(slen) 31 | g := c1 * uint32(slen) 32 | f := g 33 | a0 := rotate32(fetch32(s, slen-4)*c1, 17) * c2 34 | a1 := rotate32(fetch32(s, slen-8)*c1, 17) * c2 35 | a2 := rotate32(fetch32(s, slen-16)*c1, 17) * c2 36 | a3 := rotate32(fetch32(s, slen-12)*c1, 17) * c2 37 | a4 := rotate32(fetch32(s, slen-20)*c1, 17) * c2 38 | h ^= a0 39 | h = rotate32(h, 19) 40 | h = h*5 + 0xe6546b64 41 | h ^= a2 42 | h = rotate32(h, 19) 43 | h = h*5 + 0xe6546b64 44 | g ^= a1 45 | g = rotate32(g, 19) 46 | g = g*5 + 0xe6546b64 47 | g ^= a3 48 | g = rotate32(g, 19) 49 | g = g*5 + 0xe6546b64 50 | f += a4 51 | f = rotate32(f, 19) + 113 52 | iters := (slen - 1) / 20 53 | for { 54 | a := fetch32(s, 0) 55 | b := fetch32(s, 4) 56 | c := fetch32(s, 8) 57 | d := fetch32(s, 12) 58 | e := fetch32(s, 16) 59 | h += a 60 | g += b 61 | f += c 62 | h = mur(d, h) + e 63 | g = mur(c, g) + a 64 | f = mur(b+e*c1, f) + d 65 | f += g 66 | g += f 67 | s = s[20:] 68 | iters-- 69 | if iters == 0 { 70 | break 71 | } 72 | } 73 | g = rotate32(g, 11) * c1 74 | g = rotate32(g, 17) * c1 75 | f = rotate32(f, 11) * c1 76 | f = rotate32(f, 17) * c1 77 | h = rotate32(h+g, 19) 78 | h = h*5 + 0xe6546b64 79 | h = rotate32(h, 17) * c1 80 | h = rotate32(h+f, 19) 81 | h = h*5 + 0xe6546b64 82 | h = rotate32(h, 17) * c1 83 | return h 84 | } 85 | 86 | func Hash32WithSeed(s []byte, seed uint32) uint32 { 87 | slen := len(s) 88 | 89 | if slen <= 24 { 90 | if slen >= 13 { 91 | return hash32Len13to24Seed(s, seed*c1) 92 | } 93 | if slen >= 5 { 94 | return hash32Len5to12(s, seed) 95 | } 96 | return hash32Len0to4(s, seed) 97 | } 98 | h := hash32Len13to24Seed(s[:24], seed^uint32(slen)) 99 | return mur(Hash32(s[24:])+seed, h) 100 | } 101 | -------------------------------------------------------------------------------- /go.sum: -------------------------------------------------------------------------------- 1 | github.com/alecthomas/binary v0.0.0-20190922233330-fb1b1d9c299c/go.mod h1:v4e05/vzE8ubOim1No9Xx5eIQ/WRq6AtcnQIy/Z/JPs= 2 | github.com/dataence/bloom v0.0.0-20151026233158-e24b032dccb1/go.mod h1:hQ0yBWNA+0SlYMlAkHsylNyF2c85ZPgnJ6pvMOkzpRY= 3 | github.com/dataence/cityhash v0.0.0-20131128155616-cdd6a94144ab/go.mod h1:8k8m9EQDOnG3a2Z27FvW8LPScFO9P2JglEeq2kjKP9Y= 4 | github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= 5 | github.com/jzelinskie/whirlpool v0.0.0-20201016144138-0675e54bb004 h1:G+9t9cEtnC9jFiTxyptEKuNIAbiN5ZCQzX2a74lj3xg= 6 | github.com/jzelinskie/whirlpool v0.0.0-20201016144138-0675e54bb004/go.mod h1:KmHnJWQrgEvbuy0vcvj00gtMqbvNn1L+3YUZLK/B92c= 7 | github.com/minio/blake2b-simd v0.0.0-20160723061019-3f5f724cb5b1 h1:lYpkrQH5ajf0OXOcUbGjvZxxijuBwbbmlSxLiuofa+g= 8 | github.com/minio/blake2b-simd v0.0.0-20160723061019-3f5f724cb5b1/go.mod h1:pD8RvIylQ358TN4wwqatJ8rNavkEINozVn9DtGI3dfQ= 9 | github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4= 10 | github.com/spaolacci/murmur3 v1.1.0/go.mod h1:JwIasOWyU6f++ZhiEuf87xNszmSA2myDM2Kzu9HwQUA= 11 | github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME= 12 | github.com/stretchr/testify v1.7.0/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg= 13 | github.com/willf/bitset v1.1.11/go.mod h1:83CECat5yLh5zVOf4P1ErAgKA5UDvKtgyUABdr3+MjI= 14 | github.com/zhenjl/bloom v0.0.0-20151026233158-e24b032dccb1/go.mod h1:m5109HBotwhAcpovJ+nory3OI1OrcUmaluV7vxjX+ig= 15 | github.com/zhenjl/cityhash v0.0.0-20131128155616-cdd6a94144ab/go.mod h1:P6L88wrqK99Njntah9SB7AyzFpUXsXYq06LkjixxQmY= 16 | gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= 17 | gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= 18 | leb.io/aeshash v0.0.0-20190627052759-9e6b40329b3b/go.mod h1:BKjvdzZnV5WaMoO/kz/Fygl60dA79GTFQTSuKJmSdNs= 19 | leb.io/aeshash v0.1.0 h1:kBcHB0+ipESEgA7pAxZ6QfhYBiBaWjTQ1NBKqX7GyUE= 20 | leb.io/aeshash v0.1.0/go.mod h1:BKjvdzZnV5WaMoO/kz/Fygl60dA79GTFQTSuKJmSdNs= 21 | leb.io/cuckoo v0.1.2 h1:3/P44oEGwQ4E2xlRyvpPhvHQIvxHh5+VdanBbxRYhOk= 22 | leb.io/cuckoo v0.1.2/go.mod h1:EAn6JQBg65dcILMLuPbBRbkSjd6u+4KA+iTwBEUxBuQ= 23 | leb.io/hashland v0.0.0-20171003003232-07375b562dea/go.mod h1:OSwp5BNKniWS6joctn4Grabrxd2EERBB7pNzK9Ni3BQ= 24 | leb.io/hrff v0.1.0 h1:HAhaPEnNEJp7pCbH/qgCT0VMNMQC7I10unCRuu08cKc= 25 | leb.io/hrff v0.1.0/go.mod h1:EZ02Yctbwtxev2S/3jw6aKNrw2e/gkaaRk4fgnYFTec= 26 | -------------------------------------------------------------------------------- /gomap/hash32.go: -------------------------------------------------------------------------------- 1 | // Copyright 2014 The Go Authors. All rights reserved. 2 | // Use of this source code is governed by a BSD-style 3 | // license that can be found in the LICENSE file. 4 | 5 | // Hashing algorithm inspired by 6 | // xxhash: https://code.google.com/p/xxhash/ 7 | // cityhash: https://code.google.com/p/cityhash/ 8 | 9 | package gomap 10 | 11 | import "unsafe" 12 | 13 | func Hash32(b []byte, seed uint32) uint32 { 14 | const ( 15 | // Constants for multiplication: four random odd 32-bit numbers. 16 | m1 = 3168982561 17 | m2 = 3339683297 18 | m3 = 832293441 19 | m4 = 2336365089 20 | ) 21 | 22 | p := unsafe.Pointer(&b[0]) 23 | s := len(b) 24 | h := uint32(seed + uint32(s)) 25 | tail: 26 | switch { 27 | case s == 0: 28 | case s < 4: 29 | w := uint32(*(*byte)(p)) 30 | w += uint32(*(*byte)(add(p, s>>1))) << 8 31 | w += uint32(*(*byte)(add(p, s-1))) << 16 32 | h ^= w * m1 33 | case s == 4: 34 | h ^= readUnaligned32(p) * m1 35 | case s <= 8: 36 | h ^= readUnaligned32(p) * m1 37 | h = rotl_15(h) * m2 38 | h = rotl_11(h) 39 | h ^= readUnaligned32(add(p, s-4)) * m1 40 | case s <= 16: 41 | h ^= readUnaligned32(p) * m1 42 | h = rotl_15(h) * m2 43 | h = rotl_11(h) 44 | h ^= readUnaligned32(add(p, 4)) * m1 45 | h = rotl_15(h) * m2 46 | h = rotl_11(h) 47 | h ^= readUnaligned32(add(p, s-8)) * m1 48 | h = rotl_15(h) * m2 49 | h = rotl_11(h) 50 | h ^= readUnaligned32(add(p, s-4)) * m1 51 | default: 52 | v1 := h 53 | v2 := h + m1 54 | v3 := h + m2 55 | v4 := h + m3 56 | for s >= 16 { 57 | v1 ^= readUnaligned32(p) * m1 58 | v1 = rotl_15(v1) * m2 59 | p = add(p, 4) 60 | v2 ^= readUnaligned32(p) * m1 61 | v2 = rotl_15(v2) * m2 62 | p = add(p, 4) 63 | v3 ^= readUnaligned32(p) * m1 64 | v3 = rotl_15(v3) * m2 65 | p = add(p, 4) 66 | v4 ^= readUnaligned32(p) * m1 67 | v4 = rotl_15(v4) * m2 68 | p = add(p, 4) 69 | s -= 16 70 | } 71 | h = rotl_11(v1)*m1 + rotl_11(v2)*m2 + rotl_11(v3)*m3 + rotl_11(v4)*m4 72 | goto tail 73 | } 74 | h ^= h >> 17 75 | h *= m3 76 | h ^= h >> 13 77 | h *= m4 78 | h ^= h >> 16 79 | return uint32(h) 80 | } 81 | 82 | // Note: in order to get the compiler to issue rotl instructions, we 83 | // need to constant fold the shift amount by hand. TODO: convince 84 | // the compiler to issue rotl instructions after inlining. 85 | func rotl_15(x uint32) uint32 { 86 | return (x << 15) | (x >> (32 - 15)) 87 | } 88 | func rotl_11(x uint32) uint32 { 89 | return (x << 11) | (x >> (32 - 11)) 90 | } 91 | -------------------------------------------------------------------------------- /gomap/hash64.go: -------------------------------------------------------------------------------- 1 | // Copyright 2014 The Go Authors. All rights reserved. 2 | // Use of this source code is governed by a BSD-style 3 | // license that can be found in the LICENSE file. 4 | 5 | // Hashing algorithm inspired by 6 | // xxhash: https://code.google.com/p/xxhash/ 7 | // cityhash: https://code.google.com/p/cityhash/ 8 | 9 | package gomap 10 | 11 | import "unsafe" 12 | 13 | func Hash64(b []byte, seed uint64) uint64 { 14 | const ( 15 | // Constants for multiplication: four random odd 64-bit numbers. 16 | m1 = 16877499708836156737 17 | m2 = 2820277070424839065 18 | m3 = 9497967016996688599 19 | m4 = 15839092249703872147 20 | ) 21 | p := unsafe.Pointer(&b[0]) 22 | s := len(b) 23 | h := uint64(seed + uint64(s)) 24 | tail: 25 | switch { 26 | case s == 0: 27 | case s < 4: 28 | w := uint64(*(*byte)(p)) 29 | w += uint64(*(*byte)(add(p, s>>1))) << 8 30 | w += uint64(*(*byte)(add(p, s-1))) << 16 31 | h ^= w * m1 32 | case s <= 8: 33 | w := uint64(readUnaligned32(p)) 34 | w += uint64(readUnaligned32(add(p, s-4))) << 32 35 | h ^= w * m1 36 | case s <= 16: 37 | h ^= readUnaligned64(p) * m1 38 | h = rotl_31(h) * m2 39 | h = rotl_27(h) 40 | h ^= readUnaligned64(add(p, s-8)) * m1 41 | case s <= 32: 42 | h ^= readUnaligned64(p) * m1 43 | h = rotl_31(h) * m2 44 | h = rotl_27(h) 45 | h ^= readUnaligned64(add(p, 8)) * m1 46 | h = rotl_31(h) * m2 47 | h = rotl_27(h) 48 | h ^= readUnaligned64(add(p, s-16)) * m1 49 | h = rotl_31(h) * m2 50 | h = rotl_27(h) 51 | h ^= readUnaligned64(add(p, s-8)) * m1 52 | default: 53 | v1 := h 54 | v2 := h + m1 55 | v3 := h + m2 56 | v4 := h + m3 57 | for s >= 32 { 58 | v1 ^= readUnaligned64(p) * m1 59 | v1 = rotl_31(v1) * m2 60 | p = add(p, 8) 61 | v2 ^= readUnaligned64(p) * m1 62 | v2 = rotl_31(v2) * m2 63 | p = add(p, 8) 64 | v3 ^= readUnaligned64(p) * m1 65 | v3 = rotl_31(v3) * m2 66 | p = add(p, 8) 67 | v4 ^= readUnaligned64(p) * m1 68 | v4 = rotl_31(v4) * m2 69 | p = add(p, 8) 70 | s -= 32 71 | } 72 | h = rotl_27(v1)*m1 + rotl_27(v2)*m2 + rotl_27(v3)*m3 + rotl_27(v4)*m4 73 | goto tail 74 | } 75 | 76 | h ^= h >> 33 77 | h *= m2 78 | h ^= h >> 29 79 | h *= m3 80 | h ^= h >> 32 81 | return uint64(h) 82 | } 83 | 84 | // Note: in order to get the compiler to issue rotl instructions, we 85 | // need to constant fold the shift amount by hand. TODO: convince 86 | // the compiler to issue rotl instructions after inlining. 87 | func rotl_31(x uint64) uint64 { 88 | return (x << 31) | (x >> (64 - 31)) 89 | } 90 | func rotl_27(x uint64) uint64 { 91 | return (x << 27) | (x >> (64 - 27)) 92 | } 93 | 94 | -------------------------------------------------------------------------------- /mahash/mahash8v64.go: -------------------------------------------------------------------------------- 1 | package mahash 2 | 3 | import ( 4 | _ "fmt" 5 | ) 6 | 7 | // came from here http://amsoftware.narod.ru/algo.html 8 | var sTable = [256]byte{ 9 | 0xa3,0xd7,0x09,0x83,0xf8,0x48,0xf6,0xf4,0xb3,0x21,0x15,0x78,0x99,0xb1,0xaf,0xf9, 10 | 0xe7,0x2d,0x4d,0x8a,0xce,0x4c,0xca,0x2e,0x52,0x95,0xd9,0x1e,0x4e,0x38,0x44,0x28, 11 | 0x0a,0xdf,0x02,0xa0,0x17,0xf1,0x60,0x68,0x12,0xb7,0x7a,0xc3,0xe9,0xfa,0x3d,0x53, 12 | 0x96,0x84,0x6b,0xba,0xf2,0x63,0x9a,0x19,0x7c,0xae,0xe5,0xf5,0xf7,0x16,0x6a,0xa2, 13 | 0x39,0xb6,0x7b,0x0f,0xc1,0x93,0x81,0x1b,0xee,0xb4,0x1a,0xea,0xd0,0x91,0x2f,0xb8, 14 | 0x55,0xb9,0xda,0x85,0x3f,0x41,0xbf,0xe0,0x5a,0x58,0x80,0x5f,0x66,0x0b,0xd8,0x90, 15 | 0x35,0xd5,0xc0,0xa7,0x33,0x06,0x65,0x69,0x45,0x00,0x94,0x56,0x6d,0x98,0x9b,0x76, 16 | 0x97,0xfc,0xb2,0xc2,0xb0,0xfe,0xdb,0x20,0xe1,0xeb,0xd6,0xe4,0xdd,0x47,0x4a,0x1d, 17 | 0x42,0xed,0x9e,0x6e,0x49,0x3c,0xcd,0x43,0x27,0xd2,0x07,0xd4,0xde,0xc7,0x67,0x18, 18 | 0x89,0xcb,0x30,0x1f,0x8d,0xc6,0x8f,0xaa,0xc8,0x74,0xdc,0xc9,0x5d,0x5c,0x31,0xa4, 19 | 0x70,0x88,0x61,0x2c,0x9f,0x0d,0x2b,0x87,0x50,0x82,0x54,0x64,0x26,0x7d,0x03,0x40, 20 | 0x34,0x4b,0x1c,0x73,0xd1,0xc4,0xfd,0x3b,0xcc,0xfb,0x7f,0xab,0xe6,0x3e,0x5b,0xa5, 21 | 0xad,0x04,0x23,0x9c,0x14,0x51,0x22,0xf0,0x29,0x79,0x71,0x7e,0xff,0x8c,0x0e,0xe2, 22 | 0x0c,0xef,0xbc,0x72,0x75,0x6f,0x37,0xa1,0xec,0xd3,0x8e,0x62,0x8b,0x86,0x10,0xe8, 23 | 0x08,0x77,0x11,0xbe,0x92,0x4f,0x24,0xc5,0x32,0x36,0x9d,0xcf,0xf3,0xa6,0xbb,0xac, 24 | 0x5e,0x6c,0xa9,0x13,0x57,0x25,0xb5,0xe3,0xbd,0xa8,0x3a,0x01,0x05,0x59,0x2a,0x46, 25 | } 26 | 27 | func LROT14(x uint32) uint32 { 28 | return ((x) << 14) | ((x) >> 18) 29 | } 30 | 31 | func RROT14(x uint32) uint32 { 32 | return ((x) << 18) | ((x) >> 14) 33 | } 34 | 35 | func LROT64 (x uint64) uint64 { 36 | return ((x) << 29) | ((x) >> 34) // HIAVAL 37 | } 38 | 39 | func MaHash8v64(str []byte) (digest uint64) { 40 | //unsigned int sh1, sh2, hash1 = len, hash2 = len, i; 41 | // unsigned long long digest; 42 | 43 | hash1 := uint32(len(str)) 44 | hash2 := hash1 45 | l := len(str) 46 | for i := 0; i < l; i++ { 47 | //fmt.Printf("i=%d, str=%q, len(str)=%d\n", i, str, len(str)) 48 | hash1 += uint32(sTable[str[i]]) 49 | hash1 = LROT14 (hash1 + ((hash1 << 6) ^ (hash1 >> 11))) 50 | hash2 += uint32(sTable[str[i]]) 51 | hash2 = RROT14 (hash2 + ((hash2 << 6) ^ (hash2 >> 11))) 52 | sh1 := hash1 53 | sh2 := hash2 54 | hash1 = ((sh1 >> 16) & 0xffff) | ((sh2 & 0xffff) << 16) 55 | hash2 = ((sh2 >> 16) & 0xffff) | ((sh1 & 0xffff) << 16) 56 | } 57 | if true { 58 | digest = uint64(hash1) << 32 | uint64(hash2) 59 | digest ^= LROT64(digest + ((digest << 13) ^ (digest >> 23))) 60 | } else { 61 | digest = uint64(hash2) << 32 | uint64(hash1) 62 | } 63 | return 64 | } 65 | -------------------------------------------------------------------------------- /farm/farmhashuo.go: -------------------------------------------------------------------------------- 1 | package farm 2 | 3 | func uoH(x, y, mul uint64, r uint) uint64 { 4 | a := (x ^ y) * mul 5 | a ^= (a >> 47) 6 | b := (y ^ a) * mul 7 | return rotate64(b, r) * mul 8 | } 9 | 10 | func Hash64WithSeeds(s []byte, seed0, seed1 uint64) uint64 { 11 | slen := len(s) 12 | if slen <= 64 { 13 | return naHash64WithSeeds(s, seed0, seed1) 14 | } 15 | 16 | // For strings over 64 bytes we loop. Internal state consists of 17 | // 64 bytes: u, v, w, x, y, and z. 18 | x := seed0 19 | y := seed1*k2 + 113 20 | z := shiftMix(y*k2) * k2 21 | v := uint128{seed0, seed1} 22 | var w uint128 23 | u := x - z 24 | x *= k2 25 | mul := k2 + (u & 0x82) 26 | 27 | // Set end so that after the loop we have 1 to 64 bytes left to process. 28 | endIdx := ((slen - 1) / 64) * 64 29 | last64Idx := endIdx + ((slen - 1) & 63) - 63 30 | last64 := s[last64Idx:] 31 | 32 | for len(s) > 64 { 33 | a0 := fetch64(s, 0) 34 | a1 := fetch64(s, 8) 35 | a2 := fetch64(s, 16) 36 | a3 := fetch64(s, 24) 37 | a4 := fetch64(s, 32) 38 | a5 := fetch64(s, 40) 39 | a6 := fetch64(s, 48) 40 | a7 := fetch64(s, 56) 41 | x += a0 + a1 42 | y += a2 43 | z += a3 44 | v.lo += a4 45 | v.hi += a5 + a1 46 | w.lo += a6 47 | w.hi += a7 48 | 49 | x = rotate64(x, 26) 50 | x *= 9 51 | y = rotate64(y, 29) 52 | z *= mul 53 | v.lo = rotate64(v.lo, 33) 54 | v.hi = rotate64(v.hi, 30) 55 | w.lo ^= x 56 | w.lo *= 9 57 | z = rotate64(z, 32) 58 | z += w.hi 59 | w.hi += z 60 | z *= 9 61 | u, y = y, u 62 | 63 | z += a0 + a6 64 | v.lo += a2 65 | v.hi += a3 66 | w.lo += a4 67 | w.hi += a5 + a6 68 | x += a1 69 | y += a7 70 | 71 | y += v.lo 72 | v.lo += x - y 73 | v.hi += w.lo 74 | w.lo += v.hi 75 | w.hi += x - y 76 | x += w.hi 77 | w.hi = rotate64(w.hi, 34) 78 | u, z = z, u 79 | s = s[64:] 80 | } 81 | // Make s point to the last 64 bytes of input. 82 | s = last64 83 | u *= 9 84 | v.hi = rotate64(v.hi, 28) 85 | v.lo = rotate64(v.lo, 20) 86 | w.lo += (uint64(slen-1) & 63) 87 | u += y 88 | y += u 89 | x = rotate64(y-x+v.lo+fetch64(s, 8), 37) * mul 90 | y = rotate64(y^v.hi^fetch64(s, 48), 42) * mul 91 | x ^= w.hi * 9 92 | y += v.lo + fetch64(s, 40) 93 | z = rotate64(z+w.lo, 33) * mul 94 | v.lo, v.hi = weakHashLen32WithSeeds(s, v.hi*mul, x+w.lo) 95 | w.lo, w.hi = weakHashLen32WithSeeds(s[32:], z+w.hi, y+fetch64(s, 16)) 96 | return uoH(hashLen16Mul(v.lo+x, w.lo^y, mul)+z-u, 97 | uoH(v.hi+y, w.hi+z, k2, 30)^x, 98 | k2, 99 | 31) 100 | } 101 | 102 | func Hash64WithSeed(s []byte, seed uint64) uint64 { 103 | if len(s) <= 64 { 104 | return naHash64WithSeed(s, seed) 105 | } 106 | return Hash64WithSeeds(s, 0, seed) 107 | } 108 | 109 | func Hash64(s []byte) uint64 { 110 | if len(s) <= 64 { 111 | return naHash64(s) 112 | } 113 | return Hash64WithSeeds(s, 81, 0) 114 | } 115 | -------------------------------------------------------------------------------- /crapwow/crapwow.go: -------------------------------------------------------------------------------- 1 | // Copyright © 2014 Lawrence E. Bakst. All rights reserved. 2 | 3 | package crapwow 4 | 5 | import ( 6 | "leb.io/hashland/nhash" 7 | "unsafe" 8 | ) 9 | 10 | // this makes a new slice of uint32 that points to the same slice passed in as []byte 11 | // we should check alignment for architectures that don't handle unaligned reads 12 | // and fallback to a copy maybe using encoding/binary. 13 | // One question is what are the right test vevtors for big-endian machines. 14 | func sliceUI32(in []byte) []uint32 { 15 | return (*(*[]uint32)(unsafe.Pointer(&in)))[:len(in)/4] 16 | } 17 | 18 | func CrapWow(key []byte, seed uint32) uint32 { 19 | const m uint32 = 0x57559429 20 | const n uint32 = 0x5052acdb 21 | var l = len(key) 22 | var h = uint32(l) 23 | var k = h + seed + n 24 | var p uint64 25 | /* 26 | var cwfold = func(a, b, lo, hi uint32) { 27 | p = uint32(a) * uint64(b) 28 | lo ^= uint32(p) 29 | hi ^= uint32(p >> 32) 30 | } 31 | */ 32 | var cwmixa = func(in uint32) { 33 | p = uint64(in) * uint64(m) 34 | k ^= uint32(p) 35 | h ^= uint32(p >> 32) 36 | } 37 | 38 | var cwmixb = func(in uint32) { 39 | p = uint64(in) * uint64(n) 40 | h ^= uint32(p) 41 | k ^= uint32(p >> 32) 42 | } 43 | 44 | key4 := sliceUI32(key) 45 | for l >= 8 { 46 | cwmixb(key4[0]) 47 | cwmixa(key4[1]) 48 | key4 = key4[2:] 49 | key = key[8:] 50 | l -= 8 51 | } 52 | if l >= 4 { 53 | cwmixb(key4[0]) 54 | key4 = key4[1:] 55 | key = key[4:] 56 | l -= 4 57 | } 58 | switch l { 59 | case 3: 60 | tmp := uint32(key[2])<<16 | uint32(key[1])<<8 | uint32(key[0]) 61 | cwmixa(tmp & ((1 << (uint32(l) * 8)) - 1)) 62 | case 2: 63 | tmp := uint32(key[1])<<8 | uint32(key[0]) 64 | cwmixa(tmp & ((1 << (uint32(l) * 8)) - 1)) 65 | case 1: 66 | tmp := uint32(key[0]) 67 | cwmixa(tmp & ((1 << (uint32(l) * 8)) - 1)) 68 | } 69 | cwmixb(h ^ (k + n)) 70 | return k ^ h 71 | } 72 | 73 | type State struct { 74 | hash uint32 75 | seed uint32 76 | } 77 | 78 | // New returns a new hash.HashF32 interface that computes a 32 bit CrapWow hash. 79 | func New(seed uint32) nhash.HashF32 { 80 | s := new(State) 81 | s.seed = seed 82 | return s 83 | } 84 | 85 | // The size of an jenkins3 32 bit hash in bytes. 86 | const Size = 4 87 | 88 | // Return the size of the resulting hash. 89 | func (s *State) Size() int { return Size } 90 | 91 | // Return the blocksize of the hash which in this case is 8 bytes. 92 | func (s *State) BlockSize() int { return 8 } 93 | 94 | // Return the maximum number of seed bypes required. 95 | func (s *State) NumSeedBytes() int { 96 | return 4 97 | } 98 | 99 | // retunrs the number of bits the hash function outputs 100 | func (s *State) HashSizeInBits() int { 101 | return 32 102 | } 103 | 104 | func (s *State) Hash32(b []byte, seeds ...uint32) uint32 { 105 | if len(seeds) > 0 { 106 | s.seed = seeds[0] 107 | } 108 | s.hash = CrapWow(b, s.seed) 109 | return s.hash 110 | } 111 | -------------------------------------------------------------------------------- /nhash/nhash.go: -------------------------------------------------------------------------------- 1 | // Copyright © 2014 Lawrence E. Bakst. All rights reserved. 2 | 3 | // This package contains a new set of interfacs for hash functions. 4 | // It also implements the Go streaming hash interface as HashStream. 5 | // It is an experiment. 6 | 7 | package nhash 8 | 9 | import ( 10 | "io" 11 | ) 12 | 13 | // Interface HashFunction requires 4 methods that return the 14 | // size of the hasg function in bytes and bits. Probably wiil 15 | // flush bits. Also the maximum number of bytes of seed needed. 16 | type HashFunction interface { 17 | // Size returns the number of bytes Sum will return. 18 | Size() int 19 | 20 | // BlockSize returns the hash's underlying block size. 21 | // The Write method must be able to accept any amount 22 | // of data, but it may operate more efficiently if all writes 23 | // are a multiple of the block size. 24 | BlockSize() int 25 | 26 | // maximum number of seeds in bytes (should this be in bits?) 27 | NumSeedBytes() int 28 | 29 | // retunrs the number of bits the hash function outputs 30 | //HashSizeInBits() int 31 | } 32 | 33 | // HashStream is a streaming interface for hash functions. 34 | type HashStream interface { 35 | HashFunction 36 | 37 | // Write (via the embedded io.Writer interface) adds more data to the running hash. 38 | // It never returns an error. 39 | io.Writer 40 | 41 | // Sum appends the current hash to b and returns the resulting slice. 42 | // It does not change the underlying hash state. 43 | Sum(b []byte) []byte 44 | 45 | // Reset resets the Hash to its initial state. 46 | Reset() 47 | } 48 | 49 | // Hash32 is a common interface implemented by the streaming 32-bit hash functions. 50 | type Hash32 interface { 51 | HashStream 52 | Sum32() uint32 53 | } 54 | 55 | // Hash64 is a common interface implemented by the streaming 32-bit hash functions. 56 | type Hash64 interface { 57 | HashStream 58 | Write64(h uint64) error 59 | Sum64() uint64 60 | } 61 | 62 | // *** Everything below here will be removed or chnaged as vargs was way too expensive. *** 63 | 64 | // HashF32 is the interface that all non-streaming 32 bit hash functions implement. 65 | type HashF32 interface { 66 | HashFunction 67 | Hash32(b []byte, seeds ...uint32) uint32 68 | } 69 | 70 | // HashF64 is the interface that all non-streaming 64 bit hash functions implement. 71 | type HashF64 interface { 72 | HashFunction 73 | Hash64(b []byte, seeds ...uint64) uint64 74 | Hash64S(b []byte, seed uint64) uint64 75 | } 76 | 77 | // HashF128 is the interface that all non-streaming 128 bit hash functions implement. 78 | type HashF128 interface { 79 | HashFunction 80 | Hash128(b []byte, seeds ...uint64) (uint64, uint64) 81 | } 82 | 83 | // HashGeneric is generic interface that non-streaming, typicall crytpo hash functions implement. 84 | type HashGeneric interface { 85 | HashFunction 86 | 87 | // Hash takes "in" bytes of input, the hash is returned into byte slice "out" 88 | // change seeds to bytes ??? 89 | Hash(in []byte, out []byte, seeds ...uint64) []byte 90 | } 91 | -------------------------------------------------------------------------------- /farm/gitlog.txt: -------------------------------------------------------------------------------- 1 | commit d1e51a4af19092715f4ce7d8257fe5bc8f8be727 2 | Merge: 07065c3 61c3346 3 | Author: Damian Gryski 4 | Date: Wed Sep 9 19:09:13 2015 +0200 5 | 6 | Merge pull request #1 from leventov/master 7 | 8 | Fix a bug in _uo 9 | 10 | commit 61c334626e2b0489e4edf083635dca4e58138ac2 11 | Author: Roman Leventov 12 | Date: Wed Sep 9 19:58:11 2015 +0300 13 | 14 | Fix a bug in _uo 15 | 16 | commit 07065c3305f91265700d41b4c73b8b50c20b4a7e 17 | Author: Damian Gryski 18 | Date: Fri Jun 5 05:57:53 2015 +0200 19 | 20 | upgrade to farmhash v1.1 21 | 22 | commit fc41e106ee0e4394f69a56046e5c5adbaf29d912 23 | Author: Damian Gryski 24 | Date: Sun Jun 1 22:03:37 2014 +0200 25 | 26 | inline uint64 unpacking 27 | 28 | commit 13f1bc7abd99018d9775bab08e380588636b2160 29 | Author: Damian Gryski 30 | Date: Sun Jun 1 22:02:38 2014 +0200 31 | 32 | docs: link to cgo version 33 | 34 | commit 19a2bfa08edaa4286a2ad31b248e76e5ea220de9 35 | Author: Damian Gryski 36 | Date: Mon May 26 20:47:29 2014 +0200 37 | 38 | Remove uint128 from API -- we now match go-farmhash cgo bindings 39 | 40 | commit 613aa95d7a6c05995626a0137c1008c2c1f0a211 41 | Author: Damian Gryski 42 | Date: Sun May 25 09:07:48 2014 +0200 43 | 44 | add tests for fingerprint128 45 | 46 | commit 7a089a29876c43b0e9a88f3d780976d6a0b3f4b0 47 | Author: Damian Gryski 48 | Date: Sun May 25 09:07:36 2014 +0200 49 | 50 | fix overflow in fingerprint128 51 | 52 | commit ced72b5f975fbcfa7d839b4d7cc7043d9e8535f1 53 | Author: Damian Gryski 54 | Date: Sun May 25 09:05:25 2014 +0200 55 | 56 | fix accidental fallthrough on if/return 57 | 58 | commit 3a8b027f8435768cae9a164111b6d120886f2825 59 | Author: Damian Gryski 60 | Date: Sun May 25 09:03:50 2014 +0200 61 | 62 | slen needs to be signed -- we check <= 0 63 | 64 | commit f6133b835fa309a3500fdb49348e81fc6e33a523 65 | Author: Damian Gryski 66 | Date: Sun May 25 09:03:15 2014 +0200 67 | 68 | fix ordering of 128-bit hi/lo words 69 | 70 | commit dcba7e74ee0bd2e2134347ef9dfba201957a758d 71 | Author: Damian Gryski 72 | Date: Wed May 21 20:58:10 2014 +0200 73 | 74 | add fingerprinting and 128-bit hash 75 | 76 | commit 676d04c366434fd839939439b689846ab926edb8 77 | Author: Damian Gryski 78 | Date: Wed May 21 20:57:49 2014 +0200 79 | 80 | unexport cityhash internals 81 | 82 | commit c8f208760b05d8541eb58b562051ca27af07dd71 83 | Author: Damian Gryski 84 | Date: Wed May 21 20:57:07 2014 +0200 85 | 86 | deadcode-- 87 | 88 | commit bc94144ea05aea43eb90645cd6359e580fb4aa33 89 | Author: Damian Gryski 90 | Date: Wed May 21 13:55:26 2014 +0200 91 | 92 | license++ 93 | 94 | commit d84024f446ff8cb1fc8e2b9751ea6939f45adfc9 95 | Author: Damian Gryski 96 | Date: Wed May 21 13:27:56 2014 +0200 97 | 98 | unexport the internal routines 99 | 100 | commit aede7cd6ef44ea0b9ddfcf06ac75e1b50fc326aa 101 | Author: Damian Gryski 102 | Date: Wed May 21 13:21:46 2014 +0200 103 | 104 | initial commit 105 | -------------------------------------------------------------------------------- /keccak/KeccakSponge.h: -------------------------------------------------------------------------------- 1 | /* 2 | The Keccak sponge function, designed by Guido Bertoni, Joan Daemen, 3 | Michaël Peeters and Gilles Van Assche. For more information, feedback or 4 | questions, please refer to our website: http://keccak.noekeon.org/ 5 | 6 | Implementation by the designers, 7 | hereby denoted as "the implementer". 8 | 9 | To the extent possible under law, the implementer has waived all copyright 10 | and related or neighboring rights to the source code in this file. 11 | http://creativecommons.org/publicdomain/zero/1.0/ 12 | */ 13 | 14 | #ifndef _KeccakSponge_h_ 15 | #define _KeccakSponge_h_ 16 | 17 | #define KeccakPermutationSize 1600 18 | #define KeccakPermutationSizeInBytes (KeccakPermutationSize/8) 19 | #define KeccakMaximumRate 1536 20 | #define KeccakMaximumRateInBytes (KeccakMaximumRate/8) 21 | 22 | #if defined(__GNUC__) 23 | #define ALIGN __attribute__ ((aligned(32))) 24 | #elif defined(_MSC_VER) 25 | #define ALIGN __declspec(align(32)) 26 | #else 27 | #define ALIGN 28 | #endif 29 | 30 | ALIGN typedef struct spongeStateStruct { 31 | ALIGN unsigned char state[KeccakPermutationSizeInBytes]; 32 | ALIGN unsigned char dataQueue[KeccakMaximumRateInBytes]; 33 | unsigned int rate; 34 | unsigned int capacity; 35 | unsigned int bitsInQueue; 36 | unsigned int fixedOutputLength; 37 | int squeezing; 38 | unsigned int bitsAvailableForSqueezing; 39 | } spongeState; 40 | 41 | /** 42 | * Function to initialize the state of the Keccak[r, c] sponge function. 43 | * The sponge function is set to the absorbing phase. 44 | * @param state Pointer to the state of the sponge function to be initialized. 45 | * @param rate The value of the rate r. 46 | * @param capacity The value of the capacity c. 47 | * @pre One must have r+c=1600 and the rate a multiple of 64 bits in this implementation. 48 | * @return Zero if successful, 1 otherwise. 49 | */ 50 | int InitSponge(spongeState *state, unsigned int rate, unsigned int capacity); 51 | /** 52 | * Function to give input data for the sponge function to absorb. 53 | * @param state Pointer to the state of the sponge function initialized by InitSponge(). 54 | * @param data Pointer to the input data. 55 | * When @a databitLen is not a multiple of 8, the last bits of data must be 56 | * in the least significant bits of the last byte. 57 | * @param databitLen The number of input bits provided in the input data. 58 | * @pre In the previous call to Absorb(), databitLen was a multiple of 8. 59 | * @pre The sponge function must be in the absorbing phase, 60 | * i.e., Squeeze() must not have been called before. 61 | * @return Zero if successful, 1 otherwise. 62 | */ 63 | int Absorb(spongeState *state, const unsigned char *data, unsigned long long databitlen); 64 | /** 65 | * Function to squeeze output data from the sponge function. 66 | * If the sponge function was in the absorbing phase, this function 67 | * switches it to the squeezing phase. 68 | * @param state Pointer to the state of the sponge function initialized by InitSponge(). 69 | * @param output Pointer to the buffer where to store the output data. 70 | * @param outputLength The number of output bits desired. 71 | * It must be a multiple of 8. 72 | * @return Zero if successful, 1 otherwise. 73 | */ 74 | int Squeeze(spongeState *state, unsigned char *output, unsigned long long outputLength); 75 | 76 | #endif 77 | -------------------------------------------------------------------------------- /murmur3/murmur32.go: -------------------------------------------------------------------------------- 1 | package murmur3 2 | 3 | // http://code.google.com/p/guava-libraries/source/browse/guava/src/com/google/common/hash/Murmur3_32HashFunction.java 4 | 5 | import ( 6 | "hash" 7 | "unsafe" 8 | ) 9 | 10 | // Make sure interfaces are correctly implemented. 11 | var ( 12 | _ hash.Hash = new(digest32) 13 | _ hash.Hash32 = new(digest32) 14 | ) 15 | 16 | const ( 17 | c1_32 uint32 = 0xcc9e2d51 18 | c2_32 uint32 = 0x1b873593 19 | ) 20 | 21 | // digest32 represents a partial evaluation of a 32 bites hash. 22 | type digest32 struct { 23 | digest 24 | h1 uint32 // Unfinalized running hash. 25 | } 26 | 27 | func New32() hash.Hash32 { 28 | d := new(digest32) 29 | d.bmixer = d 30 | d.Reset() 31 | return d 32 | } 33 | 34 | func (d *digest32) Size() int { return 4 } 35 | 36 | func (d *digest32) reset() { d.h1 = 0 } 37 | 38 | func (d *digest32) Sum(b []byte) []byte { 39 | h := d.h1 40 | return append(b, byte(h>>24), byte(h>>16), byte(h>>8), byte(h)) 41 | } 42 | 43 | // Digest as many blocks as possible. 44 | func (d *digest32) bmix(p []byte) (tail []byte) { 45 | h1 := d.h1 46 | 47 | nblocks := len(p) / 4 48 | for i := 0; i < nblocks; i++ { 49 | k1 := *(*uint32)(unsafe.Pointer(&p[i*4])) 50 | 51 | k1 *= c1_32 52 | k1 = (k1 << 15) | (k1 >> 17) // rotl32(k1, 15) 53 | k1 *= c2_32 54 | 55 | h1 ^= k1 56 | h1 = (h1 << 13) | (h1 >> 19) // rotl32(h1, 13) 57 | h1 = h1*5 + 0xe6546b64 58 | } 59 | d.h1 = h1 60 | return p[nblocks*d.Size():] 61 | } 62 | 63 | func (d *digest32) Sum32() (h1 uint32) { 64 | 65 | h1 = d.h1 66 | 67 | var k1 uint32 68 | switch len(d.tail) & 3 { 69 | case 3: 70 | k1 ^= uint32(d.tail[2]) << 16 71 | fallthrough 72 | case 2: 73 | k1 ^= uint32(d.tail[1]) << 8 74 | fallthrough 75 | case 1: 76 | k1 ^= uint32(d.tail[0]) 77 | k1 *= c1_32 78 | k1 = (k1 << 15) | (k1 >> 17) // rotl32(k1, 15) 79 | k1 *= c2_32 80 | h1 ^= k1 81 | } 82 | 83 | h1 ^= uint32(d.clen) 84 | 85 | h1 ^= h1 >> 16 86 | h1 *= 0x85ebca6b 87 | h1 ^= h1 >> 13 88 | h1 *= 0xc2b2ae35 89 | h1 ^= h1 >> 16 90 | 91 | return h1 92 | } 93 | 94 | /* 95 | func rotl32(x uint32, r byte) uint32 { 96 | return (x << r) | (x >> (32 - r)) 97 | } 98 | */ 99 | 100 | // Sum32 returns the MurmurHash3 sum of data. It is equivalent to the 101 | // following sequence (without the extra burden and the extra allocation): 102 | // hasher := New32() 103 | // hasher.Write(data) 104 | // return hasher.Sum32() 105 | func Sum32(data []byte) uint32 { 106 | 107 | var h1 uint32 = 0 108 | 109 | nblocks := len(data) / 4 110 | var p uintptr 111 | if len(data) > 0 { 112 | p = uintptr(unsafe.Pointer(&data[0])) 113 | } 114 | p1 := p + uintptr(4*nblocks) 115 | for ; p < p1; p += 4 { 116 | k1 := *(*uint32)(unsafe.Pointer(p)) 117 | 118 | k1 *= c1_32 119 | k1 = (k1 << 15) | (k1 >> 17) // rotl32(k1, 15) 120 | k1 *= c2_32 121 | 122 | h1 ^= k1 123 | h1 = (h1 << 13) | (h1 >> 19) // rotl32(h1, 13) 124 | h1 = h1*5 + 0xe6546b64 125 | } 126 | 127 | tail := data[nblocks*4:] 128 | 129 | var k1 uint32 130 | switch len(tail) & 3 { 131 | case 3: 132 | k1 ^= uint32(tail[2]) << 16 133 | fallthrough 134 | case 2: 135 | k1 ^= uint32(tail[1]) << 8 136 | fallthrough 137 | case 1: 138 | k1 ^= uint32(tail[0]) 139 | k1 *= c1_32 140 | k1 = (k1 << 15) | (k1 >> 17) // rotl32(k1, 15) 141 | k1 *= c2_32 142 | h1 ^= k1 143 | } 144 | 145 | h1 ^= uint32(len(data)) 146 | 147 | h1 ^= h1 >> 16 148 | h1 *= 0x85ebca6b 149 | h1 ^= h1 >> 13 150 | h1 *= 0xc2b2ae35 151 | h1 ^= h1 >> 16 152 | 153 | return h1 154 | } 155 | -------------------------------------------------------------------------------- /keccak/KeccakNISTInterface.h: -------------------------------------------------------------------------------- 1 | /* 2 | The Keccak sponge function, designed by Guido Bertoni, Joan Daemen, 3 | Michaël Peeters and Gilles Van Assche. For more information, feedback or 4 | questions, please refer to our website: http://keccak.noekeon.org/ 5 | 6 | Implementation by the designers, 7 | hereby denoted as "the implementer". 8 | 9 | To the extent possible under law, the implementer has waived all copyright 10 | and related or neighboring rights to the source code in this file. 11 | http://creativecommons.org/publicdomain/zero/1.0/ 12 | */ 13 | 14 | #ifndef _KeccakNISTInterface_h_ 15 | #define _KeccakNISTInterface_h_ 16 | 17 | #include "KeccakSponge.h" 18 | 19 | typedef unsigned char BitSequence; 20 | typedef unsigned long long DataLength; 21 | typedef enum { SUCCESS = 0, FAIL = 1, BAD_HASHLEN = 2 } HashReturn; 22 | 23 | typedef spongeState hashState; 24 | 25 | /** 26 | * Function to initialize the state of the Keccak[r, c] sponge function. 27 | * The rate r and capacity c values are determined from @a hashbitlen. 28 | * @param state Pointer to the state of the sponge function to be initialized. 29 | * @param hashbitlen The desired number of output bits, 30 | * or 0 for Keccak[] with default parameters 31 | * and arbitrarily-long output. 32 | * @pre The value of hashbitlen must be one of 0, 224, 256, 384 and 512. 33 | * @return SUCCESS if successful, BAD_HASHLEN if the value of hashbitlen is incorrect. 34 | */ 35 | HashReturn Init(hashState *state, int hashbitlen); 36 | /** 37 | * Function to give input data for the sponge function to absorb. 38 | * @param state Pointer to the state of the sponge function initialized by Init(). 39 | * @param data Pointer to the input data. 40 | * When @a databitLen is not a multiple of 8, the last bits of data must be 41 | * in the most significant bits of the last byte. 42 | * @param databitLen The number of input bits provided in the input data. 43 | * @pre In the previous call to Absorb(), databitLen was a multiple of 8. 44 | * @return SUCCESS if successful, FAIL otherwise. 45 | */ 46 | HashReturn Update(hashState *state, const BitSequence *data, DataLength databitlen); 47 | /** 48 | * Function to squeeze output data from the sponge function. 49 | * If @a hashbitlen was not 0 in the call to Init(), the number of output bits is equal to @a hashbitlen. 50 | * If @a hashbitlen was 0 in the call to Init(), the output bits must be extracted using the Squeeze() function. 51 | * @param state Pointer to the state of the sponge function initialized by Init(). 52 | * @param hashval Pointer to the buffer where to store the output data. 53 | * @return SUCCESS if successful, FAIL otherwise. 54 | */ 55 | HashReturn Final(hashState *state, BitSequence *hashval); 56 | /** 57 | * Function to compute a hash using the Keccak[r, c] sponge function. 58 | * The rate r and capacity c values are determined from @a hashbitlen. 59 | * @param hashbitlen The desired number of output bits. 60 | * @param data Pointer to the input data. 61 | * When @a databitLen is not a multiple of 8, the last bits of data must be 62 | * in the most significant bits of the last byte. 63 | * @param databitLen The number of input bits provided in the input data. 64 | * @param hashval Pointer to the buffer where to store the output data. 65 | * @pre The value of hashbitlen must be one of 224, 256, 384 and 512. 66 | * @return SUCCESS if successful, BAD_HASHLEN if the value of hashbitlen is incorrect. 67 | */ 68 | HashReturn Hash(int hashbitlen, const BitSequence *data, DataLength databitlen, BitSequence *hashval); 69 | 70 | #endif 71 | -------------------------------------------------------------------------------- /siphash/hash_amd64.s: -------------------------------------------------------------------------------- 1 | // This is a translation of the gcc output of FloodyBerry's pure-C public 2 | // domain siphash implementation at https://github.com/floodyberry/siphash 3 | 4 | // func Hash(k0, k1 uint64, b []byte) uint64 5 | TEXT ·Hash(SB),4,$0-48 6 | MOVQ k0+0(FP),CX 7 | MOVQ $0x736F6D6570736575,R9 8 | MOVQ k1+8(FP),DI 9 | MOVQ $0x6C7967656E657261,BX 10 | MOVQ $0x646F72616E646F6D,AX 11 | MOVQ b_len+24(FP),DX 12 | MOVQ DX,R11 13 | MOVQ DX,R10 14 | XORQ CX,R9 15 | XORQ CX,BX 16 | MOVQ $0x7465646279746573,CX 17 | XORQ DI,AX 18 | XORQ DI,CX 19 | SHLQ $0x38,R11 20 | XORQ DI,DI 21 | MOVQ b_base+16(FP),SI 22 | ANDQ $0xFFFFFFFFFFFFFFF8,R10 23 | JE afterLoop 24 | XCHGQ AX,AX 25 | loopBody: 26 | MOVQ 0(SI)(DI*1),R8 27 | ADDQ AX,R9 28 | RORQ $0x33,AX 29 | XORQ R9,AX 30 | RORQ $0x20,R9 31 | ADDQ $0x8,DI 32 | XORQ R8,CX 33 | ADDQ CX,BX 34 | RORQ $0x30,CX 35 | XORQ BX,CX 36 | ADDQ AX,BX 37 | RORQ $0x2F,AX 38 | ADDQ CX,R9 39 | RORQ $0x2B,CX 40 | XORQ BX,AX 41 | XORQ R9,CX 42 | RORQ $0x20,BX 43 | ADDQ AX,R9 44 | ADDQ CX,BX 45 | RORQ $0x33,AX 46 | RORQ $0x30,CX 47 | XORQ R9,AX 48 | XORQ BX,CX 49 | RORQ $0x20,R9 50 | ADDQ AX,BX 51 | ADDQ CX,R9 52 | RORQ $0x2F,AX 53 | RORQ $0x2B,CX 54 | XORQ BX,AX 55 | RORQ $0x20,BX 56 | XORQ R9,CX 57 | XORQ R8,R9 58 | CMPQ R10,DI 59 | JA loopBody 60 | afterLoop: 61 | SUBQ R10,DX 62 | 63 | CMPQ DX,$0x7 64 | JA afterSwitch 65 | 66 | // no support for jump tables 67 | 68 | CMPQ DX,$0x7 69 | JE sw7 70 | 71 | CMPQ DX,$0x6 72 | JE sw6 73 | 74 | CMPQ DX,$0x5 75 | JE sw5 76 | 77 | CMPQ DX,$0x4 78 | JE sw4 79 | 80 | CMPQ DX,$0x3 81 | JE sw3 82 | 83 | CMPQ DX,$0x2 84 | JE sw2 85 | 86 | CMPQ DX,$0x1 87 | JE sw1 88 | 89 | JMP afterSwitch 90 | 91 | sw7: MOVBQZX 6(SI)(DI*1),DX 92 | SHLQ $0x30,DX 93 | ORQ DX,R11 94 | sw6: MOVBQZX 0x5(SI)(DI*1),DX 95 | SHLQ $0x28,DX 96 | ORQ DX,R11 97 | sw5: MOVBQZX 0x4(SI)(DI*1),DX 98 | SHLQ $0x20,DX 99 | ORQ DX,R11 100 | sw4: MOVBQZX 0x3(SI)(DI*1),DX 101 | SHLQ $0x18,DX 102 | ORQ DX,R11 103 | sw3: MOVBQZX 0x2(SI)(DI*1),DX 104 | SHLQ $0x10,DX 105 | ORQ DX,R11 106 | sw2: MOVBQZX 0x1(SI)(DI*1),DX 107 | SHLQ $0x8,DX 108 | ORQ DX,R11 109 | sw1: MOVBQZX 0(SI)(DI*1),DX 110 | ORQ DX,R11 111 | afterSwitch: 112 | LEAQ (AX)(R9*1),SI 113 | XORQ R11,CX 114 | RORQ $0x33,AX 115 | ADDQ CX,BX 116 | MOVQ CX,DX 117 | XORQ SI,AX 118 | RORQ $0x30,DX 119 | RORQ $0x20,SI 120 | LEAQ 0(BX)(AX*1),CX 121 | XORQ BX,DX 122 | RORQ $0x2F,AX 123 | ADDQ DX,SI 124 | RORQ $0x2B,DX 125 | XORQ CX,AX 126 | XORQ SI,DX 127 | RORQ $0x20,CX 128 | ADDQ AX,SI 129 | RORQ $0x33,AX 130 | ADDQ DX,CX 131 | XORQ SI,AX 132 | RORQ $0x30,DX 133 | RORQ $0x20,SI 134 | XORQ CX,DX 135 | ADDQ AX,CX 136 | RORQ $0x2F,AX 137 | ADDQ DX,SI 138 | XORQ CX,AX 139 | RORQ $0x2B,DX 140 | RORQ $0x20,CX 141 | XORQ SI,DX 142 | XORQ R11,SI 143 | XORB $0xFF,CL 144 | ADDQ AX,SI 145 | RORQ $0x33,AX 146 | ADDQ DX,CX 147 | RORQ $0x30,DX 148 | XORQ SI,AX 149 | XORQ CX,DX 150 | RORQ $0x20,SI 151 | ADDQ AX,CX 152 | ADDQ DX,SI 153 | RORQ $0x2F,AX 154 | RORQ $0x2B,DX 155 | XORQ CX,AX 156 | XORQ SI,DX 157 | RORQ $0x20,CX 158 | ADDQ AX,SI 159 | ADDQ DX,CX 160 | RORQ $0x33,AX 161 | RORQ $0x30,DX 162 | XORQ SI,AX 163 | RORQ $0x20,SI 164 | XORQ CX,DX 165 | ADDQ AX,CX 166 | RORQ $0x2F,AX 167 | ADDQ DX,SI 168 | RORQ $0x2B,DX 169 | XORQ CX,AX 170 | XORQ SI,DX 171 | RORQ $0x20,CX 172 | ADDQ AX,SI 173 | ADDQ DX,CX 174 | RORQ $0x33,AX 175 | RORQ $0x30,DX 176 | XORQ CX,DX 177 | XORQ SI,AX 178 | RORQ $0x20,SI 179 | ADDQ DX,SI 180 | ADDQ AX,CX 181 | RORQ $0x2F,AX 182 | XORQ CX,AX 183 | RORQ $0x2B,DX 184 | RORQ $0x20,CX 185 | XORQ SI,DX 186 | ADDQ AX,SI 187 | RORQ $0x33,AX 188 | ADDQ DX,CX 189 | XORQ SI,AX 190 | RORQ $0x30,DX 191 | XORQ CX,DX 192 | ADDQ AX,CX 193 | RORQ $0x2F,AX 194 | XORQ CX,AX 195 | RORQ $0x2B,DX 196 | RORQ $0x20,CX 197 | XORQ DX,AX 198 | XORQ CX,AX 199 | MOVQ AX,ret+40(FP) 200 | RET 201 | -------------------------------------------------------------------------------- /murmur3/murmur128.go: -------------------------------------------------------------------------------- 1 | package murmur3 2 | 3 | import ( 4 | //"encoding/binary" 5 | "hash" 6 | "unsafe" 7 | ) 8 | 9 | const ( 10 | c1_128 = 0x87c37b91114253d5 11 | c2_128 = 0x4cf5ad432745937f 12 | ) 13 | 14 | // Make sure interfaces are correctly implemented. 15 | var ( 16 | _ hash.Hash = new(digest128) 17 | _ Hash128 = new(digest128) 18 | _ bmixer = new(digest128) 19 | ) 20 | 21 | // Hack: the standard api doesn't define any Hash128 interface. 22 | type Hash128 interface { 23 | hash.Hash 24 | Sum128() (uint64, uint64) 25 | } 26 | 27 | // digest128 represents a partial evaluation of a 128 bites hash. 28 | type digest128 struct { 29 | digest 30 | h1 uint64 // Unfinalized running hash part 1. 31 | h2 uint64 // Unfinalized running hash part 2. 32 | } 33 | 34 | func New128() Hash128 { 35 | d := new(digest128) 36 | d.bmixer = d 37 | d.Reset() 38 | return d 39 | } 40 | 41 | func (d *digest128) Size() int { return 16 } 42 | 43 | func (d *digest128) reset() { d.h1, d.h2 = 0, 0 } 44 | 45 | func (d *digest128) Sum(b []byte) []byte { 46 | h1, h2 := d.h1, d.h2 47 | return append(b, 48 | byte(h1>>56), byte(h1>>48), byte(h1>>40), byte(h1>>32), 49 | byte(h1>>24), byte(h1>>16), byte(h1>>8), byte(h1), 50 | 51 | byte(h2>>56), byte(h2>>48), byte(h2>>40), byte(h2>>32), 52 | byte(h2>>24), byte(h2>>16), byte(h2>>8), byte(h2), 53 | ) 54 | } 55 | 56 | func (d *digest128) bmix(p []byte) (tail []byte) { 57 | h1, h2 := d.h1, d.h2 58 | 59 | nblocks := len(p) / 16 60 | for i := 0; i < nblocks; i++ { 61 | t := (*[2]uint64)(unsafe.Pointer(&p[i*16])) 62 | k1, k2 := t[0], t[1] 63 | 64 | k1 *= c1_128 65 | k1 = (k1 << 31) | (k1 >> 33) // rotl64(k1, 31) 66 | k1 *= c2_128 67 | h1 ^= k1 68 | 69 | h1 = (h1 << 27) | (h1 >> 37) // rotl64(h1, 27) 70 | h1 += h2 71 | h1 = h1*5 + 0x52dce729 72 | 73 | k2 *= c2_128 74 | k2 = (k2 << 33) | (k2 >> 31) // rotl64(k2, 33) 75 | k2 *= c1_128 76 | h2 ^= k2 77 | 78 | h2 = (h2 << 31) | (h2 >> 33) // rotl64(h2, 31) 79 | h2 += h1 80 | h2 = h2*5 + 0x38495ab5 81 | } 82 | d.h1, d.h2 = h1, h2 83 | return p[nblocks*d.Size():] 84 | } 85 | 86 | func (d *digest128) Sum128() (h1, h2 uint64) { 87 | 88 | h1, h2 = d.h1, d.h2 89 | 90 | var k1, k2 uint64 91 | switch len(d.tail) & 15 { 92 | case 15: 93 | k2 ^= uint64(d.tail[14]) << 48 94 | fallthrough 95 | case 14: 96 | k2 ^= uint64(d.tail[13]) << 40 97 | fallthrough 98 | case 13: 99 | k2 ^= uint64(d.tail[12]) << 32 100 | fallthrough 101 | case 12: 102 | k2 ^= uint64(d.tail[11]) << 24 103 | fallthrough 104 | case 11: 105 | k2 ^= uint64(d.tail[10]) << 16 106 | fallthrough 107 | case 10: 108 | k2 ^= uint64(d.tail[9]) << 8 109 | fallthrough 110 | case 9: 111 | k2 ^= uint64(d.tail[8]) << 0 112 | 113 | k2 *= c2_128 114 | k2 = (k2 << 33) | (k2 >> 31) // rotl64(k2, 33) 115 | k2 *= c1_128 116 | h2 ^= k2 117 | 118 | fallthrough 119 | 120 | case 8: 121 | k1 ^= uint64(d.tail[7]) << 56 122 | fallthrough 123 | case 7: 124 | k1 ^= uint64(d.tail[6]) << 48 125 | fallthrough 126 | case 6: 127 | k1 ^= uint64(d.tail[5]) << 40 128 | fallthrough 129 | case 5: 130 | k1 ^= uint64(d.tail[4]) << 32 131 | fallthrough 132 | case 4: 133 | k1 ^= uint64(d.tail[3]) << 24 134 | fallthrough 135 | case 3: 136 | k1 ^= uint64(d.tail[2]) << 16 137 | fallthrough 138 | case 2: 139 | k1 ^= uint64(d.tail[1]) << 8 140 | fallthrough 141 | case 1: 142 | k1 ^= uint64(d.tail[0]) << 0 143 | k1 *= c1_128 144 | k1 = (k1 << 31) | (k1 >> 33) // rotl64(k1, 31) 145 | k1 *= c2_128 146 | h1 ^= k1 147 | } 148 | 149 | h1 ^= uint64(d.clen) 150 | h2 ^= uint64(d.clen) 151 | 152 | h1 += h2 153 | h2 += h1 154 | 155 | h1 = fmix64(h1) 156 | h2 = fmix64(h2) 157 | 158 | h1 += h2 159 | h2 += h1 160 | 161 | return h1, h2 162 | } 163 | 164 | func fmix64(k uint64) uint64 { 165 | k ^= k >> 33 166 | k *= 0xff51afd7ed558ccd 167 | k ^= k >> 33 168 | k *= 0xc4ceb9fe1a85ec53 169 | k ^= k >> 33 170 | return k 171 | } 172 | 173 | /* 174 | func rotl64(x uint64, r byte) uint64 { 175 | return (x << r) | (x >> (64 - r)) 176 | } 177 | */ 178 | 179 | // Sum128 returns the MurmurHash3 sum of data. It is equivalent to the 180 | // following sequence (without the extra burden and the extra allocation): 181 | // hasher := New128() 182 | // hasher.Write(data) 183 | // return hasher.Sum128() 184 | func Sum128(data []byte) (h1 uint64, h2 uint64) { 185 | d := &digest128{h1: 0, h2: 0} 186 | d.tail = d.bmix(data) 187 | d.clen = len(data) 188 | return d.Sum128() 189 | } 190 | -------------------------------------------------------------------------------- /siphash/hash.go: -------------------------------------------------------------------------------- 1 | // +build !amd64 appengine 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 | 10 | package 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. 14 | func 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 | -------------------------------------------------------------------------------- /sbox/sbox.go: -------------------------------------------------------------------------------- 1 | // Copyright © 2014 Lawrence E. Bakst. All rights reserved. 2 | 3 | package sbox 4 | 5 | import "leb.io/hashland/nhash" 6 | 7 | var SBoxTable = [256]uint32{ 8 | 0x4660c395, 0x3baba6c5, 0x27ec605b, 0xdfc1d81a, 0xaaac4406, 0x3783e9b8, 0xa4e87c68, 0x62dc1b2a, 9 | 0xa8830d34, 0x10a56307, 0x4ba469e3, 0x54836450, 0x1b0223d4, 0x23312e32, 0xc04e13fe, 0x3b3d61fa, 10 | 0xdab2d0ea, 0x297286b1, 0x73dbf93f, 0x6bb1158b, 0x46867fe2, 0xb7fb5313, 0x3146f063, 0x4fd4c7cb, 11 | 0xa59780fa, 0x9fa38c24, 0x38c63986, 0xa0bac49f, 0xd47d3386, 0x49f44707, 0xa28dea30, 0xd0f30e6d, 12 | 0xd5ca7704, 0x934698e3, 0x1a1ddd6d, 0xfa026c39, 0xd72f0fe6, 0x4d52eb70, 0xe99126df, 0xdfdaed86, 13 | 0x4f649da8, 0x427212bb, 0xc728b983, 0x7ca5d563, 0x5e6164e5, 0xe41d3a24, 0x10018a23, 0x5a12e111, 14 | 0x999ebc05, 0xf1383400, 0x50b92a7c, 0xa37f7577, 0x2c126291, 0x9daf79b2, 0xdea086b1, 0x85b1f03d, 15 | 0x598ce687, 0xf3f5f6b9, 0xe55c5c74, 0x791733af, 0x39954ea8, 0xafcff761, 0x5fea64f1, 0x216d43b4, 16 | 0xd039f8c1, 0xa6cf1125, 0xc14b7939, 0xb6ac7001, 0x138a2eff, 0x2f7875d6, 0xfe298e40, 0x4a3fad3b, 17 | 0x066207fd, 0x8d4dd630, 0x96998973, 0xe656ac56, 0xbb2df109, 0x0ee1ec32, 0x03673d6c, 0xd20fb97d, 18 | 0x2c09423c, 0x093eb555, 0xab77c1e2, 0x64607bf2, 0x945204bd, 0xe8819613, 0xb59de0e3, 0x5df7fc9a, 19 | 0x82542258, 0xfb0ee357, 0xda2a4356, 0x5c97ab61, 0x8076e10d, 0x48e4b3cc, 0x7c28ec12, 0xb17986e1, 20 | 0x01735836, 0x1b826322, 0x6602a990, 0x7c1cef68, 0xe102458e, 0xa5564a67, 0x1136b393, 0x98dc0ea1, 21 | 0x3b6f59e5, 0x9efe981d, 0x35fafbe0, 0xc9949ec2, 0x62c765f9, 0x510cab26, 0xbe071300, 0x7ee1d449, 22 | 0xcc71beef, 0xfbb4284e, 0xbfc02ce7, 0xdf734c93, 0x2f8cebcd, 0xfeedc6ab, 0x5476ee54, 0xbd2b5ff9, 23 | 0xf4fd0352, 0x67f9d6ea, 0x7b70db05, 0x5a5f5310, 0x482dd7aa, 0xa0a66735, 0x321ae71f, 0x8e8ad56c, 24 | 0x27a509c3, 0x1690b261, 0x4494b132, 0xc43a42a7, 0x3f60a7a6, 0xd63779ff, 0xe69c1659, 0xd15972c8, 25 | 0x5f6cdb0c, 0xb9415af2, 0x1261ad8d, 0xb70a6135, 0x52ceda5e, 0xd4591dc3, 0x442b793c, 0xe50e2dee, 26 | 0x6f90fc79, 0xd9ecc8f9, 0x063dd233, 0x6cf2e985, 0xe62cfbe9, 0x3466e821, 0x2c8377a2, 0x00b9f14e, 27 | 0x237c4751, 0x40d4a33b, 0x919df7e8, 0xa16991a4, 0xc5295033, 0x5c507944, 0x89510e2b, 0xb5f7d902, 28 | 0xd2d439a6, 0xc23e5216, 0xd52d9de3, 0x534a5e05, 0x762e73d4, 0x3c147760, 0x2d189706, 0x20aa0564, 29 | 0xb07bbc3b, 0x8183e2de, 0xebc28889, 0xf839ed29, 0x532278f7, 0x41f8b31b, 0x762e89c1, 0xa1e71830, 30 | 0xac049bfc, 0x9b7f839c, 0x8fd9208d, 0x2d2402ed, 0xf1f06670, 0x2711d695, 0x5b9e8fe4, 0xdc935762, 31 | 0xa56b794f, 0xd8666b88, 0x6872c274, 0xbc603be2, 0x2196689b, 0x5b2b5f7a, 0x00c77076, 0x16bfa292, 32 | 0xc2f86524, 0xdd92e83e, 0xab60a3d4, 0x92daf8bd, 0x1fe14c62, 0xf0ff82cc, 0xc0ed8d0a, 0x64356e4d, 33 | 0x7e996b28, 0x81aad3e8, 0x05a22d56, 0xc4b25d4f, 0x5e3683e5, 0x811c2881, 0x124b1041, 0xdb1b4f02, 34 | 0x5a72b5cc, 0x07f8d94e, 0xe5740463, 0x498632ad, 0x7357ffb1, 0x0dddd380, 0x3d095486, 0x2569b0a9, 35 | 0xd6e054ae, 0x14a47e22, 0x73ec8dcc, 0x004968cf, 0xe0c3a853, 0xc9b50a03, 0xe1b0eb17, 0x57c6f281, 36 | 0xc9f9377d, 0x43e03612, 0x9a0c4554, 0xbb2d83ff, 0xa818ffee, 0xf407db87, 0x175e3847, 0x5597168f, 37 | 0xd3d547a7, 0x78f3157c, 0xfc750f20, 0x9880a1c6, 0x1af41571, 0x95d01dfc, 0xa3968d62, 0xeae03cf8, 38 | 0x02ee4662, 0x5f1943ff, 0x252d9d1c, 0x6b718887, 0xe052f724, 0x4cefa30b, 0xdcc31a00, 0xe4d0024d, 39 | 0xdbb4534a, 0xce01f5c8, 0x0c072b61, 0x5d59736a, 0x60291da4, 0x1fbe2c71, 0x2f11d09c, 0x9dce266a, 40 | } 41 | 42 | func Sbox(key []byte, seed uint32) uint32 { 43 | l := len(key) 44 | h := uint32(l) + seed 45 | for ; (l & ^1) != 0; l -= 2 { 46 | h = (((h ^ SBoxTable[key[0]]) * 3) ^ SBoxTable[key[1]]) * 3 47 | key = key[2:] 48 | } 49 | if l&1 != 0 { 50 | h = (h ^ SBoxTable[key[0]]) * 3 51 | } 52 | h += (h >> 22) ^ (h << 4) 53 | return h 54 | } 55 | 56 | type State struct { 57 | hash uint32 58 | seed uint32 59 | } 60 | 61 | // New returns a new hash.HashF32 interface that computes a 32 bit CrapWow hash. 62 | func New(seed uint32) nhash.HashF32 { 63 | s := new(State) 64 | s.seed = seed 65 | return s 66 | } 67 | 68 | // The size of an jenkins3 32 bit hash in bytes. 69 | const Size = 4 70 | 71 | // Return the size of the resulting hash. 72 | func (s *State) Size() int { return Size } 73 | 74 | // Return the blocksize of the hash which in this case is 8 bytes. 75 | func (s *State) BlockSize() int { return 2 } 76 | 77 | // Return the maximum number of seed bypes required. 78 | func (s *State) NumSeedBytes() int { 79 | return 4 80 | } 81 | 82 | // retunrs the number of bits the hash function outputs 83 | func (s *State) HashSizeInBits() int { 84 | return 32 85 | } 86 | 87 | func (s *State) Hash32(b []byte, seeds ...uint32) uint32 { 88 | if len(seeds) > 0 { 89 | s.seed = seeds[0] 90 | } 91 | s.hash = Sbox(b, s.seed) 92 | return s.hash 93 | } 94 | -------------------------------------------------------------------------------- /metro/metro64.go: -------------------------------------------------------------------------------- 1 | package metro 2 | 3 | import "encoding/binary" 4 | 5 | func rotate_right(v uint64, k uint) uint64 { 6 | return (v >> k) | (v << (64 - k)) 7 | } 8 | 9 | func Hash64_1(key []byte, seed uint32) uint64 { 10 | 11 | const k0 uint64 = 0xC83A91E1 12 | const k1 uint64 = 0x8648DBDB 13 | const k2 uint64 = 0x7BDEC03B 14 | const k3 uint64 = 0x2F5870A5 15 | 16 | ptr := key 17 | 18 | hash := (uint64(seed)+k2)*k0 + uint64(len(key)) 19 | 20 | if len(ptr) >= 32 { 21 | v := [4]uint64{hash, hash, hash, hash} 22 | 23 | for len(ptr) >= 32 { 24 | v[0] += binary.LittleEndian.Uint64(ptr) * k0 25 | ptr = ptr[8:] 26 | v[0] = rotate_right(v[0], 29) + v[2] 27 | v[1] += binary.LittleEndian.Uint64(ptr) * k1 28 | ptr = ptr[8:] 29 | v[1] = rotate_right(v[1], 29) + v[3] 30 | v[2] += binary.LittleEndian.Uint64(ptr) * k2 31 | ptr = ptr[8:] 32 | v[2] = rotate_right(v[2], 29) + v[0] 33 | v[3] += binary.LittleEndian.Uint64(ptr) * k3 34 | ptr = ptr[8:] 35 | v[3] = rotate_right(v[3], 29) + v[1] 36 | } 37 | 38 | v[2] ^= rotate_right(((v[0]+v[3])*k0)+v[1], 33) * k1 39 | v[3] ^= rotate_right(((v[1]+v[2])*k1)+v[0], 33) * k0 40 | v[0] ^= rotate_right(((v[0]+v[2])*k0)+v[3], 33) * k1 41 | v[1] ^= rotate_right(((v[1]+v[3])*k1)+v[2], 33) * k0 42 | hash += v[0] ^ v[1] 43 | } 44 | 45 | if len(ptr) >= 16 { 46 | v0 := hash + (binary.LittleEndian.Uint64(ptr) * k0) 47 | ptr = ptr[8:] 48 | v0 = rotate_right(v0, 33) * k1 49 | v1 := hash + (binary.LittleEndian.Uint64(ptr) * k1) 50 | ptr = ptr[8:] 51 | v1 = rotate_right(v1, 33) * k2 52 | v0 ^= rotate_right(v0*k0, 35) + v1 53 | v1 ^= rotate_right(v1*k3, 35) + v0 54 | hash += v1 55 | } 56 | 57 | if len(ptr) >= 8 { 58 | hash += binary.LittleEndian.Uint64(ptr) * k3 59 | ptr = ptr[8:] 60 | hash ^= rotate_right(hash, 33) * k1 61 | } 62 | 63 | if len(ptr) > 4 { 64 | hash += uint64(binary.LittleEndian.Uint32(ptr)) * k3 65 | ptr = ptr[4:] 66 | hash ^= rotate_right(hash, 15) * k1 67 | } 68 | 69 | if len(ptr) >= 2 { 70 | hash += uint64(binary.LittleEndian.Uint16(ptr)) * k3 71 | ptr = ptr[2:] 72 | hash ^= rotate_right(hash, 13) * k1 73 | } 74 | 75 | if len(ptr) >= 1 { 76 | hash += uint64(ptr[0]) * k3 77 | hash ^= rotate_right(hash, 25) * k1 78 | } 79 | 80 | hash ^= rotate_right(hash, 33) 81 | hash *= k0 82 | hash ^= rotate_right(hash, 33) 83 | 84 | return hash 85 | } 86 | 87 | func Hash64_2(key []byte, seed uint32) uint64 { 88 | const k0 uint64 = 0xD6D018F5 89 | const k1 uint64 = 0xA2AA033B 90 | const k2 uint64 = 0x62992FC1 91 | const k3 uint64 = 0x30BC5B29 92 | 93 | ptr := key 94 | 95 | hash := (uint64(seed)+k2)*k0 + uint64(len(key)) 96 | 97 | if len(ptr) >= 32 { 98 | v := [4]uint64{hash, hash, hash, hash} 99 | 100 | for len(ptr) >= 32 { 101 | v[0] += binary.LittleEndian.Uint64(ptr) * k0 102 | ptr = ptr[8:] 103 | v[0] = rotate_right(v[0], 29) + v[2] 104 | v[1] += binary.LittleEndian.Uint64(ptr) * k1 105 | ptr = ptr[8:] 106 | v[1] = rotate_right(v[1], 29) + v[3] 107 | v[2] += binary.LittleEndian.Uint64(ptr) * k2 108 | ptr = ptr[8:] 109 | v[2] = rotate_right(v[2], 29) + v[0] 110 | v[3] += binary.LittleEndian.Uint64(ptr) * k3 111 | ptr = ptr[8:] 112 | v[3] = rotate_right(v[3], 29) + v[1] 113 | } 114 | 115 | v[2] ^= rotate_right(((v[0]+v[3])*k0)+v[1], 30) * k1 116 | v[3] ^= rotate_right(((v[1]+v[2])*k1)+v[0], 30) * k0 117 | v[0] ^= rotate_right(((v[0]+v[2])*k0)+v[3], 30) * k1 118 | v[1] ^= rotate_right(((v[1]+v[3])*k1)+v[2], 30) * k0 119 | hash += v[0] ^ v[1] 120 | } 121 | 122 | if len(ptr) >= 16 { 123 | v0 := hash + (binary.LittleEndian.Uint64(ptr) * k2) 124 | ptr = ptr[8:] 125 | v0 = rotate_right(v0, 29) * k3 126 | v1 := hash + (binary.LittleEndian.Uint64(ptr) * k2) 127 | ptr = ptr[8:] 128 | v1 = rotate_right(v1, 29) * k3 129 | v0 ^= rotate_right(v0*k0, 34) + v1 130 | v1 ^= rotate_right(v1*k3, 34) + v0 131 | hash += v1 132 | } 133 | 134 | if len(ptr) >= 8 { 135 | hash += binary.LittleEndian.Uint64(ptr) * k3 136 | ptr = ptr[8:] 137 | hash ^= rotate_right(hash, 36) * k1 138 | } 139 | 140 | if len(ptr) >= 4 { 141 | hash += uint64(binary.LittleEndian.Uint32(ptr)) * k3 142 | ptr = ptr[4:] 143 | hash ^= rotate_right(hash, 15) * k1 144 | } 145 | 146 | if len(ptr) >= 2 { 147 | hash += uint64(binary.LittleEndian.Uint16(ptr)) * k3 148 | ptr = ptr[2:] 149 | hash ^= rotate_right(hash, 15) * k1 150 | } 151 | 152 | if len(ptr) >= 1 { 153 | hash += uint64(ptr[0]) * k3 154 | hash ^= rotate_right(hash, 23) * k1 155 | } 156 | 157 | hash ^= rotate_right(hash, 28) 158 | hash *= k0 159 | hash ^= rotate_right(hash, 29) 160 | 161 | return hash 162 | } 163 | -------------------------------------------------------------------------------- /farm/farmhashna.go: -------------------------------------------------------------------------------- 1 | package farm 2 | 3 | func shiftMix(val uint64) uint64 { 4 | return val ^ (val >> 47) 5 | } 6 | 7 | func hashLen16(u, v uint64) uint64 { 8 | return hash128to64(uint128{u, v}) 9 | } 10 | 11 | func hashLen16Mul(u, v, mul uint64) uint64 { 12 | // Murmur-inspired hashing. 13 | a := (u ^ v) * mul 14 | a ^= (a >> 47) 15 | b := (v ^ a) * mul 16 | b ^= (b >> 47) 17 | b *= mul 18 | return b 19 | } 20 | 21 | func hashLen0to16(s []byte) uint64 { 22 | slen := uint64(len(s)) 23 | if slen >= 8 { 24 | mul := k2 + slen*2 25 | a := fetch64(s, 0) + k2 26 | b := fetch64(s, int(slen-8)) 27 | c := rotate64(b, 37)*mul + a 28 | d := (rotate64(a, 25) + b) * mul 29 | return hashLen16Mul(c, d, mul) 30 | } 31 | 32 | if slen >= 4 { 33 | mul := k2 + slen*2 34 | a := fetch32(s, 0) 35 | return hashLen16Mul(uint64(slen)+(uint64(a)<<3), uint64(fetch32(s, int(slen-4))), mul) 36 | } 37 | if slen > 0 { 38 | a := s[0] 39 | b := s[slen>>1] 40 | c := s[slen-1] 41 | y := uint32(a) + (uint32(b) << 8) 42 | z := uint32(slen) + (uint32(c) << 2) 43 | return shiftMix(uint64(y)*k2^uint64(z)*k0) * k2 44 | } 45 | return k2 46 | } 47 | 48 | // This probably works well for 16-byte strings as well, but it may be overkill 49 | // in that case. 50 | func hashLen17to32(s []byte) uint64 { 51 | slen := len(s) 52 | mul := k2 + uint64(slen*2) 53 | a := fetch64(s, 0) * k1 54 | b := fetch64(s, 8) 55 | c := fetch64(s, slen-8) * mul 56 | d := fetch64(s, slen-16) * k2 57 | return hashLen16Mul(rotate64(a+b, 43)+rotate64(c, 30)+d, a+rotate64(b+k2, 18)+c, mul) 58 | } 59 | 60 | // Return a 16-byte hash for 48 bytes. Quick and dirty. 61 | // Callers do best to use "random-looking" values for a and b. 62 | func weakHashLen32WithSeedsWords(w, x, y, z, a, b uint64) (uint64, uint64) { 63 | a += w 64 | b = rotate64(b+a+z, 21) 65 | c := a 66 | a += x 67 | a += y 68 | b += rotate64(a, 44) 69 | return a + z, b + c 70 | } 71 | 72 | // Return a 16-byte hash for s[0] ... s[31], a, and b. Quick and dirty. 73 | func weakHashLen32WithSeeds(s []byte, a, b uint64) (uint64, uint64) { 74 | return weakHashLen32WithSeedsWords(fetch64(s, 0), 75 | fetch64(s, 8), 76 | fetch64(s, 16), 77 | fetch64(s, 24), 78 | a, 79 | b) 80 | } 81 | 82 | // Return an 8-byte hash for 33 to 64 bytes. 83 | func hashLen33to64(s []byte) uint64 { 84 | slen := len(s) 85 | mul := k2 + uint64(slen)*2 86 | a := fetch64(s, 0) * k2 87 | b := fetch64(s, 8) 88 | c := fetch64(s, slen-8) * mul 89 | d := fetch64(s, slen-16) * k2 90 | y := rotate64(a+b, 43) + rotate64(c, 30) + d 91 | z := hashLen16Mul(y, a+rotate64(b+k2, 18)+c, mul) 92 | e := fetch64(s, 16) * mul 93 | f := fetch64(s, 24) 94 | g := (y + fetch64(s, slen-32)) * mul 95 | h := (z + fetch64(s, slen-24)) * mul 96 | return hashLen16Mul(rotate64(e+f, 43)+rotate64(g, 30)+h, e+rotate64(f+a, 18)+g, mul) 97 | } 98 | 99 | func naHash64(s []byte) uint64 { 100 | slen := len(s) 101 | const seed uint64 = 81 102 | if slen <= 32 { 103 | if slen <= 16 { 104 | return hashLen0to16(s) 105 | } else { 106 | return hashLen17to32(s) 107 | } 108 | } else if slen <= 64 { 109 | return hashLen33to64(s) 110 | } 111 | 112 | // For strings over 64 bytes we loop. Internal state consists of 113 | // 56 bytes: v, w, x, y, and z. 114 | x := seed 115 | y := uint64(2480279821605975764) // == seed * k1 + 113; This overflows uint64 and is a compile error, so we expand the constant by hand 116 | z := shiftMix(y*k2+113) * k2 117 | var v1, v2 uint64 118 | var w1, w2 uint64 119 | x = x*k2 + fetch64(s, 0) 120 | 121 | // Set end so that after the loop we have 1 to 64 bytes left to process. 122 | endIdx := ((slen - 1) / 64) * 64 123 | last64Idx := endIdx + ((slen - 1) & 63) - 63 124 | last64 := s[last64Idx:] 125 | for len(s) > 64 { 126 | x = rotate64(x+y+v1+fetch64(s, 8), 37) * k1 127 | y = rotate64(y+v2+fetch64(s, 48), 42) * k1 128 | x ^= w2 129 | y += v1 + fetch64(s, 40) 130 | z = rotate64(z+w1, 33) * k1 131 | v1, v2 = weakHashLen32WithSeeds(s, v2*k1, x+w1) 132 | w1, w2 = weakHashLen32WithSeeds(s[32:], z+w2, y+fetch64(s, 16)) 133 | z, x = x, z 134 | s = s[64:] 135 | } 136 | mul := k1 + ((z & 0xff) << 1) 137 | 138 | // Make s point to the last 64 bytes of input. 139 | s = last64 140 | w1 += ((uint64(slen) - 1) & 63) 141 | v1 += w1 142 | w1 += v1 143 | x = rotate64(x+y+v1+fetch64(s, 8), 37) * mul 144 | y = rotate64(y+v2+fetch64(s, 48), 42) * mul 145 | x ^= w2 * 9 146 | y += v1*9 + fetch64(s, 40) 147 | z = rotate64(z+w1, 33) * mul 148 | v1, v2 = weakHashLen32WithSeeds(s, v2*mul, x+w1) 149 | w1, w2 = weakHashLen32WithSeeds(s[32:], z+w2, y+fetch64(s, 16)) 150 | z, x = x, z 151 | return hashLen16Mul(hashLen16Mul(v1, w1, mul)+shiftMix(y)*k0+z, 152 | hashLen16Mul(v2, w2, mul)+x, 153 | mul) 154 | } 155 | 156 | func naHash64WithSeed(s []byte, seed uint64) uint64 { 157 | return naHash64WithSeeds(s, k2, seed) 158 | } 159 | 160 | func naHash64WithSeeds(s []byte, seed0, seed1 uint64) uint64 { 161 | return hashLen16(naHash64(s)-seed0, seed1) 162 | } 163 | -------------------------------------------------------------------------------- /keccak/KeccakF-1600-unrolling.macros.h: -------------------------------------------------------------------------------- 1 | /* 2 | The Keccak sponge function, designed by Guido Bertoni, Joan Daemen, 3 | Michaël Peeters and Gilles Van Assche. For more information, feedback or 4 | questions, please refer to our website: http://keccak.noekeon.org/ 5 | 6 | Implementation by the designers, 7 | hereby denoted as "the implementer". 8 | 9 | To the extent possible under law, the implementer has waived all copyright 10 | and related or neighboring rights to the source code in this file. 11 | http://creativecommons.org/publicdomain/zero/1.0/ 12 | */ 13 | 14 | #if (Unrolling == 24) 15 | #define rounds \ 16 | prepareTheta \ 17 | thetaRhoPiChiIotaPrepareTheta( 0, A, E) \ 18 | thetaRhoPiChiIotaPrepareTheta( 1, E, A) \ 19 | thetaRhoPiChiIotaPrepareTheta( 2, A, E) \ 20 | thetaRhoPiChiIotaPrepareTheta( 3, E, A) \ 21 | thetaRhoPiChiIotaPrepareTheta( 4, A, E) \ 22 | thetaRhoPiChiIotaPrepareTheta( 5, E, A) \ 23 | thetaRhoPiChiIotaPrepareTheta( 6, A, E) \ 24 | thetaRhoPiChiIotaPrepareTheta( 7, E, A) \ 25 | thetaRhoPiChiIotaPrepareTheta( 8, A, E) \ 26 | thetaRhoPiChiIotaPrepareTheta( 9, E, A) \ 27 | thetaRhoPiChiIotaPrepareTheta(10, A, E) \ 28 | thetaRhoPiChiIotaPrepareTheta(11, E, A) \ 29 | thetaRhoPiChiIotaPrepareTheta(12, A, E) \ 30 | thetaRhoPiChiIotaPrepareTheta(13, E, A) \ 31 | thetaRhoPiChiIotaPrepareTheta(14, A, E) \ 32 | thetaRhoPiChiIotaPrepareTheta(15, E, A) \ 33 | thetaRhoPiChiIotaPrepareTheta(16, A, E) \ 34 | thetaRhoPiChiIotaPrepareTheta(17, E, A) \ 35 | thetaRhoPiChiIotaPrepareTheta(18, A, E) \ 36 | thetaRhoPiChiIotaPrepareTheta(19, E, A) \ 37 | thetaRhoPiChiIotaPrepareTheta(20, A, E) \ 38 | thetaRhoPiChiIotaPrepareTheta(21, E, A) \ 39 | thetaRhoPiChiIotaPrepareTheta(22, A, E) \ 40 | thetaRhoPiChiIota(23, E, A) \ 41 | copyToState(state, A) 42 | #elif (Unrolling == 12) 43 | #define rounds \ 44 | prepareTheta \ 45 | for(i=0; i<24; i+=12) { \ 46 | thetaRhoPiChiIotaPrepareTheta(i , A, E) \ 47 | thetaRhoPiChiIotaPrepareTheta(i+ 1, E, A) \ 48 | thetaRhoPiChiIotaPrepareTheta(i+ 2, A, E) \ 49 | thetaRhoPiChiIotaPrepareTheta(i+ 3, E, A) \ 50 | thetaRhoPiChiIotaPrepareTheta(i+ 4, A, E) \ 51 | thetaRhoPiChiIotaPrepareTheta(i+ 5, E, A) \ 52 | thetaRhoPiChiIotaPrepareTheta(i+ 6, A, E) \ 53 | thetaRhoPiChiIotaPrepareTheta(i+ 7, E, A) \ 54 | thetaRhoPiChiIotaPrepareTheta(i+ 8, A, E) \ 55 | thetaRhoPiChiIotaPrepareTheta(i+ 9, E, A) \ 56 | thetaRhoPiChiIotaPrepareTheta(i+10, A, E) \ 57 | thetaRhoPiChiIotaPrepareTheta(i+11, E, A) \ 58 | } \ 59 | copyToState(state, A) 60 | #elif (Unrolling == 8) 61 | #define rounds \ 62 | prepareTheta \ 63 | for(i=0; i<24; i+=8) { \ 64 | thetaRhoPiChiIotaPrepareTheta(i , A, E) \ 65 | thetaRhoPiChiIotaPrepareTheta(i+1, E, A) \ 66 | thetaRhoPiChiIotaPrepareTheta(i+2, A, E) \ 67 | thetaRhoPiChiIotaPrepareTheta(i+3, E, A) \ 68 | thetaRhoPiChiIotaPrepareTheta(i+4, A, E) \ 69 | thetaRhoPiChiIotaPrepareTheta(i+5, E, A) \ 70 | thetaRhoPiChiIotaPrepareTheta(i+6, A, E) \ 71 | thetaRhoPiChiIotaPrepareTheta(i+7, E, A) \ 72 | } \ 73 | copyToState(state, A) 74 | #elif (Unrolling == 6) 75 | #define rounds \ 76 | prepareTheta \ 77 | for(i=0; i<24; i+=6) { \ 78 | thetaRhoPiChiIotaPrepareTheta(i , A, E) \ 79 | thetaRhoPiChiIotaPrepareTheta(i+1, E, A) \ 80 | thetaRhoPiChiIotaPrepareTheta(i+2, A, E) \ 81 | thetaRhoPiChiIotaPrepareTheta(i+3, E, A) \ 82 | thetaRhoPiChiIotaPrepareTheta(i+4, A, E) \ 83 | thetaRhoPiChiIotaPrepareTheta(i+5, E, A) \ 84 | } \ 85 | copyToState(state, A) 86 | #elif (Unrolling == 4) 87 | #define rounds \ 88 | prepareTheta \ 89 | for(i=0; i<24; i+=4) { \ 90 | thetaRhoPiChiIotaPrepareTheta(i , A, E) \ 91 | thetaRhoPiChiIotaPrepareTheta(i+1, E, A) \ 92 | thetaRhoPiChiIotaPrepareTheta(i+2, A, E) \ 93 | thetaRhoPiChiIotaPrepareTheta(i+3, E, A) \ 94 | } \ 95 | copyToState(state, A) 96 | #elif (Unrolling == 3) 97 | #define rounds \ 98 | prepareTheta \ 99 | for(i=0; i<24; i+=3) { \ 100 | thetaRhoPiChiIotaPrepareTheta(i , A, E) \ 101 | thetaRhoPiChiIotaPrepareTheta(i+1, E, A) \ 102 | thetaRhoPiChiIotaPrepareTheta(i+2, A, E) \ 103 | copyStateVariables(A, E) \ 104 | } \ 105 | copyToState(state, A) 106 | #elif (Unrolling == 2) 107 | #define rounds \ 108 | prepareTheta \ 109 | for(i=0; i<24; i+=2) { \ 110 | thetaRhoPiChiIotaPrepareTheta(i , A, E) \ 111 | thetaRhoPiChiIotaPrepareTheta(i+1, E, A) \ 112 | } \ 113 | copyToState(state, A) 114 | #elif (Unrolling == 1) 115 | #define rounds \ 116 | prepareTheta \ 117 | for(i=0; i<24; i++) { \ 118 | thetaRhoPiChiIotaPrepareTheta(i , A, E) \ 119 | copyStateVariables(A, E) \ 120 | } \ 121 | copyToState(state, A) 122 | #else 123 | #error "Unrolling is not correctly specified!" 124 | #endif 125 | -------------------------------------------------------------------------------- /keccakpg/keccak.go: -------------------------------------------------------------------------------- 1 | // Package keccak implements the Keccak (SHA-3) hash algorithm. 2 | // http://keccak.noekeon.org. 3 | package keccakpg 4 | 5 | import ( 6 | _ "fmt" 7 | "hash" 8 | ) 9 | 10 | const stdRounds = 24 11 | 12 | var roundConstants = []uint64{ 13 | 0x0000000000000001, 0x0000000000008082, 14 | 0x800000000000808A, 0x8000000080008000, 15 | 0x000000000000808B, 0x0000000080000001, 16 | 0x8000000080008081, 0x8000000000008009, 17 | 0x000000000000008A, 0x0000000000000088, 18 | 0x0000000080008009, 0x000000008000000A, 19 | 0x000000008000808B, 0x800000000000008B, 20 | 0x8000000000008089, 0x8000000000008003, 21 | 0x8000000000008002, 0x8000000000000080, 22 | 0x000000000000800A, 0x800000008000000A, 23 | 0x8000000080008081, 0x8000000000008080, 24 | 0x0000000080000001, 0x8000000080008008, 25 | } 26 | 27 | var rotationConstants = [24]uint{ 28 | 1, 3, 6, 10, 15, 21, 28, 36, 29 | 45, 55, 2, 14, 27, 41, 56, 8, 30 | 25, 43, 62, 18, 39, 61, 20, 44, 31 | } 32 | 33 | var piLane = [24]uint{ 34 | 10, 7, 11, 17, 18, 3, 5, 16, 35 | 8, 21, 24, 4, 15, 23, 19, 13, 36 | 12, 2, 20, 14, 22, 9, 6, 1, 37 | } 38 | 39 | type keccak struct { 40 | S [25]uint64 41 | size int 42 | blockSize int 43 | rounds int 44 | buf []byte 45 | } 46 | 47 | func newKeccak(bitlen, rounds int) hash.Hash { 48 | var h keccak 49 | h.size = bitlen / 8 50 | h.blockSize = (200 - 2*h.size) 51 | h.rounds = rounds 52 | if rounds != stdRounds { 53 | //fmt.Printf("keccak: warning non standard number of rounds %d vs %d\n", rounds, stdRounds) 54 | } 55 | return &h 56 | } 57 | 58 | func NewCustom(bits, rounds int) hash.Hash { 59 | return newKeccak(bits, rounds) 60 | } 61 | 62 | func New160() hash.Hash { 63 | return newKeccak(160, stdRounds) 64 | } 65 | 66 | func New224() hash.Hash { 67 | return newKeccak(224, stdRounds) 68 | } 69 | 70 | func New256() hash.Hash { 71 | return newKeccak(256, stdRounds) 72 | } 73 | 74 | func New384() hash.Hash { 75 | return newKeccak(384, stdRounds) 76 | } 77 | 78 | func New512() hash.Hash { 79 | return newKeccak(512, stdRounds) 80 | } 81 | 82 | func (k *keccak) Write(b []byte) (int, error) { 83 | n := len(b) 84 | 85 | if len(k.buf) > 0 { 86 | x := k.blockSize - len(k.buf) 87 | if x > len(b) { 88 | x = len(b) 89 | } 90 | k.buf = append(k.buf, b[:x]...) 91 | b = b[x:] 92 | 93 | if len(k.buf) < k.blockSize { 94 | return n, nil 95 | } 96 | 97 | k.f(k.buf) 98 | k.buf = nil 99 | } 100 | 101 | for len(b) >= k.blockSize { 102 | k.f(b[:k.blockSize]) 103 | b = b[k.blockSize:] 104 | } 105 | 106 | k.buf = b 107 | 108 | return n, nil 109 | } 110 | 111 | func (k0 *keccak) Sum(b []byte) []byte { 112 | 113 | k := *k0 114 | 115 | last := k.pad(k.buf) 116 | k.f(last) 117 | 118 | buf := make([]byte, len(k.S)*8) 119 | for i := range k.S { 120 | putUint64le(buf[i*8:], k.S[i]) 121 | } 122 | return append(b, buf[:k.size]...) 123 | } 124 | 125 | func (k *keccak) Reset() { 126 | for i := range k.S { 127 | k.S[i] = 0 128 | } 129 | k.buf = nil 130 | } 131 | 132 | func (k *keccak) Size() int { 133 | return k.size 134 | } 135 | 136 | func (k *keccak) BlockSize() int { 137 | return k.blockSize 138 | } 139 | 140 | func rotl64(x uint64, n uint) uint64 { 141 | return (x << n) | (x >> (64 - n)) 142 | } 143 | 144 | func (k *keccak) f(block []byte) { 145 | 146 | if len(block) != k.blockSize { 147 | panic("f() called with invalid block size") 148 | } 149 | 150 | for i := 0; i < k.blockSize/8; i++ { 151 | k.S[i] ^= uint64le(block[i*8:]) 152 | } 153 | 154 | for r := 0; r < k.rounds; r++ { 155 | var bc [5]uint64 156 | 157 | // theta 158 | for i := range bc { 159 | bc[i] = k.S[i] ^ k.S[5+i] ^ k.S[10+i] ^ k.S[15+i] ^ k.S[20+i] 160 | } 161 | for i := range bc { 162 | t := bc[(i+4)%5] ^ rotl64(bc[(i+1)%5], 1) 163 | for j := 0; j < len(k.S); j += 5 { 164 | k.S[i+j] ^= t 165 | } 166 | } 167 | 168 | // rho phi 169 | temp := k.S[1] 170 | for i := range piLane { 171 | j := piLane[i] 172 | temp2 := k.S[j] 173 | k.S[j] = rotl64(temp, rotationConstants[i]) 174 | temp = temp2 175 | } 176 | 177 | // chi 178 | for j := 0; j < len(k.S); j += 5 { 179 | for i := range bc { 180 | bc[i] = k.S[j+i] 181 | } 182 | for i := range bc { 183 | k.S[j+i] ^= (^bc[(i+1)%5]) & bc[(i+2)%5] 184 | } 185 | } 186 | 187 | // iota 188 | k.S[0] ^= roundConstants[r] 189 | } 190 | } 191 | 192 | func (k *keccak) pad(block []byte) []byte { 193 | 194 | padded := make([]byte, k.blockSize) 195 | 196 | copy(padded, k.buf) 197 | padded[len(k.buf)] = 0x01 198 | padded[len(padded)-1] |= 0x80 199 | 200 | return padded 201 | } 202 | 203 | func uint64le(v []byte) uint64 { 204 | return uint64(v[0]) | 205 | uint64(v[1])<<8 | 206 | uint64(v[2])<<16 | 207 | uint64(v[3])<<24 | 208 | uint64(v[4])<<32 | 209 | uint64(v[5])<<40 | 210 | uint64(v[6])<<48 | 211 | uint64(v[7])<<56 212 | 213 | } 214 | 215 | func putUint64le(v []byte, x uint64) { 216 | v[0] = byte(x) 217 | v[1] = byte(x >> 8) 218 | v[2] = byte(x >> 16) 219 | v[3] = byte(x >> 24) 220 | v[4] = byte(x >> 32) 221 | v[5] = byte(x >> 40) 222 | v[6] = byte(x >> 48) 223 | v[7] = byte(x >> 56) 224 | } 225 | -------------------------------------------------------------------------------- /murmur3/README.md: -------------------------------------------------------------------------------- 1 | murmur3 2 | ======= 3 | 4 | Native Go implementation of Austin Appleby's third MurmurHash revision (aka 5 | MurmurHash3). 6 | 7 | Reference algorithm has been slightly hacked as to support the streaming mode 8 | required by Go's standard [Hash interface](http://golang.org/pkg/hash/#Hash). 9 | 10 | 11 | Benchmarks 12 | ---------- 13 | 14 | Go tip as of 2014-06-12 (i.e almost go1.3), core i7 @ 3.4 Ghz. All runs 15 | include hasher instantiation and sequence finalization. 16 | 17 |
18 | 
19 | Benchmark32_1        500000000     7.69 ns/op      130.00 MB/s
20 | Benchmark32_2        200000000     8.83 ns/op      226.42 MB/s
21 | Benchmark32_4        500000000     7.99 ns/op      500.39 MB/s
22 | Benchmark32_8        200000000     9.47 ns/op      844.69 MB/s
23 | Benchmark32_16       100000000     12.1 ns/op     1321.61 MB/s
24 | Benchmark32_32       100000000     18.3 ns/op     1743.93 MB/s
25 | Benchmark32_64        50000000     30.9 ns/op     2071.64 MB/s
26 | Benchmark32_128       50000000     57.6 ns/op     2222.96 MB/s
27 | Benchmark32_256       20000000      116 ns/op     2188.60 MB/s
28 | Benchmark32_512       10000000      226 ns/op     2260.59 MB/s
29 | Benchmark32_1024       5000000      452 ns/op     2263.73 MB/s
30 | Benchmark32_2048       2000000      891 ns/op     2296.02 MB/s
31 | Benchmark32_4096       1000000     1787 ns/op     2290.92 MB/s
32 | Benchmark32_8192        500000     3593 ns/op     2279.68 MB/s
33 | Benchmark128_1       100000000     26.1 ns/op       38.33 MB/s
34 | Benchmark128_2       100000000     29.0 ns/op       69.07 MB/s
35 | Benchmark128_4        50000000     29.8 ns/op      134.17 MB/s
36 | Benchmark128_8        50000000     31.6 ns/op      252.86 MB/s
37 | Benchmark128_16      100000000     26.5 ns/op      603.42 MB/s
38 | Benchmark128_32      100000000     28.6 ns/op     1117.15 MB/s
39 | Benchmark128_64       50000000     35.5 ns/op     1800.97 MB/s
40 | Benchmark128_128      50000000     50.9 ns/op     2515.50 MB/s
41 | Benchmark128_256      20000000     76.9 ns/op     3330.11 MB/s
42 | Benchmark128_512      20000000      135 ns/op     3769.09 MB/s
43 | Benchmark128_1024     10000000      250 ns/op     4094.38 MB/s
44 | Benchmark128_2048      5000000      477 ns/op     4290.75 MB/s
45 | Benchmark128_4096      2000000      940 ns/op     4353.29 MB/s
46 | Benchmark128_8192      1000000     1838 ns/op     4455.47 MB/s
47 | 
48 | 
49 | 50 | 51 |
52 | 
53 | benchmark              Go1.0 MB/s    Go1.1 MB/s  speedup    Go1.2 MB/s  speedup    Go1.3 MB/s  speedup
54 | Benchmark32_1               98.90        118.59    1.20x        114.79    0.97x        130.00    1.13x
55 | Benchmark32_2              168.04        213.31    1.27x        210.65    0.99x        226.42    1.07x
56 | Benchmark32_4              414.01        494.19    1.19x        490.29    0.99x        500.39    1.02x
57 | Benchmark32_8              662.19        836.09    1.26x        836.46    1.00x        844.69    1.01x
58 | Benchmark32_16             917.46       1304.62    1.42x       1297.63    0.99x       1321.61    1.02x
59 | Benchmark32_32            1141.93       1737.54    1.52x       1728.24    0.99x       1743.93    1.01x
60 | Benchmark32_64            1289.47       2039.51    1.58x       2038.20    1.00x       2071.64    1.02x
61 | Benchmark32_128           1299.23       2097.63    1.61x       2177.13    1.04x       2222.96    1.02x
62 | Benchmark32_256           1369.90       2202.34    1.61x       2213.15    1.00x       2188.60    0.99x
63 | Benchmark32_512           1399.56       2255.72    1.61x       2264.49    1.00x       2260.59    1.00x
64 | Benchmark32_1024          1410.90       2285.82    1.62x       2270.99    0.99x       2263.73    1.00x
65 | Benchmark32_2048          1422.14       2297.62    1.62x       2269.59    0.99x       2296.02    1.01x
66 | Benchmark32_4096          1420.53       2307.81    1.62x       2273.43    0.99x       2290.92    1.01x
67 | Benchmark32_8192          1424.79       2312.87    1.62x       2286.07    0.99x       2279.68    1.00x
68 | Benchmark128_1               8.32         30.15    3.62x         30.84    1.02x         38.33    1.24x
69 | Benchmark128_2              16.38         59.72    3.65x         59.37    0.99x         69.07    1.16x
70 | Benchmark128_4              32.26        112.96    3.50x        114.24    1.01x        134.17    1.17x
71 | Benchmark128_8              62.68        217.88    3.48x        218.18    1.00x        252.86    1.16x
72 | Benchmark128_16            128.47        451.57    3.51x        474.65    1.05x        603.42    1.27x
73 | Benchmark128_32            246.18        910.42    3.70x        871.06    0.96x       1117.15    1.28x
74 | Benchmark128_64            449.05       1477.64    3.29x       1449.24    0.98x       1800.97    1.24x
75 | Benchmark128_128           762.61       2222.42    2.91x       2217.30    1.00x       2515.50    1.13x
76 | Benchmark128_256          1179.92       3005.46    2.55x       2931.55    0.98x       3330.11    1.14x
77 | Benchmark128_512          1616.51       3590.75    2.22x       3592.08    1.00x       3769.09    1.05x
78 | Benchmark128_1024         1964.36       3979.67    2.03x       4034.01    1.01x       4094.38    1.01x
79 | Benchmark128_2048         2225.07       4156.93    1.87x       4244.17    1.02x       4290.75    1.01x
80 | Benchmark128_4096         2360.15       4299.09    1.82x       4392.35    1.02x       4353.29    0.99x
81 | Benchmark128_8192         2411.50       4356.84    1.81x       4480.68    1.03x       4455.47    0.99x
82 | 
83 | 
84 | 85 | -------------------------------------------------------------------------------- /metro/metro128.go: -------------------------------------------------------------------------------- 1 | package metro 2 | 3 | import "encoding/binary" 4 | 5 | func Hash128_1(key []byte, seed uint32) (uint64, uint64) { 6 | 7 | const k0 uint64 = 0xC83A91E1 8 | const k1 uint64 = 0x8648DBDB 9 | const k2 uint64 = 0x7BDEC03B 10 | const k3 uint64 = 0x2F5870A5 11 | 12 | ptr := key 13 | 14 | var v [4]uint64 15 | 16 | v[0] = (uint64(seed)-k0)*k3 + uint64(len(ptr)) 17 | v[1] = (uint64(seed)+k1)*k2 + uint64(len(ptr)) 18 | 19 | if len(ptr) >= 32 { 20 | v[2] = (uint64(seed)+k0)*k2 + uint64(len(ptr)) 21 | v[3] = (uint64(seed)-k1)*k3 + uint64(len(ptr)) 22 | 23 | for len(ptr) >= 32 { 24 | v[0] += binary.LittleEndian.Uint64(ptr) * k0 25 | ptr = ptr[8:] 26 | v[0] = rotate_right(v[0], 29) + v[2] 27 | v[1] += binary.LittleEndian.Uint64(ptr) * k1 28 | ptr = ptr[8:] 29 | v[1] = rotate_right(v[1], 29) + v[3] 30 | v[2] += binary.LittleEndian.Uint64(ptr) * k2 31 | ptr = ptr[8:] 32 | v[2] = rotate_right(v[2], 29) + v[0] 33 | v[3] += binary.LittleEndian.Uint64(ptr) * k3 34 | ptr = ptr[8:] 35 | v[3] = rotate_right(v[3], 29) + v[1] 36 | } 37 | 38 | v[2] ^= rotate_right(((v[0]+v[3])*k0)+v[1], 26) * k1 39 | v[3] ^= rotate_right(((v[1]+v[2])*k1)+v[0], 26) * k0 40 | v[0] ^= rotate_right(((v[0]+v[2])*k0)+v[3], 26) * k1 41 | v[1] ^= rotate_right(((v[1]+v[3])*k1)+v[2], 30) * k0 42 | } 43 | 44 | if len(ptr) >= 16 { 45 | v[0] += binary.LittleEndian.Uint64(ptr) * k2 46 | ptr = ptr[8:] 47 | v[0] = rotate_right(v[0], 33) * k3 48 | v[1] += binary.LittleEndian.Uint64(ptr) * k2 49 | ptr = ptr[8:] 50 | v[1] = rotate_right(v[1], 33) * k3 51 | v[0] ^= rotate_right((v[0]*k2)+v[1], 17) * k1 52 | v[1] ^= rotate_right((v[1]*k3)+v[0], 17) * k0 53 | } 54 | 55 | if len(ptr) >= 8 { 56 | v[0] += binary.LittleEndian.Uint64(ptr) * k2 57 | ptr = ptr[8:] 58 | v[0] = rotate_right(v[0], 33) * k3 59 | v[0] ^= rotate_right((v[0]*k2)+v[1], 20) * k1 60 | } 61 | 62 | if len(ptr) >= 4 { 63 | v[1] += uint64(binary.LittleEndian.Uint32(ptr)) * k2 64 | ptr = ptr[4:] 65 | v[1] = rotate_right(v[1], 33) * k3 66 | v[1] ^= rotate_right((v[1]*k3)+v[0], 18) * k0 67 | } 68 | 69 | if len(ptr) >= 2 { 70 | v[0] += uint64(binary.LittleEndian.Uint16(ptr)) * k2 71 | ptr = ptr[2:] 72 | v[0] = rotate_right(v[0], 33) * k3 73 | v[0] ^= rotate_right((v[0]*k2)+v[1], 24) * k1 74 | } 75 | 76 | if len(ptr) >= 1 { 77 | v[1] += uint64(ptr[0]) * k2 78 | v[1] = rotate_right(v[1], 33) * k3 79 | v[1] ^= rotate_right((v[1]*k3)+v[0], 24) * k0 80 | } 81 | 82 | v[0] += rotate_right((v[0]*k0)+v[1], 13) 83 | v[1] += rotate_right((v[1]*k1)+v[0], 37) 84 | v[0] += rotate_right((v[0]*k2)+v[1], 13) 85 | v[1] += rotate_right((v[1]*k3)+v[0], 37) 86 | 87 | return v[0], v[1] 88 | } 89 | 90 | func Hash128_2(key []byte, seed uint32) (uint64, uint64) { 91 | const k0 uint64 = 0xD6D018F5 92 | const k1 uint64 = 0xA2AA033B 93 | const k2 uint64 = 0x62992FC1 94 | const k3 uint64 = 0x30BC5B29 95 | 96 | ptr := key 97 | 98 | var v [4]uint64 99 | 100 | v[0] = (uint64(seed)-k0)*k3 + uint64(len(ptr)) 101 | v[1] = (uint64(seed)+k1)*k2 + uint64(len(ptr)) 102 | 103 | if len(ptr) >= 32 { 104 | v[2] = (uint64(seed)+k0)*k2 + uint64(len(ptr)) 105 | v[3] = (uint64(seed)-k1)*k3 + uint64(len(ptr)) 106 | 107 | for len(ptr) >= 32 { 108 | v[0] += binary.LittleEndian.Uint64(ptr) * k0 109 | ptr = ptr[8:] 110 | v[0] = rotate_right(v[0], 29) + v[2] 111 | v[1] += binary.LittleEndian.Uint64(ptr) * k1 112 | ptr = ptr[8:] 113 | v[1] = rotate_right(v[1], 29) + v[3] 114 | v[2] += binary.LittleEndian.Uint64(ptr) * k2 115 | ptr = ptr[8:] 116 | v[2] = rotate_right(v[2], 29) + v[0] 117 | v[3] += binary.LittleEndian.Uint64(ptr) * k3 118 | ptr = ptr[8:] 119 | v[3] = rotate_right(v[3], 29) + v[1] 120 | } 121 | 122 | v[2] ^= rotate_right(((v[0]+v[3])*k0)+v[1], 33) * k1 123 | v[3] ^= rotate_right(((v[1]+v[2])*k1)+v[0], 33) * k0 124 | v[0] ^= rotate_right(((v[0]+v[2])*k0)+v[3], 33) * k1 125 | v[1] ^= rotate_right(((v[1]+v[3])*k1)+v[2], 33) * k0 126 | } 127 | 128 | if len(ptr) >= 16 { 129 | v[0] += binary.LittleEndian.Uint64(ptr) * k2 130 | ptr = ptr[8:] 131 | v[0] = rotate_right(v[0], 29) * k3 132 | v[1] += binary.LittleEndian.Uint64(ptr) * k2 133 | ptr = ptr[8:] 134 | v[1] = rotate_right(v[1], 29) * k3 135 | v[0] ^= rotate_right((v[0]*k2)+v[1], 29) * k1 136 | v[1] ^= rotate_right((v[1]*k3)+v[0], 29) * k0 137 | } 138 | 139 | if len(ptr) >= 8 { 140 | v[0] += binary.LittleEndian.Uint64(ptr) * k2 141 | ptr = ptr[8:] 142 | v[0] = rotate_right(v[0], 29) * k3 143 | v[0] ^= rotate_right((v[0]*k2)+v[1], 29) * k1 144 | } 145 | 146 | if len(ptr) >= 4 { 147 | v[1] += uint64(binary.LittleEndian.Uint32(ptr)) * k2 148 | ptr = ptr[4:] 149 | v[1] = rotate_right(v[1], 29) * k3 150 | v[1] ^= rotate_right((v[1]*k3)+v[0], 25) * k0 151 | } 152 | 153 | if len(ptr) >= 2 { 154 | v[0] += uint64(binary.LittleEndian.Uint16(ptr)) * k2 155 | ptr = ptr[2:] 156 | v[0] = rotate_right(v[0], 29) * k3 157 | v[0] ^= rotate_right((v[0]*k2)+v[1], 30) * k1 158 | } 159 | 160 | if len(ptr) >= 1 { 161 | v[1] += uint64(ptr[0]) * k2 162 | v[1] = rotate_right(v[1], 29) * k3 163 | v[1] ^= rotate_right((v[1]*k3)+v[0], 18) * k0 164 | } 165 | 166 | v[0] += rotate_right((v[0]*k0)+v[1], 33) 167 | v[1] += rotate_right((v[1]*k1)+v[0], 33) 168 | v[0] += rotate_right((v[0]*k2)+v[1], 33) 169 | v[1] += rotate_right((v[1]*k3)+v[0], 33) 170 | 171 | return v[0], v[1] 172 | } 173 | -------------------------------------------------------------------------------- /farm/farmhashcc.go: -------------------------------------------------------------------------------- 1 | package farm 2 | 3 | // This file provides a 32-bit hash equivalent to CityHash32 (v1.1.1) 4 | // and a 128-bit hash equivalent to CityHash128 (v1.1.1). It also provides 5 | // a seeded 32-bit hash function similar to CityHash32. 6 | 7 | func hash32Len13to24Seed(s []byte, seed uint32) uint32 { 8 | slen := len(s) 9 | a := fetch32(s, -4+(slen>>1)) 10 | b := fetch32(s, 4) 11 | c := fetch32(s, slen-8) 12 | d := fetch32(s, (slen >> 1)) 13 | e := fetch32(s, 0) 14 | f := fetch32(s, slen-4) 15 | h := d*c1 + uint32(slen) + seed 16 | a = rotate32(a, 12) + f 17 | h = mur(c, h) + a 18 | a = rotate32(a, 3) + c 19 | h = mur(e, h) + a 20 | a = rotate32(a+f, 12) + d 21 | h = mur(b^seed, h) + a 22 | return fmix(h) 23 | } 24 | 25 | func hash32Len0to4(s []byte, seed uint32) uint32 { 26 | slen := len(s) 27 | b := seed 28 | c := uint32(9) 29 | for i := 0; i < slen; i++ { 30 | v := int8(s[i]) 31 | b = uint32(b*c1) + uint32(v) 32 | c ^= b 33 | } 34 | return fmix(mur(b, mur(uint32(slen), c))) 35 | } 36 | 37 | func hash128to64(x uint128) uint64 { 38 | // Murmur-inspired hashing. 39 | const kMul uint64 = 0x9ddfea08eb382d69 40 | a := (x.lo ^ x.hi) * kMul 41 | a ^= (a >> 47) 42 | b := (x.hi ^ a) * kMul 43 | b ^= (b >> 47) 44 | b *= kMul 45 | return b 46 | } 47 | 48 | type uint128 struct { 49 | lo uint64 50 | hi uint64 51 | } 52 | 53 | // A subroutine for CityHash128(). Returns a decent 128-bit hash for strings 54 | // of any length representable in signed long. Based on City and Murmur. 55 | func cityMurmur(s []byte, seed uint128) uint128 { 56 | slen := len(s) 57 | a := seed.lo 58 | b := seed.hi 59 | c := uint64(0) 60 | d := uint64(0) 61 | l := slen - 16 62 | if l <= 0 { // len <= 16 63 | a = shiftMix(a*k1) * k1 64 | c = b*k1 + hashLen0to16(s) 65 | if slen >= 8 { 66 | d = shiftMix(a + fetch64(s, 0)) 67 | } else { 68 | d = shiftMix(a + c) 69 | } 70 | } else { // len > 16 71 | c = hashLen16(fetch64(s, int(slen-8))+k1, a) 72 | d = hashLen16(b+uint64(slen), c+fetch64(s, int(slen-16))) 73 | a += d 74 | for { 75 | a ^= shiftMix(fetch64(s, 0)*k1) * k1 76 | a *= k1 77 | b ^= a 78 | c ^= shiftMix(fetch64(s, 8)*k1) * k1 79 | c *= k1 80 | d ^= c 81 | s = s[16:] 82 | l -= 16 83 | if l <= 0 { 84 | break 85 | } 86 | } 87 | } 88 | a = hashLen16(a, c) 89 | b = hashLen16(d, b) 90 | return uint128{a ^ b, hashLen16(b, a)} 91 | } 92 | 93 | func cityHash128WithSeed(s []byte, seed uint128) uint128 { 94 | slen := len(s) 95 | if slen < 128 { 96 | return cityMurmur(s, seed) 97 | } 98 | 99 | endIdx := ((slen - 1) / 128) * 128 100 | lastBlockIdx := endIdx + ((slen - 1) & 127) - 127 101 | last := s[lastBlockIdx:] 102 | 103 | // We expect len >= 128 to be the common case. Keep 56 bytes of state: 104 | // v, w, x, y, and z. 105 | var v1, v2 uint64 106 | var w1, w2 uint64 107 | x := seed.lo 108 | y := seed.hi 109 | z := uint64(slen) * k1 110 | v1 = rotate64(y^k1, 49)*k1 + fetch64(s, 0) 111 | v2 = rotate64(v1, 42)*k1 + fetch64(s, 8) 112 | w1 = rotate64(y+z, 35)*k1 + x 113 | w2 = rotate64(x+fetch64(s, 88), 53) * k1 114 | 115 | // This is the same inner loop as CityHash64(), manually unrolled. 116 | for { 117 | x = rotate64(x+y+v1+fetch64(s, 8), 37) * k1 118 | y = rotate64(y+v2+fetch64(s, 48), 42) * k1 119 | x ^= w2 120 | y += v1 + fetch64(s, 40) 121 | z = rotate64(z+w1, 33) * k1 122 | v1, v2 = weakHashLen32WithSeeds(s, v2*k1, x+w1) 123 | w1, w2 = weakHashLen32WithSeeds(s[32:], z+w2, y+fetch64(s, 16)) 124 | z, x = x, z 125 | s = s[64:] 126 | x = rotate64(x+y+v1+fetch64(s, 8), 37) * k1 127 | y = rotate64(y+v2+fetch64(s, 48), 42) * k1 128 | x ^= w2 129 | y += v1 + fetch64(s, 40) 130 | z = rotate64(z+w1, 33) * k1 131 | v1, v2 = weakHashLen32WithSeeds(s, v2*k1, x+w1) 132 | w1, w2 = weakHashLen32WithSeeds(s[32:], z+w2, y+fetch64(s, 16)) 133 | z, x = x, z 134 | s = s[64:] 135 | slen -= 128 136 | if slen < 128 { 137 | break 138 | } 139 | } 140 | x += rotate64(v1+z, 49) * k0 141 | y = y*k0 + rotate64(w2, 37) 142 | z = z*k0 + rotate64(w1, 27) 143 | w1 *= 9 144 | v1 *= k0 145 | // If 0 < len < 128, hash up to 4 chunks of 32 bytes each from the end of s. 146 | for tail_done := 0; tail_done < slen; { 147 | tail_done += 32 148 | y = rotate64(x+y, 42)*k0 + v2 149 | w1 += fetch64(last, 128-tail_done+16) 150 | x = x*k0 + w1 151 | z += w2 + fetch64(last, 128-tail_done) 152 | w2 += v1 153 | v1, v2 = weakHashLen32WithSeeds(last[128-tail_done:], v1+z, v2) 154 | v1 *= k0 155 | } 156 | 157 | // At this point our 56 bytes of state should contain more than 158 | // enough information for a strong 128-bit hash. We use two 159 | // different 56-byte-to-8-byte hashes to get a 16-byte final result. 160 | x = hashLen16(x, v1) 161 | y = hashLen16(y+z, w1) 162 | return uint128{hashLen16(x+v2, w2) + y, 163 | hashLen16(x+w2, y+v2)} 164 | } 165 | 166 | func cityHash128(s []byte) uint128 { 167 | slen := len(s) 168 | if slen >= 16 { 169 | return cityHash128WithSeed(s[16:], uint128{fetch64(s, 0), fetch64(s, 8) + k0}) 170 | } 171 | return cityHash128WithSeed(s, uint128{k0, k1}) 172 | } 173 | 174 | func Fingerprint128(s []byte) (lo, hi uint64) { 175 | h := cityHash128(s) 176 | return h.lo, h.hi 177 | } 178 | 179 | func Fingerprint64(s []byte) uint64 { 180 | return Hash64(s) 181 | } 182 | 183 | func Fingerprint32(s []byte) uint32 { 184 | return Hash32(s) 185 | } 186 | 187 | func Hash128(s []byte) (lo, hi uint64) { 188 | return Fingerprint128(s) 189 | } 190 | 191 | func Hash128WithSeed(s []byte, seed0, seed1 uint64) (lo, hi uint64) { 192 | h := cityHash128WithSeed(s, uint128{seed0, seed1}) 193 | return h.lo, h.hi 194 | } 195 | -------------------------------------------------------------------------------- /farm/farm_test.go: -------------------------------------------------------------------------------- 1 | package farm 2 | 3 | import "testing" 4 | 5 | // Generated from the C++ code 6 | var golden32 = []struct { 7 | out uint32 8 | in string 9 | }{ 10 | {0x3c973d4d, "a"}, 11 | {0x417330fd, "ab"}, 12 | {0x2f635ec7, "abc"}, 13 | {0x98b51e95, "abcd"}, 14 | {0xa3f366ac, "abcde"}, 15 | {0x0f813aa4, "abcdef"}, 16 | {0x21deb6d7, "abcdefg"}, 17 | {0xfd7ec8b9, "abcdefgh"}, 18 | {0x6f98dc86, "abcdefghi"}, 19 | {0xf2669361, "abcdefghij"}, 20 | {0xe273108f, "Discard medicine more than two years old."}, 21 | {0xf585dfc4, "He who has a shady past knows that nice guys finish last."}, 22 | {0x363394d1, "I wouldn't marry him with a ten foot pole."}, 23 | {0x7613810f, "Free! Free!/A trip/to Mars/for 900/empty jars/Burma Shave"}, 24 | {0x2cc30bb7, "The days of the digital watch are numbered. -Tom Stoppard"}, 25 | {0x322984d9, "Nepal premier won't resign."}, 26 | {0xa5812ac8, "For every action there is an equal and opposite government program."}, 27 | {0x1090d244, "His money is twice tainted: 'taint yours and 'taint mine."}, 28 | {0xff16c9e6, "There is no reason for any individual to have a computer in their home. -Ken Olsen, 1977"}, 29 | {0xcc3d0ff2, "It's a tiny change to the code and not completely disgusting. - Bob Manchek"}, 30 | {0xc6246b8d, "size: a.out: bad magic"}, 31 | {0xd225e92e, "The major problem is with sendmail. -Mark Horton"}, 32 | {0x1b8db5d0, "Give me a rock, paper and scissors and I will move the world. CCFestoon"}, 33 | {0x4fda5f07, "If the enemy is within range, then so are you."}, 34 | {0x2e18e880, "It's well we cannot hear the screams/That we create in others' dreams."}, 35 | {0xd07de88f, "You remind me of a TV show, but that's all right: I watch it anyway."}, 36 | {0x221694e4, "C is as portable as Stonehedge!!"}, 37 | {0xe2053c2c, "Even if I could be Shakespeare, I think I should still choose to be Faraday. - A. Huxley"}, 38 | {0x11c493bb, "The fugacity of a constituent in a mixture of gases at a given temperature is proportional to its mole fraction. Lewis-Randall Rule"}, 39 | {0x0819a4e8, "How can you write a big system without C++? -Paul Glick"}, 40 | } 41 | 42 | func TestHash32(t *testing.T) { 43 | 44 | for _, tt := range golden32 { 45 | if h := Hash32([]byte(tt.in)); h != tt.out { 46 | t.Errorf("Hash32(%q)=%#08x (len=%d), want %#08x", tt.in, h, len(tt.in), tt.out) 47 | } 48 | } 49 | 50 | } 51 | 52 | // Generated from the C++ code 53 | var golden64 = []struct { 54 | out uint64 55 | in string 56 | }{ 57 | {0xb3454265b6df75e3, "a"}, 58 | {0xaa8d6e5242ada51e, "ab"}, 59 | {0x24a5b3a074e7f369, "abc"}, 60 | {0x1a5502de4a1f8101, "abcd"}, 61 | {0xc22f4663e54e04d4, "abcde"}, 62 | {0xc329379e6a03c2cd, "abcdef"}, 63 | {0x3c40c92b1ccb7355, "abcdefg"}, 64 | {0xfee9d22990c82909, "abcdefgh"}, 65 | {0x332c8ed4dae5ba42, "abcdefghi"}, 66 | {0x8a3abb6a5f3fb7fb, "abcdefghij"}, 67 | {0xe8f89ab6df9bdd25, "Discard medicine more than two years old."}, 68 | {0x786d7e1987023ca9, "He who has a shady past knows that nice guys finish last."}, 69 | {0xa9961670ce2a46d9, "I wouldn't marry him with a ten foot pole."}, 70 | {0x5d14f96c18fe3d5e, "Free! Free!/A trip/to Mars/for 900/empty jars/Burma Shave"}, 71 | {0x2a578b80bb82147c, "The days of the digital watch are numbered. -Tom Stoppard"}, 72 | {0x8eb3808d1ccfc779, "Nepal premier won't resign."}, 73 | {0xb8d104d1135bbc60, "For every action there is an equal and opposite government program."}, 74 | {0xec8848fd3b266c10, "His money is twice tainted: 'taint yours and 'taint mine."}, 75 | {0xfe6aa49558b3cbe0, "There is no reason for any individual to have a computer in their home. -Ken Olsen, 1977"}, 76 | {0xa104da6f2f575514, "It's a tiny change to the code and not completely disgusting. - Bob Manchek"}, 77 | {0x80d73b843ba57db8, "size: a.out: bad magic"}, 78 | {0xc2f8db8624fefc0e, "The major problem is with sendmail. -Mark Horton"}, 79 | {0xa58e3702193e4631, "Give me a rock, paper and scissors and I will move the world. CCFestoon"}, 80 | {0xbdd69b798d6ba37a, "If the enemy is within range, then so are you."}, 81 | {0x61751a90ec7d71bf, "It's well we cannot hear the screams/That we create in others' dreams."}, 82 | {0x836f5ff0c2a7dfaa, "You remind me of a TV show, but that's all right: I watch it anyway."}, 83 | {0xb944f8a16261e414, "C is as portable as Stonehedge!!"}, 84 | {0x96d012f9bccb3e, "Even if I could be Shakespeare, I think I should still choose to be Faraday. - A. Huxley"}, 85 | {0x8fe4429d157f60f5, "The fugacity of a constituent in a mixture of gases at a given temperature is proportional to its mole fraction. Lewis-Randall Rule"}, 86 | {0x5a0a6efd52e84e2a, "How can you write a big system without C++? -Paul Glick"}, 87 | } 88 | 89 | func TestHash64(t *testing.T) { 90 | for _, tt := range golden64 { 91 | if h := Hash64([]byte(tt.in)); h != tt.out { 92 | t.Errorf("Hash64(%q)=%#016x, (len=%d) want %#016x", tt.in, h, len(tt.in), tt.out) 93 | } 94 | 95 | } 96 | } 97 | 98 | func TestFingerprint128(t *testing.T) { 99 | 100 | var tests = []struct { 101 | hi, lo uint64 102 | in string 103 | }{ 104 | {9054869399155703984, 8033370924408288235, "abcdef"}, 105 | {352412539875473798, 3547689611939963773, "There is no reason for any individual to have a computer in their home. -Ken Olsen, 1977"}, 106 | {14320160249354795919, 10805939018293574989, "The fugacity of a constituent in a mixture of gases at a given temperature is proportional to its mole fraction. Lewis-Randall RuleAAAAAAAAAAAAAAAA"}, 107 | } 108 | 109 | for _, tt := range tests { 110 | if lo, hi := Fingerprint128([]byte(tt.in)); hi != tt.hi || lo != tt.lo { 111 | t.Errorf("Fingerprint128(%q)=(%#016x, %#016x) (len=%d) want (%#016x, %#016x)", tt.in, lo, hi, len(tt.in), tt.lo, tt.hi) 112 | } 113 | } 114 | } 115 | -------------------------------------------------------------------------------- /siphash/hash128_amd64.s: -------------------------------------------------------------------------------- 1 | // This is a translation of the gcc output of FloodyBerry's pure-C public 2 | // domain siphash implementation at https://github.com/floodyberry/siphash 3 | 4 | // This assembly code has been modified from the 64-bit output to the experiment 128-bit output. 5 | 6 | // SI = v0 7 | // AX = v1 8 | // CX = v2 9 | // DX = v3 10 | 11 | // func Hash128(k0, k1 uint64, b []byte) (r0 uint64, r1 uint64) 12 | TEXT ·Hash128(SB),4,$0-56 13 | MOVQ k0+0(FP),CX 14 | MOVQ $0x736F6D6570736575,R9 15 | MOVQ k1+8(FP),DI 16 | MOVQ $0x6C7967656E657261,BX 17 | MOVQ $0x646F72616E646F6D,AX 18 | MOVQ b_len+24(FP),DX 19 | XORQ $0xEE,AX 20 | MOVQ DX,R11 21 | MOVQ DX,R10 22 | XORQ CX,R9 23 | XORQ CX,BX 24 | MOVQ $0x7465646279746573,CX 25 | XORQ DI,AX 26 | XORQ DI,CX 27 | SHLQ $0x38,R11 28 | XORQ DI,DI 29 | MOVQ b_base+16(FP),SI 30 | ANDQ $0xFFFFFFFFFFFFFFF8,R10 31 | JE afterLoop 32 | XCHGQ AX,AX 33 | loopBody: 34 | MOVQ 0(SI)(DI*1),R8 35 | ADDQ AX,R9 36 | RORQ $0x33,AX 37 | XORQ R9,AX 38 | RORQ $0x20,R9 39 | ADDQ $0x8,DI 40 | XORQ R8,CX 41 | ADDQ CX,BX 42 | RORQ $0x30,CX 43 | XORQ BX,CX 44 | ADDQ AX,BX 45 | RORQ $0x2F,AX 46 | ADDQ CX,R9 47 | RORQ $0x2B,CX 48 | XORQ BX,AX 49 | XORQ R9,CX 50 | RORQ $0x20,BX 51 | ADDQ AX,R9 52 | ADDQ CX,BX 53 | RORQ $0x33,AX 54 | RORQ $0x30,CX 55 | XORQ R9,AX 56 | XORQ BX,CX 57 | RORQ $0x20,R9 58 | ADDQ AX,BX 59 | ADDQ CX,R9 60 | RORQ $0x2F,AX 61 | RORQ $0x2B,CX 62 | XORQ BX,AX 63 | RORQ $0x20,BX 64 | XORQ R9,CX 65 | XORQ R8,R9 66 | CMPQ R10,DI 67 | JA loopBody 68 | afterLoop: 69 | SUBQ R10,DX 70 | 71 | CMPQ DX,$0x7 72 | JA afterSwitch 73 | 74 | // no support for jump tables 75 | 76 | CMPQ DX,$0x7 77 | JE sw7 78 | 79 | CMPQ DX,$0x6 80 | JE sw6 81 | 82 | CMPQ DX,$0x5 83 | JE sw5 84 | 85 | CMPQ DX,$0x4 86 | JE sw4 87 | 88 | CMPQ DX,$0x3 89 | JE sw3 90 | 91 | CMPQ DX,$0x2 92 | JE sw2 93 | 94 | CMPQ DX,$0x1 95 | JE sw1 96 | 97 | JMP afterSwitch 98 | 99 | sw7: MOVBQZX 6(SI)(DI*1),DX 100 | SHLQ $0x30,DX 101 | ORQ DX,R11 102 | sw6: MOVBQZX 0x5(SI)(DI*1),DX 103 | SHLQ $0x28,DX 104 | ORQ DX,R11 105 | sw5: MOVBQZX 0x4(SI)(DI*1),DX 106 | SHLQ $0x20,DX 107 | ORQ DX,R11 108 | sw4: MOVBQZX 0x3(SI)(DI*1),DX 109 | SHLQ $0x18,DX 110 | ORQ DX,R11 111 | sw3: MOVBQZX 0x2(SI)(DI*1),DX 112 | SHLQ $0x10,DX 113 | ORQ DX,R11 114 | sw2: MOVBQZX 0x1(SI)(DI*1),DX 115 | SHLQ $0x8,DX 116 | ORQ DX,R11 117 | sw1: MOVBQZX 0(SI)(DI*1),DX 118 | ORQ DX,R11 119 | afterSwitch: 120 | LEAQ (AX)(R9*1),SI 121 | XORQ R11,CX 122 | RORQ $0x33,AX 123 | ADDQ CX,BX 124 | MOVQ CX,DX 125 | XORQ SI,AX 126 | RORQ $0x30,DX 127 | RORQ $0x20,SI 128 | LEAQ 0(BX)(AX*1),CX 129 | XORQ BX,DX 130 | RORQ $0x2F,AX 131 | ADDQ DX,SI 132 | RORQ $0x2B,DX 133 | XORQ CX,AX 134 | XORQ SI,DX 135 | RORQ $0x20,CX 136 | ADDQ AX,SI 137 | RORQ $0x33,AX 138 | ADDQ DX,CX 139 | XORQ SI,AX 140 | RORQ $0x30,DX 141 | RORQ $0x20,SI 142 | XORQ CX,DX 143 | ADDQ AX,CX 144 | RORQ $0x2F,AX 145 | ADDQ DX,SI 146 | XORQ CX,AX 147 | RORQ $0x2B,DX 148 | RORQ $0x20,CX 149 | XORQ SI,DX 150 | XORQ R11,SI 151 | XORB $0xEE,CL 152 | ADDQ AX,SI 153 | RORQ $0x33,AX 154 | ADDQ DX,CX 155 | RORQ $0x30,DX 156 | XORQ SI,AX 157 | XORQ CX,DX 158 | RORQ $0x20,SI 159 | ADDQ AX,CX 160 | ADDQ DX,SI 161 | RORQ $0x2F,AX 162 | RORQ $0x2B,DX 163 | XORQ CX,AX 164 | XORQ SI,DX 165 | RORQ $0x20,CX 166 | ADDQ AX,SI 167 | ADDQ DX,CX 168 | RORQ $0x33,AX 169 | RORQ $0x30,DX 170 | XORQ SI,AX 171 | RORQ $0x20,SI 172 | XORQ CX,DX 173 | ADDQ AX,CX 174 | RORQ $0x2F,AX 175 | ADDQ DX,SI 176 | RORQ $0x2B,DX 177 | XORQ CX,AX 178 | XORQ SI,DX 179 | RORQ $0x20,CX 180 | ADDQ AX,SI 181 | ADDQ DX,CX 182 | RORQ $0x33,AX 183 | RORQ $0x30,DX 184 | XORQ CX,DX 185 | XORQ SI,AX 186 | RORQ $0x20,SI 187 | ADDQ DX,SI 188 | ADDQ AX,CX 189 | RORQ $0x2F,AX 190 | XORQ CX,AX 191 | RORQ $0x2B,DX 192 | RORQ $0x20,CX 193 | XORQ SI,DX 194 | 195 | // gcc optimized the tail end of this function differently. However, 196 | // we need to preserve out registers to carry out the second stage of 197 | // the finalization. This is a duplicate of an earlier finalization 198 | // round. 199 | 200 | ADDQ AX,SI 201 | RORQ $0x33,AX 202 | ADDQ DX,CX 203 | RORQ $0x30,DX 204 | XORQ SI,AX 205 | XORQ CX,DX 206 | RORQ $0x20,SI 207 | ADDQ AX,CX 208 | ADDQ DX,SI 209 | RORQ $0x2F,AX 210 | RORQ $0x2B,DX 211 | XORQ CX,AX 212 | XORQ SI,DX 213 | RORQ $0x20,CX 214 | 215 | // Stuff the result into BX instead of AX as gcc had done 216 | 217 | MOVQ SI,BX 218 | XORQ AX,BX 219 | XORQ DX,BX 220 | XORQ CX,BX 221 | MOVQ BX,r0+40(FP) 222 | 223 | // Start the second finalization round 224 | 225 | XORB $0xDD,AL 226 | ADDQ AX,SI 227 | RORQ $0x33,AX 228 | ADDQ DX,CX 229 | RORQ $0x30,DX 230 | XORQ SI,AX 231 | XORQ CX,DX 232 | RORQ $0x20,SI 233 | ADDQ AX,CX 234 | ADDQ DX,SI 235 | RORQ $0x2F,AX 236 | RORQ $0x2B,DX 237 | XORQ CX,AX 238 | XORQ SI,DX 239 | RORQ $0x20,CX 240 | ADDQ AX,SI 241 | ADDQ DX,CX 242 | RORQ $0x33,AX 243 | RORQ $0x30,DX 244 | XORQ SI,AX 245 | RORQ $0x20,SI 246 | XORQ CX,DX 247 | ADDQ AX,CX 248 | RORQ $0x2F,AX 249 | ADDQ DX,SI 250 | RORQ $0x2B,DX 251 | XORQ CX,AX 252 | XORQ SI,DX 253 | RORQ $0x20,CX 254 | ADDQ AX,SI 255 | ADDQ DX,CX 256 | RORQ $0x33,AX 257 | RORQ $0x30,DX 258 | XORQ CX,DX 259 | XORQ SI,AX 260 | RORQ $0x20,SI 261 | ADDQ DX,SI 262 | ADDQ AX,CX 263 | RORQ $0x2F,AX 264 | XORQ CX,AX 265 | RORQ $0x2B,DX 266 | RORQ $0x20,CX 267 | XORQ SI,DX 268 | 269 | ADDQ AX,SI 270 | RORQ $0x33,AX 271 | ADDQ DX,CX 272 | RORQ $0x30,DX 273 | XORQ SI,AX 274 | XORQ CX,DX 275 | RORQ $0x20,SI 276 | ADDQ AX,CX 277 | ADDQ DX,SI 278 | RORQ $0x2F,AX 279 | RORQ $0x2B,DX 280 | XORQ CX,AX 281 | XORQ SI,DX 282 | RORQ $0x20,CX 283 | 284 | MOVQ SI,BX 285 | XORQ AX,BX 286 | XORQ DX,BX 287 | XORQ CX,BX 288 | MOVQ BX,r1+48(FP) 289 | 290 | RET 291 | -------------------------------------------------------------------------------- /murmur3/murmur_test.go: -------------------------------------------------------------------------------- 1 | package murmur3 2 | 3 | import ( 4 | "hash" 5 | "testing" 6 | ) 7 | 8 | var data = []struct { 9 | h32 uint32 10 | h64_1 uint64 11 | h64_2 uint64 12 | s string 13 | }{ 14 | {0x00000000, 0x0000000000000000, 0x0000000000000000, ""}, 15 | {0x248bfa47, 0xcbd8a7b341bd9b02, 0x5b1e906a48ae1d19, "hello"}, 16 | {0x149bbb7f, 0x342fac623a5ebc8e, 0x4cdcbc079642414d, "hello, world"}, 17 | {0xe31e8a70, 0xb89e5988b737affc, 0x664fc2950231b2cb, "19 Jan 2038 at 3:14:07 AM"}, 18 | {0xd5c48bfc, 0xcd99481f9ee902c9, 0x695da1a38987b6e7, "The quick brown fox jumps over the lazy dog."}, 19 | } 20 | 21 | func TestRef(t *testing.T) { 22 | for _, elem := range data { 23 | 24 | var h32 hash.Hash32 = New32() 25 | h32.Write([]byte(elem.s)) 26 | if v := h32.Sum32(); v != elem.h32 { 27 | t.Errorf("'%s': 0x%x (want 0x%x)", elem.s, v, elem.h32) 28 | } 29 | 30 | if v := Sum32([]byte(elem.s)); v != elem.h32 { 31 | t.Errorf("'%s': 0x%x (want 0x%x)", elem.s, v, elem.h32) 32 | } 33 | 34 | var h64 hash.Hash64 = New64() 35 | h64.Write([]byte(elem.s)) 36 | if v := h64.Sum64(); v != elem.h64_1 { 37 | t.Errorf("'%s': 0x%x (want 0x%x)", elem.s, v, elem.h64_1) 38 | } 39 | 40 | if v := Sum64([]byte(elem.s)); v != elem.h64_1 { 41 | t.Errorf("'%s': 0x%x (want 0x%x)", elem.s, v, elem.h64_1) 42 | } 43 | 44 | var h128 Hash128 = New128() 45 | h128.Write([]byte(elem.s)) 46 | if v1, v2 := h128.Sum128(); v1 != elem.h64_1 || v2 != elem.h64_2 { 47 | t.Errorf("'%s': 0x%x-0x%x (want 0x%x-0x%x)", elem.s, v1, v2, elem.h64_1, elem.h64_2) 48 | } 49 | 50 | if v1, v2 := Sum128([]byte(elem.s)); v1 != elem.h64_1 || v2 != elem.h64_2 { 51 | t.Errorf("'%s': 0x%x-0x%x (want 0x%x-0x%x)", elem.s, v1, v2, elem.h64_1, elem.h64_2) 52 | } 53 | } 54 | } 55 | 56 | func TestIncremental(t *testing.T) { 57 | for _, elem := range data { 58 | h32 := New32() 59 | h128 := New128() 60 | for i, j, k := 0, 0, len(elem.s); i < k; i = j { 61 | j = 2*i + 3 62 | if j > k { 63 | j = k 64 | } 65 | s := elem.s[i:j] 66 | print(s + "|") 67 | h32.Write([]byte(s)) 68 | h128.Write([]byte(s)) 69 | } 70 | println() 71 | if v := h32.Sum32(); v != elem.h32 { 72 | t.Errorf("'%s': 0x%x (want 0x%x)", elem.s, v, elem.h32) 73 | } 74 | if v1, v2 := h128.Sum128(); v1 != elem.h64_1 || v2 != elem.h64_2 { 75 | t.Errorf("'%s': 0x%x-0x%x (want 0x%x-0x%x)", elem.s, v1, v2, elem.h64_1, elem.h64_2) 76 | } 77 | } 78 | } 79 | 80 | //--- 81 | 82 | func bench32(b *testing.B, length int) { 83 | buf := make([]byte, length) 84 | b.SetBytes(int64(length)) 85 | b.ResetTimer() 86 | for i := 0; i < b.N; i++ { 87 | Sum32(buf) 88 | } 89 | } 90 | 91 | func Benchmark32_1(b *testing.B) { 92 | bench32(b, 1) 93 | } 94 | func Benchmark32_2(b *testing.B) { 95 | bench32(b, 2) 96 | } 97 | func Benchmark32_4(b *testing.B) { 98 | bench32(b, 4) 99 | } 100 | func Benchmark32_8(b *testing.B) { 101 | bench32(b, 8) 102 | } 103 | func Benchmark32_16(b *testing.B) { 104 | bench32(b, 16) 105 | } 106 | func Benchmark32_32(b *testing.B) { 107 | bench32(b, 32) 108 | } 109 | func Benchmark32_64(b *testing.B) { 110 | bench32(b, 64) 111 | } 112 | func Benchmark32_128(b *testing.B) { 113 | bench32(b, 128) 114 | } 115 | func Benchmark32_256(b *testing.B) { 116 | bench32(b, 256) 117 | } 118 | func Benchmark32_512(b *testing.B) { 119 | bench32(b, 512) 120 | } 121 | func Benchmark32_1024(b *testing.B) { 122 | bench32(b, 1024) 123 | } 124 | func Benchmark32_2048(b *testing.B) { 125 | bench32(b, 2048) 126 | } 127 | func Benchmark32_4096(b *testing.B) { 128 | bench32(b, 4096) 129 | } 130 | func Benchmark32_8192(b *testing.B) { 131 | bench32(b, 8192) 132 | } 133 | 134 | //--- 135 | 136 | func benchPartial32(b *testing.B, length int) { 137 | buf := make([]byte, length) 138 | b.SetBytes(int64(length)) 139 | 140 | start := (32 / 8) / 2 141 | chunks := 7 142 | k := length / chunks 143 | tail := (length - start) % k 144 | 145 | b.ResetTimer() 146 | for i := 0; i < b.N; i++ { 147 | hasher := New32() 148 | hasher.Write(buf[0:start]) 149 | 150 | for j := start; j+k <= length; j += k { 151 | hasher.Write(buf[j : j+k]) 152 | } 153 | 154 | hasher.Write(buf[length-tail:]) 155 | hasher.Sum32() 156 | } 157 | } 158 | 159 | func BenchmarkPartial32_8(b *testing.B) { 160 | benchPartial32(b, 8) 161 | } 162 | func BenchmarkPartial32_16(b *testing.B) { 163 | benchPartial32(b, 16) 164 | } 165 | func BenchmarkPartial32_32(b *testing.B) { 166 | benchPartial32(b, 32) 167 | } 168 | func BenchmarkPartial32_64(b *testing.B) { 169 | benchPartial32(b, 64) 170 | } 171 | func BenchmarkPartial32_128(b *testing.B) { 172 | benchPartial32(b, 128) 173 | } 174 | 175 | //--- 176 | 177 | func bench128(b *testing.B, length int) { 178 | buf := make([]byte, length) 179 | b.SetBytes(int64(length)) 180 | b.ResetTimer() 181 | for i := 0; i < b.N; i++ { 182 | Sum128(buf) 183 | } 184 | } 185 | 186 | func Benchmark128_1(b *testing.B) { 187 | bench128(b, 1) 188 | } 189 | func Benchmark128_2(b *testing.B) { 190 | bench128(b, 2) 191 | } 192 | func Benchmark128_4(b *testing.B) { 193 | bench128(b, 4) 194 | } 195 | func Benchmark128_8(b *testing.B) { 196 | bench128(b, 8) 197 | } 198 | func Benchmark128_16(b *testing.B) { 199 | bench128(b, 16) 200 | } 201 | func Benchmark128_32(b *testing.B) { 202 | bench128(b, 32) 203 | } 204 | func Benchmark128_64(b *testing.B) { 205 | bench128(b, 64) 206 | } 207 | func Benchmark128_128(b *testing.B) { 208 | bench128(b, 128) 209 | } 210 | func Benchmark128_256(b *testing.B) { 211 | bench128(b, 256) 212 | } 213 | func Benchmark128_512(b *testing.B) { 214 | bench128(b, 512) 215 | } 216 | func Benchmark128_1024(b *testing.B) { 217 | bench128(b, 1024) 218 | } 219 | func Benchmark128_2048(b *testing.B) { 220 | bench128(b, 2048) 221 | } 222 | func Benchmark128_4096(b *testing.B) { 223 | bench128(b, 4096) 224 | } 225 | func Benchmark128_8192(b *testing.B) { 226 | bench128(b, 8192) 227 | } 228 | 229 | //--- 230 | -------------------------------------------------------------------------------- /keccak/brg_endian.h: -------------------------------------------------------------------------------- 1 | /* 2 | --------------------------------------------------------------------------- 3 | Copyright (c) 1998-2008, Brian Gladman, Worcester, UK. All rights reserved. 4 | 5 | LICENSE TERMS 6 | 7 | The redistribution and use of this software (with or without changes) 8 | is allowed without the payment of fees or royalties provided that: 9 | 10 | 1. source code distributions include the above copyright notice, this 11 | list of conditions and the following disclaimer; 12 | 13 | 2. binary distributions include the above copyright notice, this list 14 | of conditions and the following disclaimer in their documentation; 15 | 16 | 3. the name of the copyright holder is not used to endorse products 17 | built using this software without specific written permission. 18 | 19 | DISCLAIMER 20 | 21 | This software is provided 'as is' with no explicit or implied warranties 22 | in respect of its properties, including, but not limited to, correctness 23 | and/or fitness for purpose. 24 | --------------------------------------------------------------------------- 25 | Issue Date: 20/12/2007 26 | Changes for ARM 9/9/2010 27 | */ 28 | 29 | #ifndef _BRG_ENDIAN_H 30 | #define _BRG_ENDIAN_H 31 | 32 | #define IS_BIG_ENDIAN 4321 /* byte 0 is most significant (mc68k) */ 33 | #define IS_LITTLE_ENDIAN 1234 /* byte 0 is least significant (i386) */ 34 | 35 | #if 0 36 | /* Include files where endian defines and byteswap functions may reside */ 37 | #if defined( __sun ) 38 | # include 39 | #elif defined( __FreeBSD__ ) || defined( __OpenBSD__ ) || defined( __NetBSD__ ) 40 | # include 41 | #elif defined( BSD ) && ( BSD >= 199103 ) || defined( __APPLE__ ) || \ 42 | defined( __CYGWIN32__ ) || defined( __DJGPP__ ) || defined( __osf__ ) 43 | # include 44 | #elif defined( __linux__ ) || defined( __GNUC__ ) || defined( __GNU_LIBRARY__ ) 45 | # if !defined( __MINGW32__ ) && !defined( _AIX ) 46 | # include 47 | # if !defined( __BEOS__ ) 48 | # include 49 | # endif 50 | # endif 51 | #endif 52 | #endif 53 | 54 | /* Now attempt to set the define for platform byte order using any */ 55 | /* of the four forms SYMBOL, _SYMBOL, __SYMBOL & __SYMBOL__, which */ 56 | /* seem to encompass most endian symbol definitions */ 57 | 58 | #if defined( BIG_ENDIAN ) && defined( LITTLE_ENDIAN ) 59 | # if defined( BYTE_ORDER ) && BYTE_ORDER == BIG_ENDIAN 60 | # define PLATFORM_BYTE_ORDER IS_BIG_ENDIAN 61 | # elif defined( BYTE_ORDER ) && BYTE_ORDER == LITTLE_ENDIAN 62 | # define PLATFORM_BYTE_ORDER IS_LITTLE_ENDIAN 63 | # endif 64 | #elif defined( BIG_ENDIAN ) 65 | # define PLATFORM_BYTE_ORDER IS_BIG_ENDIAN 66 | #elif defined( LITTLE_ENDIAN ) 67 | # define PLATFORM_BYTE_ORDER IS_LITTLE_ENDIAN 68 | #endif 69 | 70 | #if defined( _BIG_ENDIAN ) && defined( _LITTLE_ENDIAN ) 71 | # if defined( _BYTE_ORDER ) && _BYTE_ORDER == _BIG_ENDIAN 72 | # define PLATFORM_BYTE_ORDER IS_BIG_ENDIAN 73 | # elif defined( _BYTE_ORDER ) && _BYTE_ORDER == _LITTLE_ENDIAN 74 | # define PLATFORM_BYTE_ORDER IS_LITTLE_ENDIAN 75 | # endif 76 | #elif defined( _BIG_ENDIAN ) 77 | # define PLATFORM_BYTE_ORDER IS_BIG_ENDIAN 78 | #elif defined( _LITTLE_ENDIAN ) 79 | # define PLATFORM_BYTE_ORDER IS_LITTLE_ENDIAN 80 | #endif 81 | 82 | #if defined( __BIG_ENDIAN ) && defined( __LITTLE_ENDIAN ) 83 | # if defined( __BYTE_ORDER ) && __BYTE_ORDER == __BIG_ENDIAN 84 | # define PLATFORM_BYTE_ORDER IS_BIG_ENDIAN 85 | # elif defined( __BYTE_ORDER ) && __BYTE_ORDER == __LITTLE_ENDIAN 86 | # define PLATFORM_BYTE_ORDER IS_LITTLE_ENDIAN 87 | # endif 88 | #elif defined( __BIG_ENDIAN ) 89 | # define PLATFORM_BYTE_ORDER IS_BIG_ENDIAN 90 | #elif defined( __LITTLE_ENDIAN ) 91 | # define PLATFORM_BYTE_ORDER IS_LITTLE_ENDIAN 92 | #endif 93 | 94 | #if defined( __BIG_ENDIAN__ ) && defined( __LITTLE_ENDIAN__ ) 95 | # if defined( __BYTE_ORDER__ ) && __BYTE_ORDER__ == __BIG_ENDIAN__ 96 | # define PLATFORM_BYTE_ORDER IS_BIG_ENDIAN 97 | # elif defined( __BYTE_ORDER__ ) && __BYTE_ORDER__ == __LITTLE_ENDIAN__ 98 | # define PLATFORM_BYTE_ORDER IS_LITTLE_ENDIAN 99 | # endif 100 | #elif defined( __BIG_ENDIAN__ ) 101 | # define PLATFORM_BYTE_ORDER IS_BIG_ENDIAN 102 | #elif defined( __LITTLE_ENDIAN__ ) 103 | # define PLATFORM_BYTE_ORDER IS_LITTLE_ENDIAN 104 | #endif 105 | 106 | /* if the platform byte order could not be determined, then try to */ 107 | /* set this define using common machine defines */ 108 | #if !defined(PLATFORM_BYTE_ORDER) 109 | 110 | #if defined( __alpha__ ) || defined( __alpha ) || defined( i386 ) || \ 111 | defined( __i386__ ) || defined( _M_I86 ) || defined( _M_IX86 ) || \ 112 | defined( __OS2__ ) || defined( sun386 ) || defined( __TURBOC__ ) || \ 113 | defined( vax ) || defined( vms ) || defined( VMS ) || \ 114 | defined( __VMS ) || defined( _M_X64 ) 115 | # define PLATFORM_BYTE_ORDER IS_LITTLE_ENDIAN 116 | 117 | #elif defined( AMIGA ) || defined( applec ) || defined( __AS400__ ) || \ 118 | defined( _CRAY ) || defined( __hppa ) || defined( __hp9000 ) || \ 119 | defined( ibm370 ) || defined( mc68000 ) || defined( m68k ) || \ 120 | defined( __MRC__ ) || defined( __MVS__ ) || defined( __MWERKS__ ) || \ 121 | defined( sparc ) || defined( __sparc) || defined( SYMANTEC_C ) || \ 122 | defined( __VOS__ ) || defined( __TIGCC__ ) || defined( __TANDEM ) || \ 123 | defined( THINK_C ) || defined( __VMCMS__ ) || defined( _AIX ) 124 | # define PLATFORM_BYTE_ORDER IS_BIG_ENDIAN 125 | 126 | #elif defined(__arm__) 127 | # ifdef __BIG_ENDIAN 128 | # define PLATFORM_BYTE_ORDER IS_BIG_ENDIAN 129 | # else 130 | # define PLATFORM_BYTE_ORDER IS_LITTLE_ENDIAN 131 | # endif 132 | #elif 1 /* **** EDIT HERE IF NECESSARY **** */ 133 | # define PLATFORM_BYTE_ORDER IS_LITTLE_ENDIAN 134 | #elif 0 /* **** EDIT HERE IF NECESSARY **** */ 135 | # define PLATFORM_BYTE_ORDER IS_BIG_ENDIAN 136 | #else 137 | # error Please edit lines 132 or 134 in brg_endian.h to set the platform byte order 138 | #endif 139 | 140 | #endif 141 | 142 | #endif 143 | -------------------------------------------------------------------------------- /siphash/hash128.go: -------------------------------------------------------------------------------- 1 | // +build !amd64 appengine 2 | // Written in 2012 by Dmitry Chestnykh. 3 | // Modifications 2014 for 128-bit hash function by Damian Gryski. 4 | // 5 | // To the extent possible under law, the authors 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 | 10 | package siphash 11 | 12 | // Hash returns the 128-bit SipHash-2-4 of the given byte slice with two 64-bit 13 | // parts of 128-bit key: k0 and k1. 14 | // 15 | // Note that 128-bit SipHash is considered experimental by SipHash authors at this time. 16 | func Hash128(k0, k1 uint64, p []byte) (uint64, uint64) { 17 | // Initialization. 18 | v0 := k0 ^ 0x736f6d6570736575 19 | v1 := k1 ^ 0x646f72616e646f6d 20 | v2 := k0 ^ 0x6c7967656e657261 21 | v3 := k1 ^ 0x7465646279746573 22 | t := uint64(len(p)) << 56 23 | 24 | v1 ^= 0xee 25 | 26 | // Compression. 27 | for len(p) >= BlockSize { 28 | m := uint64(p[0]) | uint64(p[1])<<8 | uint64(p[2])<<16 | uint64(p[3])<<24 | 29 | uint64(p[4])<<32 | uint64(p[5])<<40 | uint64(p[6])<<48 | uint64(p[7])<<56 30 | v3 ^= m 31 | 32 | // Round 1. 33 | v0 += v1 34 | v1 = v1<<13 | v1>>(64-13) 35 | v1 ^= v0 36 | v0 = v0<<32 | v0>>(64-32) 37 | 38 | v2 += v3 39 | v3 = v3<<16 | v3>>(64-16) 40 | v3 ^= v2 41 | 42 | v0 += v3 43 | v3 = v3<<21 | v3>>(64-21) 44 | v3 ^= v0 45 | 46 | v2 += v1 47 | v1 = v1<<17 | v1>>(64-17) 48 | v1 ^= v2 49 | v2 = v2<<32 | v2>>(64-32) 50 | 51 | // Round 2. 52 | v0 += v1 53 | v1 = v1<<13 | v1>>(64-13) 54 | v1 ^= v0 55 | v0 = v0<<32 | v0>>(64-32) 56 | 57 | v2 += v3 58 | v3 = v3<<16 | v3>>(64-16) 59 | v3 ^= v2 60 | 61 | v0 += v3 62 | v3 = v3<<21 | v3>>(64-21) 63 | v3 ^= v0 64 | 65 | v2 += v1 66 | v1 = v1<<17 | v1>>(64-17) 67 | v1 ^= v2 68 | v2 = v2<<32 | v2>>(64-32) 69 | 70 | v0 ^= m 71 | p = p[BlockSize:] 72 | } 73 | 74 | // Compress last block. 75 | switch len(p) { 76 | case 7: 77 | t |= uint64(p[6]) << 48 78 | fallthrough 79 | case 6: 80 | t |= uint64(p[5]) << 40 81 | fallthrough 82 | case 5: 83 | t |= uint64(p[4]) << 32 84 | fallthrough 85 | case 4: 86 | t |= uint64(p[3]) << 24 87 | fallthrough 88 | case 3: 89 | t |= uint64(p[2]) << 16 90 | fallthrough 91 | case 2: 92 | t |= uint64(p[1]) << 8 93 | fallthrough 94 | case 1: 95 | t |= uint64(p[0]) 96 | } 97 | 98 | v3 ^= t 99 | 100 | // Round 1. 101 | v0 += v1 102 | v1 = v1<<13 | v1>>(64-13) 103 | v1 ^= v0 104 | v0 = v0<<32 | v0>>(64-32) 105 | 106 | v2 += v3 107 | v3 = v3<<16 | v3>>(64-16) 108 | v3 ^= v2 109 | 110 | v0 += v3 111 | v3 = v3<<21 | v3>>(64-21) 112 | v3 ^= v0 113 | 114 | v2 += v1 115 | v1 = v1<<17 | v1>>(64-17) 116 | v1 ^= v2 117 | v2 = v2<<32 | v2>>(64-32) 118 | 119 | // Round 2. 120 | v0 += v1 121 | v1 = v1<<13 | v1>>(64-13) 122 | v1 ^= v0 123 | v0 = v0<<32 | v0>>(64-32) 124 | 125 | v2 += v3 126 | v3 = v3<<16 | v3>>(64-16) 127 | v3 ^= v2 128 | 129 | v0 += v3 130 | v3 = v3<<21 | v3>>(64-21) 131 | v3 ^= v0 132 | 133 | v2 += v1 134 | v1 = v1<<17 | v1>>(64-17) 135 | v1 ^= v2 136 | v2 = v2<<32 | v2>>(64-32) 137 | 138 | v0 ^= t 139 | 140 | // Finalization. 141 | v2 ^= 0xee 142 | 143 | // Round 1. 144 | v0 += v1 145 | v1 = v1<<13 | v1>>(64-13) 146 | v1 ^= v0 147 | v0 = v0<<32 | v0>>(64-32) 148 | 149 | v2 += v3 150 | v3 = v3<<16 | v3>>(64-16) 151 | v3 ^= v2 152 | 153 | v0 += v3 154 | v3 = v3<<21 | v3>>(64-21) 155 | v3 ^= v0 156 | 157 | v2 += v1 158 | v1 = v1<<17 | v1>>(64-17) 159 | v1 ^= v2 160 | v2 = v2<<32 | v2>>(64-32) 161 | 162 | // Round 2. 163 | v0 += v1 164 | v1 = v1<<13 | v1>>(64-13) 165 | v1 ^= v0 166 | v0 = v0<<32 | v0>>(64-32) 167 | 168 | v2 += v3 169 | v3 = v3<<16 | v3>>(64-16) 170 | v3 ^= v2 171 | 172 | v0 += v3 173 | v3 = v3<<21 | v3>>(64-21) 174 | v3 ^= v0 175 | 176 | v2 += v1 177 | v1 = v1<<17 | v1>>(64-17) 178 | v1 ^= v2 179 | v2 = v2<<32 | v2>>(64-32) 180 | 181 | // Round 3. 182 | v0 += v1 183 | v1 = v1<<13 | v1>>(64-13) 184 | v1 ^= v0 185 | v0 = v0<<32 | v0>>(64-32) 186 | 187 | v2 += v3 188 | v3 = v3<<16 | v3>>(64-16) 189 | v3 ^= v2 190 | 191 | v0 += v3 192 | v3 = v3<<21 | v3>>(64-21) 193 | v3 ^= v0 194 | 195 | v2 += v1 196 | v1 = v1<<17 | v1>>(64-17) 197 | v1 ^= v2 198 | v2 = v2<<32 | v2>>(64-32) 199 | 200 | // Round 4. 201 | v0 += v1 202 | v1 = v1<<13 | v1>>(64-13) 203 | v1 ^= v0 204 | v0 = v0<<32 | v0>>(64-32) 205 | 206 | v2 += v3 207 | v3 = v3<<16 | v3>>(64-16) 208 | v3 ^= v2 209 | 210 | v0 += v3 211 | v3 = v3<<21 | v3>>(64-21) 212 | v3 ^= v0 213 | 214 | v2 += v1 215 | v1 = v1<<17 | v1>>(64-17) 216 | v1 ^= v2 217 | v2 = v2<<32 | v2>>(64-32) 218 | 219 | r0 := v0 ^ v1 ^ v2 ^ v3 220 | 221 | v1 ^= 0xdd 222 | 223 | // Round 1. 224 | v0 += v1 225 | v1 = v1<<13 | v1>>(64-13) 226 | v1 ^= v0 227 | v0 = v0<<32 | v0>>(64-32) 228 | 229 | v2 += v3 230 | v3 = v3<<16 | v3>>(64-16) 231 | v3 ^= v2 232 | 233 | v0 += v3 234 | v3 = v3<<21 | v3>>(64-21) 235 | v3 ^= v0 236 | 237 | v2 += v1 238 | v1 = v1<<17 | v1>>(64-17) 239 | v1 ^= v2 240 | v2 = v2<<32 | v2>>(64-32) 241 | 242 | // Round 2. 243 | v0 += v1 244 | v1 = v1<<13 | v1>>(64-13) 245 | v1 ^= v0 246 | v0 = v0<<32 | v0>>(64-32) 247 | 248 | v2 += v3 249 | v3 = v3<<16 | v3>>(64-16) 250 | v3 ^= v2 251 | 252 | v0 += v3 253 | v3 = v3<<21 | v3>>(64-21) 254 | v3 ^= v0 255 | 256 | v2 += v1 257 | v1 = v1<<17 | v1>>(64-17) 258 | v1 ^= v2 259 | v2 = v2<<32 | v2>>(64-32) 260 | 261 | // Round 3. 262 | v0 += v1 263 | v1 = v1<<13 | v1>>(64-13) 264 | v1 ^= v0 265 | v0 = v0<<32 | v0>>(64-32) 266 | 267 | v2 += v3 268 | v3 = v3<<16 | v3>>(64-16) 269 | v3 ^= v2 270 | 271 | v0 += v3 272 | v3 = v3<<21 | v3>>(64-21) 273 | v3 ^= v0 274 | 275 | v2 += v1 276 | v1 = v1<<17 | v1>>(64-17) 277 | v1 ^= v2 278 | v2 = v2<<32 | v2>>(64-32) 279 | 280 | // Round 4. 281 | v0 += v1 282 | v1 = v1<<13 | v1>>(64-13) 283 | v1 ^= v0 284 | v0 = v0<<32 | v0>>(64-32) 285 | 286 | v2 += v3 287 | v3 = v3<<16 | v3>>(64-16) 288 | v3 ^= v2 289 | 290 | v0 += v3 291 | v3 = v3<<21 | v3>>(64-21) 292 | v3 ^= v0 293 | 294 | v2 += v1 295 | v1 = v1<<17 | v1>>(64-17) 296 | v1 ^= v2 297 | v2 = v2<<32 | v2>>(64-32) 298 | 299 | r1 := v0 ^ v1 ^ v2 ^ v3 300 | 301 | return r0, r1 302 | } 303 | -------------------------------------------------------------------------------- /siphashpg/siphash.go: -------------------------------------------------------------------------------- 1 | // Copyright © 2014 Lawrence E. Bakst. All rights reserved. 2 | // transliterated from the reference implementation cited below 3 | // This version only works for LE 4 | 5 | /* 6 | SipHash reference C implementation 7 | 8 | Copyright (c) 2012-2014 Jean-Philippe Aumasson 9 | Copyright (c) 2012-2014 Daniel J. Bernstein 10 | 11 | To the extent possible under law, the author(s) have dedicated all copyright 12 | and related and neighboring rights to this software to the public domain 13 | worldwide. This software is distributed without any warranty. 14 | 15 | You should have received a copy of the CC0 Public Domain Dedication along with 16 | this software. If not, see . 17 | */ 18 | 19 | package siphashpg 20 | 21 | import "fmt" 22 | import "unsafe" 23 | /* default: SipHash-2-4 */ 24 | const ( 25 | Crounds = 2 26 | Drounds = 4 27 | ) 28 | 29 | func rotl(x, b uint64) uint64 { 30 | return ((x) << (b)) | ( (x) >> (64 - (b))) 31 | } 32 | 33 | func U8tou64le(p []byte) uint64 { 34 | /* 35 | for k, v := range p { 36 | fmt.Printf("p[%d]=0x%x\n", k, v) 37 | } 38 | */ 39 | return 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 40 | } 41 | 42 | func U64tou8le(v uint64) (r []byte) { 43 | r = make([]byte, 8, 8) 44 | r = r[:] 45 | for k, _ := range r { 46 | r[k] = byte(v&0xFF) 47 | v >>= 8 48 | } 49 | return 50 | } 51 | 52 | func siprounda(v0, v1, v2, v3 uint64) (uint64, uint64, uint64, uint64) { 53 | v0 += v1; v1=rotl(v1,13); v1 ^= v0; v0=rotl(v0,32); 54 | v2 += v3; v3=rotl(v3,16); v3 ^= v2; 55 | return v0, v1, v2, v3 56 | } 57 | 58 | func siproundb(v0, v1, v2, v3 uint64) (uint64, uint64, uint64, uint64) { 59 | v0 += v3; v3=rotl(v3,21); v3 ^= v0; 60 | v2 += v1; v1=rotl(v1,17); v1 ^= v2; v2=rotl(v2,32); 61 | return v0, v1, v2, v3 62 | } 63 | 64 | func TRACE(inlen int, v0, v1, v2, v3 uint64) { 65 | return 66 | fmt.Printf( "(%3d) v0 %08x %08x\n", inlen, v0 >> 32, v0&0xFFFFFFFF) 67 | fmt.Printf( "(%3d) v1 %08x %08x\n", inlen, v1 >> 32, v1&0xFFFFFFFF) 68 | fmt.Printf( "(%3d) v2 %08x %08x\n", inlen, v2 >> 32, v2&0xFFFFFFFF) 69 | fmt.Printf( "(%3d) v3 %08x %08x\n", inlen, v3 >> 32, v3&0xFFFFFFFF) 70 | } 71 | 72 | // This makes a new slice of uint64 that points to the same slice passed in as []byte. 73 | // We should check alignment for architectures that don't handle unaligned reads. 74 | // Fallback to a copy or maybe use encoding/binary? 75 | // Not sure what the right thing to do is for little vs big endian? 76 | // What are the right test vevtors for big-endian machines. 77 | func sliceUI64(in []byte) []uint64 { 78 | return (*(*[]uint64)(unsafe.Pointer(&in)))[:len(in)/8] 79 | } 80 | 81 | // take input slice in and seeds k as well a compression and final rounds cr, dr 82 | // return a 64 bit hash in ra and if dbl is true a 128 bit hash in ra and rb 83 | func Siphash(in []byte, k []byte, cr, dr int, dbl bool) (ra, rb uint64) { 84 | var fast = true 85 | var v0, v1, v2, v3 uint64 86 | var sipround = func() { 87 | v0 += v1; v1=rotl(v1,13); v1 ^= v0; v0=rotl(v0,32); 88 | v2 += v3; v3=rotl(v3,16); v3 ^= v2; 89 | v0 += v3; v3=rotl(v3,21); v3 ^= v0; 90 | v2 += v1; v1=rotl(v1,17); v1 ^= v2; v2=rotl(v2,32); 91 | } 92 | 93 | if len(k) != 16 || cr <= 0 || dr <= 0 { 94 | panic("siphash") 95 | } 96 | // initialize state 97 | /* "somepseudorandomlygeneratedbytes" */ 98 | v0 = uint64(0x736f6d6570736575) 99 | v1 = uint64(0x646f72616e646f6d) 100 | v2 = uint64(0x6c7967656e657261) 101 | v3 = uint64(0x7465646279746573) 102 | 103 | k0 := U8tou64le(k) 104 | k1 := U8tou64le(k[8:]) 105 | b := uint64(len(in)) << 56 106 | //fmt.Printf("k=%v, k0=0x%08x, k1=0x%08x, b=0x%08x\n", k, k0, k1, b) 107 | 108 | v3 ^= k1 109 | v2 ^= k0 110 | v1 ^= k1 111 | v0 ^= k0 112 | 113 | if dbl { 114 | v1 ^= 0xee 115 | } 116 | 117 | k64 := sliceUI64(in) 118 | cnt := 0 119 | l := len(in) 120 | // peel off as many 64 bit words as we have 121 | if fast { 122 | for ; l >= 8; in = in[8:] { 123 | m := k64[cnt] 124 | cnt++ 125 | l -= 8 126 | v3 ^= m 127 | 128 | //TRACE(len(in), v0, v1, v2, v3) 129 | for i := 0; i < cr; i++ { 130 | sipround() 131 | //v0, v1, v2, v3 = siprounda(v0, v1, v2, v3) 132 | //v0, v1, v2, v3 = siproundb(v0, v1, v2, v3) 133 | } 134 | v0 ^= m 135 | } 136 | } else { 137 | for ; len(in) >= 8; in = in[8:] { 138 | m := U8tou64le(in) 139 | v3 ^= m 140 | 141 | //TRACE(len(in), v0, v1, v2, v3) 142 | for i := 0; i < cr; i++ { 143 | sipround() 144 | //v0, v1, v2, v3 = siprounda(v0, v1, v2, v3) 145 | //v0, v1, v2, v3 = siproundb(v0, v1, v2, v3) 146 | } 147 | v0 ^= m 148 | } 149 | } 150 | 151 | //fmt.Printf("in=%v, len(in)=%d\n", in, len(in)) 152 | // deal with the tail 153 | switch len(in) { 154 | case 7: 155 | b |= uint64(in[6]) << 48 156 | fallthrough 157 | case 6: 158 | b |= uint64(in[5]) << 40 159 | fallthrough 160 | case 5: 161 | b |= uint64(in[4]) << 32 162 | fallthrough 163 | case 4: 164 | b |= uint64(in[3]) << 24 165 | fallthrough 166 | case 3: 167 | b |= uint64(in[2]) << 16 168 | fallthrough 169 | case 2: 170 | b |= uint64(in[1]) << 8 171 | fallthrough 172 | case 1: 173 | b |= uint64(in[0]) 174 | break; 175 | case 0: 176 | break; 177 | default: 178 | //fmt.Printf("len(in)=%d\n", len(in)) 179 | panic("siphash bad length") 180 | } 181 | v3 ^= b; 182 | 183 | //TRACE(len(in), v0, v1, v2, v3) 184 | for i := 0; i < cr; i++ { 185 | sipround() 186 | //v0, v1, v2, v3 = siprounda(v0, v1, v2, v3) 187 | //v0, v1, v2, v3 = siproundb(v0, v1, v2, v3) 188 | } 189 | v0 ^= b 190 | 191 | if dbl { 192 | v2 ^= 0xee 193 | } else { 194 | v2 ^= 0xff 195 | } 196 | 197 | //TRACE(len(in), v0, v1, v2, v3) 198 | for i := 0; i < dr; i++ { 199 | sipround() 200 | //v0, v1, v2, v3 = siprounda(v0, v1, v2, v3) 201 | //v0, v1, v2, v3 = siproundb(v0, v1, v2, v3) 202 | } 203 | b = v0 ^ v1 ^ v2 ^ v3 204 | ra = b 205 | 206 | // if 128 bit result desired run some more rounds and get another 64 bits 207 | if dbl { 208 | v1 ^= 0xdd 209 | //TRACE(len(in), v0, v1, v2, v3) 210 | for i := 0; i < dr; i++ { 211 | sipround() 212 | //v0, v1, v2, v3 = siprounda(v0, v1, v2, v3) 213 | //v0, v1, v2, v3 = siproundb(v0, v1, v2, v3) 214 | } 215 | b = v0 ^ v1 ^ v2 ^ v3 216 | rb = b 217 | } 218 | return 219 | } -------------------------------------------------------------------------------- /jenkins/jenkins_test.go: -------------------------------------------------------------------------------- 1 | // Copyright © 2014 Lawrence E. Bakst. All rights reserved. 2 | package jenkins_test 3 | 4 | //import "flag" 5 | import ( 6 | "fmt" 7 | "testing" 8 | "time" 9 | "unsafe" 10 | 11 | "leb.io/hashland/jenkins" 12 | "leb.io/hrff" 13 | ) 14 | 15 | //import "math" 16 | //import "math/rand" 17 | //import "runtime" 18 | 19 | func stu(s string) []uint32 { 20 | //fmt.Printf("stu: s=%q\n", s) 21 | l := (len(s) + 3) / 4 22 | d := make([]uint32, l, l) 23 | d = d[0:0] 24 | b := ([]byte)(s) 25 | //fmt.Printf("b=%x\n", b) 26 | for i := 0; i < l; i++ { 27 | t := *(*uint32)(unsafe.Pointer(&b[i*4])) 28 | //fmt.Printf("t=%x \n", t) 29 | d = append(d, t) 30 | } 31 | //fmt.Printf("stu: len(s)=%d, len(d)=%d, d=%x\n", len(s), len(d), d) 32 | return d 33 | } 34 | 35 | func tdiff(begin, end time.Time) time.Duration { 36 | d := end.Sub(begin) 37 | return d 38 | } 39 | 40 | func TestCheck(t *testing.T) { 41 | jenkins.Check() 42 | } 43 | 44 | func TestBasic(t *testing.T) { 45 | 46 | q := "This is the time for all good men to come to the aid of their country..." 47 | //qq := []byte{"xThis is the time for all good men to come to the aid of their country..."} 48 | //qqq := []byte{"xxThis is the time for all good men to come to the aid of their country..."} 49 | //qqqq[] := []byte{"xxxThis is the time for all good men to come to the aid of their country..."} 50 | 51 | u := stu(q) 52 | fmt.Printf("len(q)=%d, len(u)=%d\n", len(q), len(u)) 53 | h1 := jenkins.HashWordsLen(u, 13, 0) 54 | fmt.Printf("%08x, %0x8, %08x\n", h1, h1, h1) 55 | 56 | b, c := uint32(0), uint32(0) 57 | c, b = jenkins.HashString("", c, b) 58 | //fmt.Printf("%08x, %08x\n", c, b) 59 | if c != 0xdeadbeef || b != 0xdeadbeef { 60 | t.Logf("c=0x%x != 0xdeadbeef || b=0x%x != 0xdeadbeef\n", c, b) 61 | t.FailNow() 62 | } 63 | 64 | b, c = 0xdeadbeef, 0 65 | c, b = jenkins.HashString("", c, b) 66 | //fmt.Printf("%08x, %08x\n", c, b) // bd5b7dde deadbeef 67 | if c != 0xbd5b7dde || b != 0xdeadbeef { 68 | t.Logf("c=0x%x != 0xbd5b7dde || b=0x%x != 0xdeadbeef\n", c, b) 69 | t.FailNow() 70 | } 71 | 72 | b, c = 0xdeadbeef, 0xdeadbeef 73 | c, b = jenkins.HashString("", c, b) 74 | //fmt.Printf("%08x, %08x\n", c, b) // 9c093ccd bd5b7dde 75 | if c != 0x9c093ccd || b != 0xbd5b7dde { 76 | t.Logf("c=0x%x != 0x9c093ccd || b=0x%x != 0xbd5b7dde\n", c, b) 77 | t.FailNow() 78 | } 79 | 80 | b, c = 0, 0 81 | c, b = jenkins.HashString("Four score and seven years ago", c, b) 82 | //fmt.Printf("%08x, %08x\n", c, b) // 17770551 ce7226e6 83 | if c != 0x17770551 || b != 0xce7226e6 { 84 | t.Logf("c=0x%x != 0x17770551 || b=0x%x != 0xce7226e6\n", c, b) 85 | t.FailNow() 86 | } 87 | 88 | b, c = 1, 0 89 | c, b = jenkins.HashString("Four score and seven years ago", c, b) 90 | //fmt.Printf("%08x, %08x\n", c, b) // e3607cae bd371de4 91 | if c != 0xe3607cae || b != 0xbd371de4 { 92 | t.Logf("c=0x%x != 0xe3607cae || b=0x%x != 0xbd371de4\n", c, b) 93 | t.FailNow() 94 | } 95 | 96 | b, c = 0, 1 97 | c, b = jenkins.HashString("Four score and seven years ago", c, b) 98 | //fmt.Printf("%08x, %08x\n", c, b) // cd628161 6cbea4b3 99 | if c != 0xcd628161 || b != 0x6cbea4b3 { 100 | t.Logf("c=0x%x != 0xcd628161 || b=0x%x != 0x6cbea4b3\n", c, b) 101 | t.FailNow() 102 | } 103 | 104 | } 105 | 106 | func TestHash32v(t *testing.T) { 107 | k := make([]byte, 30, 30) 108 | seed := uint32(0) 109 | for i := 0; i < len(k); i++ { 110 | h := jenkins.Hash232(k[:i], seed) 111 | fmt.Printf("i=%03d, h=0x%08x, k=%v\n", i, h, k[:i]) // 0x8965bbe9 112 | } 113 | } 114 | 115 | func TestHash32(t *testing.T) { 116 | k := make([]byte, 4, 4) 117 | k = k[:] 118 | seed := uint32(0) 119 | h := jenkins.Hash232(k, seed) 120 | fmt.Printf("k=%v, h=0x%08x\n", k, h) // 0x8965bbe9 121 | } 122 | 123 | func TestHash64(t *testing.T) { 124 | k := make([]byte, 24, 24) 125 | k = k[:] 126 | seed := uint64(0) 127 | h := jenkins.Hash264(k, seed) 128 | fmt.Printf("k=%v, h=0x%016x\n", k, h) // 0x74882dd69da95fae 129 | } 130 | 131 | func BenchmarkJenkins332(b *testing.B) { 132 | //tmp := make([]byte, 4, 4) 133 | us := make([]uint32, 1) 134 | start := time.Now() 135 | b.SetBytes(int64(b.N * 4)) 136 | for i := 1; i <= b.N; i++ { 137 | us[0] = uint32(i) 138 | //tmp[0], tmp[1], tmp[2], tmp[3] = byte(key&0xFF), byte((key>>8)&0xFF), byte((key>>16)&0xFF), byte((key>>24)&0xFF) 139 | jenkins.HashWords332(us, 0) 140 | } 141 | stop := time.Now() 142 | dur := tdiff(start, stop) 143 | hsec := hrff.Float64{(float64(b.N) / dur.Seconds()), "hashes/sec"} 144 | fmt.Printf("bench: %h\n", hsec) 145 | bsec := hrff.Float64{(float64(b.N) * 4 / dur.Seconds()), "B/sec"} 146 | fmt.Printf("bench: %h\n", bsec) 147 | } 148 | 149 | func BenchmarkJenkins232(b *testing.B) { 150 | bs := make([]byte, 4, 4) 151 | start := time.Now() 152 | b.SetBytes(int64(b.N * 4)) 153 | for i := 1; i <= b.N; i++ { 154 | bs[0], bs[1], bs[2], bs[3] = byte(i)&0xFF, (byte(i)>>8)&0xFF, (byte(i)>>16)&0xFF, (byte(i)>>24)&0xFF 155 | //tmp[0], tmp[1], tmp[2], tmp[3] = byte(key&0xFF), byte((key>>8)&0xFF), byte((key>>16)&0xFF), byte((key>>24)&0xFF) 156 | jenkins.Hash232(bs, 0) 157 | } 158 | stop := time.Now() 159 | dur := tdiff(start, stop) 160 | hsec := hrff.Float64{(float64(b.N) / dur.Seconds()), "hashes/sec"} 161 | fmt.Printf("bench: %h\n", hsec) 162 | bsec := hrff.Float64{(float64(b.N) * 4 / dur.Seconds()), "B/sec"} 163 | fmt.Printf("bench: %h\n", bsec) 164 | } 165 | 166 | func BenchmarkJenkins264Bytes4(b *testing.B) { 167 | bs := make([]byte, 4, 4) 168 | start := time.Now() 169 | b.SetBytes(int64(b.N * 4)) 170 | for i := 1; i <= b.N; i++ { 171 | bs[0], bs[1], bs[2], bs[3] = byte(i)&0xFF, (byte(i)>>8)&0xFF, (byte(i)>>16)&0xFF, (byte(i)>>24)&0xFF 172 | //tmp[0], tmp[1], tmp[2], tmp[3] = byte(key&0xFF), byte((key>>8)&0xFF), byte((key>>16)&0xFF), byte((key>>24)&0xFF) 173 | jenkins.Hash264(bs, 0) 174 | } 175 | stop := time.Now() 176 | dur := tdiff(start, stop) 177 | hsec := hrff.Float64{(float64(b.N) / dur.Seconds()), "hashes/sec"} 178 | fmt.Printf("bench: %h\n", hsec) 179 | bsec := hrff.Float64{(float64(b.N) * 4 / dur.Seconds()), "B/sec"} 180 | fmt.Printf("bench: %h\n", bsec) 181 | } 182 | 183 | func BenchmarkJenkins264Bytes24(b *testing.B) { 184 | bs := make([]byte, 24, 24) 185 | start := time.Now() 186 | b.SetBytes(int64(b.N * 4)) 187 | for i := 1; i <= b.N; i++ { 188 | bs[0], bs[1], bs[2], bs[3] = byte(i)&0xFF, (byte(i)>>8)&0xFF, (byte(i)>>16)&0xFF, (byte(i)>>24)&0xFF 189 | bs[4], bs[5], bs[6], bs[7] = bs[0], bs[1], bs[2], bs[3] 190 | bs[8], bs[9], bs[10], bs[11], bs[12], bs[13], bs[14], bs[15] = bs[0], bs[1], bs[2], bs[3], bs[4], bs[5], bs[6], bs[7] 191 | bs[16], bs[17], bs[18], bs[19], bs[20], bs[21], bs[22], bs[23] = bs[0], bs[1], bs[2], bs[3], bs[4], bs[5], bs[6], bs[7] 192 | jenkins.Hash264(bs, 0) 193 | } 194 | stop := time.Now() 195 | dur := tdiff(start, stop) 196 | hsec := hrff.Float64{(float64(b.N) / dur.Seconds()), "hashes/sec"} 197 | fmt.Printf("bench: %h\n", hsec) 198 | bsec := hrff.Float64{(float64(b.N) * 4 / dur.Seconds()), "B/sec"} 199 | fmt.Printf("bench: %h\n", bsec) 200 | } 201 | 202 | /* 203 | func main() { 204 | q := "This is the time for all good men to come to the aid of their country..." 205 | //qq := []byte{"xThis is the time for all good men to come to the aid of their country..."} 206 | //qqq := []byte{"xxThis is the time for all good men to come to the aid of their country..."} 207 | //qqqq[] := []byte{"xxxThis is the time for all good men to come to the aid of their country..."} 208 | 209 | u := stu(q) 210 | h1 := hashword(u, (len(q)-1)/4, 13) 211 | h2 := hashword(u, (len(q)-5)/4, 13) 212 | h3 := hashword(u, (len(q)-9)/4, 13) 213 | fmt.Printf("%08x, %0x8, %08x\n", h1, h2, h3) 214 | 215 | 216 | } 217 | */ 218 | -------------------------------------------------------------------------------- /threefish/threefish.go: -------------------------------------------------------------------------------- 1 | // Copyright (C) 2011 Werner Dittmann 2 | // 3 | // This program is free software: you can redistribute it and/or modify 4 | // it under the terms of the GNU General Public License as published by 5 | // the Free Software Foundation, either version 3 of the License, or 6 | // (at your option) any later version. 7 | // 8 | // This program is distributed in the hope that it will be useful, 9 | // but WITHOUT ANY WARRANTY; without even the implied warranty of 10 | // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 11 | // GNU General Public License for more details. 12 | // 13 | // You should have received a copy of the GNU General Public License 14 | // along with this program. If not, see . 15 | // 16 | // Authors: Werner Dittmann 17 | // 18 | 19 | // This package implements the Threefish cipher as specified in the Skein V1.3 20 | // specification. The Skein digest algorithm uses Threefish to generate 21 | // the digests. 22 | // 23 | // NOTE: Threefish is a new cipher algorithm - use with care until fully analysed. 24 | // 25 | package threefish 26 | 27 | import ( 28 | "strconv" 29 | "encoding/binary" 30 | ) 31 | 32 | // General Threefish constants 33 | // 34 | const ( 35 | KEY_SCHEDULE_CONST = uint64(0x1BD11BDAA9FC1A22) 36 | EXPANDED_TWEAK_SIZE = 3 37 | ) 38 | 39 | // Internal interface to simplify Threefish usage 40 | // 41 | type cipherInternal interface { 42 | // Encrypt function 43 | // 44 | // Derived classes must implement this function. 45 | // 46 | // input 47 | // The plaintext input. 48 | // output 49 | // The ciphertext output. 50 | // 51 | encrypt(input, output []uint64) 52 | 53 | // Decrypt function 54 | // 55 | // Derived classes must implement this function. 56 | // 57 | // input 58 | // The ciphertext input. 59 | // output 60 | // The plaintext output. 61 | // 62 | decrypt(input, output []uint64) 63 | 64 | getTempData() ([]uint64, []uint64) 65 | setTweak(tweak []uint64) 66 | setKey(key []uint64) 67 | } 68 | 69 | // A Cipher is an instance of Threefish using a particular key and state size. 70 | // 71 | type Cipher struct { 72 | stateSize int 73 | cipherInternal 74 | } 75 | 76 | type KeySizeError int 77 | 78 | func (k KeySizeError) Error() string { 79 | return "crypto/threefish: invalid key size " + strconv.Itoa(int(k)) 80 | } 81 | 82 | // NewCipher creates and returns a Cipher. 83 | // 84 | // The key length can be 32, 64 or 128 bytes and must match the Threefish 85 | // state size. The blocksize is the same as the key length (state size). 86 | // The tweak is a uint64 array with two elements. 87 | // 88 | // key 89 | // Key data, key length selects the internal state size 90 | // tweak 91 | // The initial Tweak data for this threefish instance 92 | // 93 | func New(key []byte, tweak []uint64) (*Cipher, error) { 94 | var err error 95 | var internal cipherInternal 96 | 97 | switch len(key) { 98 | case 32: 99 | internal, err = newThreefish256(key, tweak) 100 | case 64: 101 | internal, err = newThreefish512(key, tweak) 102 | case 128: 103 | internal, err = newThreefish1024(key, tweak) 104 | default: 105 | return nil, KeySizeError(len(key)) 106 | } 107 | return &Cipher{len(key) * 8, internal}, err 108 | } 109 | 110 | // New64 creates and returns a Cipher. 111 | // 112 | // The key is a uint64 array of 4, 8 or 16 elements. The key length must match the 113 | // Threefish state size. The blocksize is the same as the key length (state size). 114 | // The tweak is a uint64 array with two elements. 115 | // 116 | // key 117 | // Key data, key length selects the internal state size 118 | // tweak 119 | // The initial Tweak data for this threefish instance 120 | // 121 | func New64(key, tweak []uint64) (*Cipher, error) { 122 | var err error 123 | var internal cipherInternal 124 | 125 | switch len(key) { 126 | case 4: 127 | internal, err = newThreefish256_64(key, tweak) 128 | case 8: 129 | internal, err = newThreefish512_64(key, tweak) 130 | case 16: 131 | internal, err = newThreefish1024_64(key, tweak) 132 | default: 133 | return nil, KeySizeError(len(key)) 134 | } 135 | return &Cipher{len(key) * 8, internal}, err 136 | } 137 | 138 | // NewSize creates and returns a Cipher. 139 | // 140 | // The size argument is the requested Threefish state size 141 | // which is also the key and block size. Supported sizes see constants section. 142 | // 143 | func NewSize(size int) (*Cipher, error) { 144 | var err error 145 | var internal cipherInternal 146 | 147 | switch size { 148 | case 256: 149 | internal, err = newThreefish256(nil, nil) 150 | case 512: 151 | internal, err = newThreefish512(nil, nil) 152 | case 1024: 153 | internal, err = newThreefish1024(nil, nil) 154 | default: 155 | return nil, KeySizeError(size) 156 | } 157 | return &Cipher{size, internal}, err 158 | } 159 | 160 | // BlockSize returns the cipher's block size in bytes. 161 | // 162 | func (c *Cipher) BlockSize() int { 163 | return c.stateSize / 8 164 | } 165 | 166 | // Encrypt a block. 167 | // Dst and src may point at the same memory. 168 | // 169 | // dst 170 | // Destination of encypted data (cipher data) 171 | // src 172 | // Contains a block of plain data 173 | // 174 | func (c *Cipher) Encrypt(dst, src []byte) { 175 | 176 | uintLen := c.stateSize / 64 177 | 178 | // This saves makes 179 | tmpin, tmpout := c.getTempData() 180 | 181 | for i := 0; i < uintLen; i++ { 182 | tmpin[i] = binary.LittleEndian.Uint64(src[i*8 : i*8+8]) 183 | } 184 | c.encrypt(tmpin, tmpout) 185 | 186 | for i := 0; i < uintLen; i++ { 187 | binary.LittleEndian.PutUint64(dst[i*8:i*8+8], tmpout[i]) 188 | } 189 | } 190 | 191 | // Decrypt a block. 192 | // Dst and src may point at the same memory. 193 | // 194 | // dst 195 | // Destination of encypted data (cipher data) 196 | // src 197 | // Contains a block of plain data 198 | // 199 | func (c *Cipher) Decrypt(dst, src []byte) { 200 | 201 | uintLen := c.stateSize / 64 202 | 203 | // This saves a make because tmpin and tmpout are of variable length 204 | tmpin, tmpout := c.getTempData() 205 | 206 | for i := 0; i < uintLen; i++ { 207 | tmpin[i] = binary.LittleEndian.Uint64(src[i*8 : i*8+8]) 208 | } 209 | c.decrypt(tmpin, tmpout) 210 | 211 | for i := 0; i < uintLen; i++ { 212 | binary.LittleEndian.PutUint64(dst[i*8:i*8+8], tmpout[i]) 213 | } 214 | } 215 | 216 | // Encrypt a block. 217 | // Blocks are unit64 arrays. 218 | // Dst and src may point at the same memory. 219 | // 220 | // dst 221 | // Destination of encypted data (cipher data) 222 | // src 223 | // Contains a block of plain data 224 | // 225 | func (c *Cipher) Encrypt64(dst, src []uint64) { 226 | c.encrypt(src, dst) 227 | } 228 | 229 | // Decrypt a block. 230 | // Blocks are unit64 arrays. 231 | // Dst and src may point at the same memory. 232 | // 233 | // dst 234 | // Destination of decrypted data (plain data) 235 | // src 236 | // Contains a block of encrypted data (cipher data) 237 | // 238 | func (c *Cipher) Decrypt64(dst, src []uint64) { 239 | c.decrypt(src, dst) 240 | } 241 | 242 | // Set the tweak data. 243 | // 244 | // The tweak is a uint64 array with two elements. 245 | // 246 | func (c *Cipher) SetTweak(tweak []uint64) { 247 | c.setTweak(tweak) 248 | } 249 | 250 | // Set the key. 251 | // 252 | // The key must have the same length as the Threefish state size. 253 | // 254 | func (c *Cipher) SetKey(key []uint64) { 255 | c.setKey(key) 256 | } 257 | 258 | // Some helper functions available for all Threefish* implementations 259 | func setTweak(tweak, expandedTweak []uint64) { 260 | if tweak != nil { 261 | expandedTweak[0] = tweak[0] 262 | expandedTweak[1] = tweak[1] 263 | expandedTweak[2] = tweak[0] ^ tweak[1] 264 | } 265 | } 266 | 267 | func setKey(key, expandedKey []uint64) { 268 | var i int 269 | parity := uint64(KEY_SCHEDULE_CONST) 270 | 271 | for i = 0; i < len(expandedKey)-1; i++ { 272 | expandedKey[i] = key[i] 273 | parity ^= key[i] 274 | } 275 | expandedKey[i] = parity 276 | } 277 | -------------------------------------------------------------------------------- /keccakpg/keccak_test.go: -------------------------------------------------------------------------------- 1 | package keccakpg 2 | 3 | import ( 4 | "bytes" 5 | "hash" 6 | "math/rand" 7 | "testing" 8 | ) 9 | 10 | type test struct { 11 | length int 12 | input []byte 13 | output []byte 14 | } 15 | 16 | var tests = []test{ 17 | { 18 | 28, 19 | []byte{}, 20 | []byte{ 21 | 0xf7, 0x18, 0x37, 0x50, 0x2b, 0xa8, 0xe1, 0x08, 22 | 0x37, 0xbd, 0xd8, 0xd3, 0x65, 0xad, 0xb8, 0x55, 23 | 0x91, 0x89, 0x56, 0x02, 0xfc, 0x55, 0x2b, 0x48, 24 | 0xb7, 0x39, 0x0a, 0xbd, 25 | }, 26 | }, { 27 | 28, 28 | []byte("Keccak-224 Test Hash"), 29 | []byte{ 30 | 0x30, 0x04, 0x5b, 0x34, 0x94, 0x6e, 0x1b, 0x2e, 31 | 0x09, 0x16, 0x13, 0x36, 0x2f, 0xd2, 0x2a, 0xa0, 32 | 0x8e, 0x2b, 0xea, 0xfe, 0xc5, 0xe8, 0xda, 0xee, 33 | 0x42, 0xc2, 0xe6, 0x65}, 34 | }, { 35 | 32, 36 | []byte{}, 37 | []byte{ 38 | 0xc5, 0xd2, 0x46, 0x01, 0x86, 0xf7, 0x23, 0x3c, 39 | 0x92, 0x7e, 0x7d, 0xb2, 0xdc, 0xc7, 0x03, 0xc0, 40 | 0xe5, 0x00, 0xb6, 0x53, 0xca, 0x82, 0x27, 0x3b, 41 | 0x7b, 0xfa, 0xd8, 0x04, 0x5d, 0x85, 0xa4, 0x70, 42 | }, 43 | }, { 44 | 32, 45 | []byte("Keccak-256 Test Hash"), 46 | []byte{ 47 | 0xa8, 0xd7, 0x1b, 0x07, 0xf4, 0xaf, 0x26, 0xa4, 48 | 0xff, 0x21, 0x02, 0x7f, 0x62, 0xff, 0x60, 0x26, 49 | 0x7f, 0xf9, 0x55, 0xc9, 0x63, 0xf0, 0x42, 0xc4, 50 | 0x6d, 0xa5, 0x2e, 0xe3, 0xcf, 0xaf, 0x3d, 0x3c}, 51 | }, { 52 | 48, 53 | []byte{}, 54 | []byte{ 55 | 0x2c, 0x23, 0x14, 0x6a, 0x63, 0xa2, 0x9a, 0xcf, 56 | 0x99, 0xe7, 0x3b, 0x88, 0xf8, 0xc2, 0x4e, 0xaa, 57 | 0x7d, 0xc6, 0x0a, 0xa7, 0x71, 0x78, 0x0c, 0xcc, 58 | 0x00, 0x6a, 0xfb, 0xfa, 0x8f, 0xe2, 0x47, 0x9b, 59 | 0x2d, 0xd2, 0xb2, 0x13, 0x62, 0x33, 0x74, 0x41, 60 | 0xac, 0x12, 0xb5, 0x15, 0x91, 0x19, 0x57, 0xff, 61 | }, 62 | }, { 63 | 48, 64 | []byte("Keccak-384 Test Hash"), 65 | []byte{ 66 | 0xe2, 0x13, 0xfd, 0x74, 0xaf, 0x0c, 0x5f, 0xf9, 67 | 0x1b, 0x42, 0x3c, 0x8b, 0xce, 0xec, 0xd7, 0x01, 68 | 0xf8, 0xdd, 0x64, 0xec, 0x18, 0xfd, 0x6f, 0x92, 69 | 0x60, 0xfc, 0x9e, 0xc1, 0xed, 0xbd, 0x22, 0x30, 70 | 0xa6, 0x90, 0x86, 0x65, 0xbc, 0xd9, 0xfb, 0xf4, 71 | 0x1a, 0x99, 0xa1, 0x8a, 0x7d, 0x9e, 0x44, 0x6e}, 72 | }, { 73 | 64, 74 | []byte{}, 75 | []byte{ 76 | 0x0e, 0xab, 0x42, 0xde, 0x4c, 0x3c, 0xeb, 0x92, 77 | 0x35, 0xfc, 0x91, 0xac, 0xff, 0xe7, 0x46, 0xb2, 78 | 0x9c, 0x29, 0xa8, 0xc3, 0x66, 0xb7, 0xc6, 0x0e, 79 | 0x4e, 0x67, 0xc4, 0x66, 0xf3, 0x6a, 0x43, 0x04, 80 | 0xc0, 0x0f, 0xa9, 0xca, 0xf9, 0xd8, 0x79, 0x76, 81 | 0xba, 0x46, 0x9b, 0xcb, 0xe0, 0x67, 0x13, 0xb4, 82 | 0x35, 0xf0, 0x91, 0xef, 0x27, 0x69, 0xfb, 0x16, 83 | 0x0c, 0xda, 0xb3, 0x3d, 0x36, 0x70, 0x68, 0x0e, 84 | }, 85 | }, { 86 | 64, 87 | []byte("Keccak-512 Test Hash"), 88 | []byte{ 89 | 0x96, 0xee, 0x47, 0x18, 0xdc, 0xba, 0x3c, 0x74, 90 | 0x61, 0x9b, 0xa1, 0xfa, 0x7f, 0x57, 0xdf, 0xe7, 91 | 0x76, 0x9d, 0x3f, 0x66, 0x98, 0xa8, 0xb3, 0x3f, 92 | 0xa1, 0x01, 0x83, 0x89, 0x70, 0xa1, 0x31, 0xe6, 93 | 0x21, 0xcc, 0xfd, 0x05, 0xfe, 0xff, 0xbc, 0x11, 94 | 0x80, 0xf2, 0x63, 0xc2, 0x7f, 0x1a, 0xda, 0xb4, 95 | 0x60, 0x95, 0xd6, 0xf1, 0x25, 0x33, 0x14, 0x72, 96 | 0x4b, 0x5c, 0xbf, 0x78, 0x28, 0x65, 0x8e, 0x6a, 97 | }, 98 | }, 99 | } 100 | 101 | func TestKeccak(t *testing.T) { 102 | for i := range tests { 103 | var h hash.Hash 104 | 105 | switch tests[i].length { 106 | case 28: 107 | h = New224() 108 | case 32: 109 | h = New256() 110 | case 48: 111 | h = New384() 112 | case 64: 113 | h = New512() 114 | default: 115 | panic("invalid testcase") 116 | } 117 | 118 | h.Write(tests[i].input) 119 | 120 | d := h.Sum(nil) 121 | if !bytes.Equal(d, tests[i].output) { 122 | t.Errorf("testcase %d: expected %x got %x", i, tests[i].output, d) 123 | } 124 | } 125 | } 126 | 127 | type testcase struct { 128 | msg []byte 129 | output224 []byte 130 | output256 []byte 131 | output384 []byte 132 | output512 []byte 133 | } 134 | 135 | func TestKeccakShort224(t *testing.T) { 136 | for i := range tstShort { 137 | h := New224() 138 | h.Write(tstShort[i].msg) 139 | d := h.Sum(nil) 140 | if !bytes.Equal(d, tstShort[i].output224) { 141 | t.Errorf("testcase Short224 %d: expected %x got %x", i, tstShort[i].output224, d) 142 | } 143 | } 144 | } 145 | 146 | func TestKeccakShort256(t *testing.T) { 147 | for i := range tstShort { 148 | h := New256() 149 | h.Write(tstShort[i].msg) 150 | d := h.Sum(nil) 151 | if !bytes.Equal(d, tstShort[i].output256) { 152 | t.Errorf("testcase Short256 %d: expected %x got %x", i, tstShort[i].output256, d) 153 | } 154 | } 155 | } 156 | 157 | func TestKeccakShort384(t *testing.T) { 158 | for i := range tstShort { 159 | h := New384() 160 | h.Write(tstShort[i].msg) 161 | d := h.Sum(nil) 162 | if !bytes.Equal(d, tstShort[i].output384) { 163 | t.Errorf("testcase Short384 %d: expected %x got %x", i, tstShort[i].output384, d) 164 | } 165 | } 166 | } 167 | 168 | func TestKeccakShort512(t *testing.T) { 169 | for i := range tstShort { 170 | h := New512() 171 | h.Write(tstShort[i].msg) 172 | d := h.Sum(nil) 173 | if !bytes.Equal(d, tstShort[i].output512) { 174 | t.Errorf("testcase Short512 %d: expected %x got %x", i, tstShort[i].output512, d) 175 | } 176 | } 177 | } 178 | 179 | func TestKeccakLong224(t *testing.T) { 180 | for i := range tstLong { 181 | h := New224() 182 | h.Write(tstLong[i].msg) 183 | d := h.Sum(nil) 184 | if !bytes.Equal(d, tstLong[i].output224) { 185 | t.Errorf("testcase Long224 %d: expected %x got %x", i, tstLong[i].output224, d) 186 | } 187 | } 188 | } 189 | 190 | func TestKeccakLong256(t *testing.T) { 191 | for i := range tstLong { 192 | h := New256() 193 | h.Write(tstLong[i].msg) 194 | d := h.Sum(nil) 195 | if !bytes.Equal(d, tstLong[i].output256) { 196 | t.Errorf("testcase Long256 %d: expected %x got %x", i, tstLong[i].output256, d) 197 | } 198 | } 199 | } 200 | 201 | func TestKeccakLong384(t *testing.T) { 202 | for i := range tstLong { 203 | h := New384() 204 | h.Write(tstLong[i].msg) 205 | d := h.Sum(nil) 206 | if !bytes.Equal(d, tstLong[i].output384) { 207 | t.Errorf("testcase Long384 %d: expected %x got %x", i, tstLong[i].output384, d) 208 | } 209 | } 210 | } 211 | 212 | func TestKeccakLong512(t *testing.T) { 213 | for i := range tstLong { 214 | h := New512() 215 | h.Write(tstLong[i].msg) 216 | d := h.Sum(nil) 217 | if !bytes.Equal(d, tstLong[i].output512) { 218 | t.Errorf("testcase Long512 %d: expected %x got %x", i, tstLong[i].output512, d) 219 | } 220 | } 221 | } 222 | 223 | const BUF_SIZE = 1048576 224 | 225 | var buf = func() []byte { 226 | result := make([]byte, BUF_SIZE) 227 | rand.Seed(0xDEADBEEF) 228 | for i := range result { 229 | result[i] = byte(rand.Int()) 230 | } 231 | return result 232 | }() 233 | 234 | func BenchmarkKeccak224Write1MiB(b *testing.B) { 235 | for i := 0; i < b.N; i++ { 236 | b.StopTimer() 237 | h := New224() 238 | b.StartTimer() 239 | h.Write(buf) 240 | } 241 | } 242 | 243 | func BenchmarkKeccak224Sum(b *testing.B) { 244 | b.StopTimer() 245 | h := New224() 246 | h.Write(buf) 247 | b.StartTimer() 248 | for i := 0; i < b.N; i++ { 249 | b.StopTimer() 250 | h0 := h 251 | b.StartTimer() 252 | h0.Sum(nil) 253 | } 254 | } 255 | 256 | func BenchmarkKeccak224Real(b *testing.B) { 257 | b.StopTimer() 258 | b.SetBytes(int64(b.N*8)) 259 | bs := make([]byte, 8, 8) 260 | h := New224() 261 | b.StartTimer() 262 | for i := 0; i < b.N; i++ { 263 | h.Reset() 264 | bs[0], bs[1], bs[2], bs[3], bs[4], bs[5], bs[6], bs[7] = byte(i), byte(i>>8), byte(i>>16), byte(i>>24), byte(i>>32), byte(i>>40), byte(i>>48), byte(i>>56) 265 | h.Write(bs) 266 | h.Sum(nil) 267 | } 268 | } 269 | 270 | func BenchmarkKeccak256Write1MiB(b *testing.B) { 271 | for i := 0; i < b.N; i++ { 272 | b.StopTimer() 273 | h := New224() 274 | b.StartTimer() 275 | h.Write(buf) 276 | } 277 | } 278 | 279 | func BenchmarkKeccak256Sum(b *testing.B) { 280 | b.StopTimer() 281 | h := New256() 282 | h.Write(buf) 283 | b.StartTimer() 284 | for i := 0; i < b.N; i++ { 285 | b.StopTimer() 286 | h1 := h 287 | b.StartTimer() 288 | h1.Sum(nil) 289 | } 290 | } 291 | 292 | func BenchmarkKeccak384Write1MiB(b *testing.B) { 293 | for i := 0; i < b.N; i++ { 294 | b.StopTimer() 295 | h := New384() 296 | b.StartTimer() 297 | h.Write(buf) 298 | } 299 | } 300 | 301 | func BenchmarkKeccak384Sum(b *testing.B) { 302 | b.StopTimer() 303 | h := New384() 304 | h.Write(buf) 305 | b.StartTimer() 306 | for i := 0; i < b.N; i++ { 307 | b.StopTimer() 308 | h0 := h 309 | b.StartTimer() 310 | h0.Sum(nil) 311 | } 312 | } 313 | 314 | func BenchmarkKeccak512Write1MiB(b *testing.B) { 315 | for i := 0; i < b.N; i++ { 316 | b.StopTimer() 317 | h := New512() 318 | b.StartTimer() 319 | h.Write(buf) 320 | } 321 | } 322 | 323 | func BenchmarkKeccak512Sum(b *testing.B) { 324 | b.StopTimer() 325 | h := New512() 326 | h.Write(buf) 327 | b.StartTimer() 328 | for i := 0; i < b.N; i++ { 329 | b.StopTimer() 330 | h0 := h 331 | b.StartTimer() 332 | h0.Sum(nil) 333 | } 334 | } 335 | 336 | -------------------------------------------------------------------------------- /keccak/keccak_test.go: -------------------------------------------------------------------------------- 1 | package keccak 2 | // borrowed from https://github.com/ebfe/keccak 3 | 4 | import ( 5 | "bytes" 6 | "hash" 7 | "math/rand" 8 | "testing" 9 | ) 10 | 11 | type test struct { 12 | length int 13 | input []byte 14 | output []byte 15 | } 16 | 17 | var tests = []test{ 18 | { 19 | 28, 20 | []byte{}, 21 | []byte{ 22 | 0xf7, 0x18, 0x37, 0x50, 0x2b, 0xa8, 0xe1, 0x08, 23 | 0x37, 0xbd, 0xd8, 0xd3, 0x65, 0xad, 0xb8, 0x55, 24 | 0x91, 0x89, 0x56, 0x02, 0xfc, 0x55, 0x2b, 0x48, 25 | 0xb7, 0x39, 0x0a, 0xbd, 26 | }, 27 | }, { 28 | 28, 29 | []byte("Keccak-224 Test Hash"), 30 | []byte{ 31 | 0x30, 0x04, 0x5b, 0x34, 0x94, 0x6e, 0x1b, 0x2e, 32 | 0x09, 0x16, 0x13, 0x36, 0x2f, 0xd2, 0x2a, 0xa0, 33 | 0x8e, 0x2b, 0xea, 0xfe, 0xc5, 0xe8, 0xda, 0xee, 34 | 0x42, 0xc2, 0xe6, 0x65}, 35 | }, { 36 | 32, 37 | []byte{}, 38 | []byte{ 39 | 0xc5, 0xd2, 0x46, 0x01, 0x86, 0xf7, 0x23, 0x3c, 40 | 0x92, 0x7e, 0x7d, 0xb2, 0xdc, 0xc7, 0x03, 0xc0, 41 | 0xe5, 0x00, 0xb6, 0x53, 0xca, 0x82, 0x27, 0x3b, 42 | 0x7b, 0xfa, 0xd8, 0x04, 0x5d, 0x85, 0xa4, 0x70, 43 | }, 44 | }, { 45 | 32, 46 | []byte("Keccak-256 Test Hash"), 47 | []byte{ 48 | 0xa8, 0xd7, 0x1b, 0x07, 0xf4, 0xaf, 0x26, 0xa4, 49 | 0xff, 0x21, 0x02, 0x7f, 0x62, 0xff, 0x60, 0x26, 50 | 0x7f, 0xf9, 0x55, 0xc9, 0x63, 0xf0, 0x42, 0xc4, 51 | 0x6d, 0xa5, 0x2e, 0xe3, 0xcf, 0xaf, 0x3d, 0x3c}, 52 | }, { 53 | 48, 54 | []byte{}, 55 | []byte{ 56 | 0x2c, 0x23, 0x14, 0x6a, 0x63, 0xa2, 0x9a, 0xcf, 57 | 0x99, 0xe7, 0x3b, 0x88, 0xf8, 0xc2, 0x4e, 0xaa, 58 | 0x7d, 0xc6, 0x0a, 0xa7, 0x71, 0x78, 0x0c, 0xcc, 59 | 0x00, 0x6a, 0xfb, 0xfa, 0x8f, 0xe2, 0x47, 0x9b, 60 | 0x2d, 0xd2, 0xb2, 0x13, 0x62, 0x33, 0x74, 0x41, 61 | 0xac, 0x12, 0xb5, 0x15, 0x91, 0x19, 0x57, 0xff, 62 | }, 63 | }, { 64 | 48, 65 | []byte("Keccak-384 Test Hash"), 66 | []byte{ 67 | 0xe2, 0x13, 0xfd, 0x74, 0xaf, 0x0c, 0x5f, 0xf9, 68 | 0x1b, 0x42, 0x3c, 0x8b, 0xce, 0xec, 0xd7, 0x01, 69 | 0xf8, 0xdd, 0x64, 0xec, 0x18, 0xfd, 0x6f, 0x92, 70 | 0x60, 0xfc, 0x9e, 0xc1, 0xed, 0xbd, 0x22, 0x30, 71 | 0xa6, 0x90, 0x86, 0x65, 0xbc, 0xd9, 0xfb, 0xf4, 72 | 0x1a, 0x99, 0xa1, 0x8a, 0x7d, 0x9e, 0x44, 0x6e}, 73 | }, { 74 | 64, 75 | []byte{}, 76 | []byte{ 77 | 0x0e, 0xab, 0x42, 0xde, 0x4c, 0x3c, 0xeb, 0x92, 78 | 0x35, 0xfc, 0x91, 0xac, 0xff, 0xe7, 0x46, 0xb2, 79 | 0x9c, 0x29, 0xa8, 0xc3, 0x66, 0xb7, 0xc6, 0x0e, 80 | 0x4e, 0x67, 0xc4, 0x66, 0xf3, 0x6a, 0x43, 0x04, 81 | 0xc0, 0x0f, 0xa9, 0xca, 0xf9, 0xd8, 0x79, 0x76, 82 | 0xba, 0x46, 0x9b, 0xcb, 0xe0, 0x67, 0x13, 0xb4, 83 | 0x35, 0xf0, 0x91, 0xef, 0x27, 0x69, 0xfb, 0x16, 84 | 0x0c, 0xda, 0xb3, 0x3d, 0x36, 0x70, 0x68, 0x0e, 85 | }, 86 | }, { 87 | 64, 88 | []byte("Keccak-512 Test Hash"), 89 | []byte{ 90 | 0x96, 0xee, 0x47, 0x18, 0xdc, 0xba, 0x3c, 0x74, 91 | 0x61, 0x9b, 0xa1, 0xfa, 0x7f, 0x57, 0xdf, 0xe7, 92 | 0x76, 0x9d, 0x3f, 0x66, 0x98, 0xa8, 0xb3, 0x3f, 93 | 0xa1, 0x01, 0x83, 0x89, 0x70, 0xa1, 0x31, 0xe6, 94 | 0x21, 0xcc, 0xfd, 0x05, 0xfe, 0xff, 0xbc, 0x11, 95 | 0x80, 0xf2, 0x63, 0xc2, 0x7f, 0x1a, 0xda, 0xb4, 96 | 0x60, 0x95, 0xd6, 0xf1, 0x25, 0x33, 0x14, 0x72, 97 | 0x4b, 0x5c, 0xbf, 0x78, 0x28, 0x65, 0x8e, 0x6a, 98 | }, 99 | }, 100 | } 101 | 102 | func TestKeccak(t *testing.T) { 103 | for i := range tests { 104 | var h hash.Hash 105 | 106 | switch tests[i].length { 107 | case 28: 108 | h = New224() 109 | case 32: 110 | h = New256() 111 | case 48: 112 | h = New384() 113 | case 64: 114 | h = New512() 115 | default: 116 | panic("invalid testcase") 117 | } 118 | 119 | h.Write(tests[i].input) 120 | 121 | d := h.Sum(nil) 122 | if !bytes.Equal(d, tests[i].output) { 123 | t.Errorf("testcase %d: expected %x got %x", i, tests[i].output, d) 124 | } 125 | } 126 | } 127 | 128 | type testcase struct { 129 | msg []byte 130 | output224 []byte 131 | output256 []byte 132 | output384 []byte 133 | output512 []byte 134 | } 135 | 136 | func TestKeccakShort224(t *testing.T) { 137 | for i := range tstShort { 138 | h := New224() 139 | h.Write(tstShort[i].msg) 140 | d := h.Sum(nil) 141 | if !bytes.Equal(d, tstShort[i].output224) { 142 | t.Errorf("testcase Short224 %d: expected %x got %x", i, tstShort[i].output224, d) 143 | } 144 | } 145 | } 146 | 147 | func TestKeccakShort256(t *testing.T) { 148 | for i := range tstShort { 149 | h := New256() 150 | h.Write(tstShort[i].msg) 151 | d := h.Sum(nil) 152 | if !bytes.Equal(d, tstShort[i].output256) { 153 | t.Errorf("testcase Short256 %d: expected %x got %x", i, tstShort[i].output256, d) 154 | } 155 | } 156 | } 157 | 158 | func TestKeccakShort384(t *testing.T) { 159 | for i := range tstShort { 160 | h := New384() 161 | h.Write(tstShort[i].msg) 162 | d := h.Sum(nil) 163 | if !bytes.Equal(d, tstShort[i].output384) { 164 | t.Errorf("testcase Short384 %d: expected %x got %x", i, tstShort[i].output384, d) 165 | } 166 | } 167 | } 168 | 169 | func TestKeccakShort512(t *testing.T) { 170 | for i := range tstShort { 171 | h := New512() 172 | h.Write(tstShort[i].msg) 173 | d := h.Sum(nil) 174 | if !bytes.Equal(d, tstShort[i].output512) { 175 | t.Errorf("testcase Short512 %d: expected %x got %x", i, tstShort[i].output512, d) 176 | } 177 | } 178 | } 179 | 180 | func TestKeccakLong224(t *testing.T) { 181 | for i := range tstLong { 182 | h := New224() 183 | h.Write(tstLong[i].msg) 184 | d := h.Sum(nil) 185 | if !bytes.Equal(d, tstLong[i].output224) { 186 | t.Errorf("testcase Long224 %d: expected %x got %x", i, tstLong[i].output224, d) 187 | } 188 | } 189 | } 190 | 191 | func TestKeccakLong256(t *testing.T) { 192 | for i := range tstLong { 193 | h := New256() 194 | h.Write(tstLong[i].msg) 195 | d := h.Sum(nil) 196 | if !bytes.Equal(d, tstLong[i].output256) { 197 | t.Errorf("testcase Long256 %d: expected %x got %x", i, tstLong[i].output256, d) 198 | } 199 | } 200 | } 201 | 202 | func TestKeccakLong384(t *testing.T) { 203 | for i := range tstLong { 204 | h := New384() 205 | h.Write(tstLong[i].msg) 206 | d := h.Sum(nil) 207 | if !bytes.Equal(d, tstLong[i].output384) { 208 | t.Errorf("testcase Long384 %d: expected %x got %x", i, tstLong[i].output384, d) 209 | } 210 | } 211 | } 212 | 213 | func TestKeccakLong512(t *testing.T) { 214 | for i := range tstLong { 215 | h := New512() 216 | h.Write(tstLong[i].msg) 217 | d := h.Sum(nil) 218 | if !bytes.Equal(d, tstLong[i].output512) { 219 | t.Errorf("testcase Long512 %d: expected %x got %x", i, tstLong[i].output512, d) 220 | } 221 | } 222 | } 223 | 224 | const BUF_SIZE = 1048576 225 | 226 | var buf = func() []byte { 227 | result := make([]byte, BUF_SIZE) 228 | rand.Seed(0xDEADBEEF) 229 | for i := range result { 230 | result[i] = byte(rand.Int()) 231 | } 232 | return result 233 | }() 234 | 235 | func BenchmarkKeccak224Write1MiB(b *testing.B) { 236 | for i := 0; i < b.N; i++ { 237 | b.StopTimer() 238 | h := New224() 239 | b.StartTimer() 240 | h.Write(buf) 241 | } 242 | } 243 | 244 | func BenchmarkKeccak224Sum(b *testing.B) { 245 | b.StopTimer() 246 | h := New224() 247 | h.Write(buf) 248 | b.StartTimer() 249 | for i := 0; i < b.N; i++ { 250 | b.StopTimer() 251 | h0 := h 252 | b.StartTimer() 253 | h0.Sum(nil) 254 | } 255 | } 256 | 257 | func BenchmarkKeccak256Write1MiB(b *testing.B) { 258 | for i := 0; i < b.N; i++ { 259 | b.StopTimer() 260 | h := New224() 261 | b.StartTimer() 262 | h.Write(buf) 263 | } 264 | } 265 | 266 | func BenchmarkKeccak256Sum(b *testing.B) { 267 | b.StopTimer() 268 | h := New256() 269 | h.Write(buf) 270 | b.StartTimer() 271 | for i := 0; i < b.N; i++ { 272 | b.StopTimer() 273 | h1 := h 274 | b.StartTimer() 275 | h1.Sum(nil) 276 | } 277 | } 278 | 279 | func BenchmarkKeccak224Real(b *testing.B) { 280 | b.StopTimer() 281 | b.SetBytes(int64(b.N*8)) 282 | bs := make([]byte, 8, 8) 283 | h := New224() 284 | b.StartTimer() 285 | for i := 0; i < b.N; i++ { 286 | h.Reset() 287 | bs[0], bs[1], bs[2], bs[3], bs[4], bs[5], bs[6], bs[7] = byte(i), byte(i>>8), byte(i>>16), byte(i>>24), byte(i>>32), byte(i>>40), byte(i>>48), byte(i>>56) 288 | h.Write(bs) 289 | h.Sum(nil) 290 | } 291 | } 292 | 293 | func BenchmarkKeccak384Write1MiB(b *testing.B) { 294 | for i := 0; i < b.N; i++ { 295 | b.StopTimer() 296 | h := New384() 297 | b.StartTimer() 298 | h.Write(buf) 299 | } 300 | } 301 | 302 | func BenchmarkKeccak384Sum(b *testing.B) { 303 | b.StopTimer() 304 | h := New384() 305 | h.Write(buf) 306 | b.StartTimer() 307 | for i := 0; i < b.N; i++ { 308 | b.StopTimer() 309 | h0 := h 310 | b.StartTimer() 311 | h0.Sum(nil) 312 | } 313 | } 314 | 315 | func BenchmarkKeccak512Write1MiB(b *testing.B) { 316 | for i := 0; i < b.N; i++ { 317 | b.StopTimer() 318 | h := New512() 319 | b.StartTimer() 320 | h.Write(buf) 321 | } 322 | } 323 | 324 | func BenchmarkKeccak512Sum(b *testing.B) { 325 | b.StopTimer() 326 | h := New512() 327 | h.Write(buf) 328 | b.StartTimer() 329 | for i := 0; i < b.N; i++ { 330 | b.StopTimer() 331 | h0 := h 332 | b.StartTimer() 333 | h0.Sum(nil) 334 | } 335 | } 336 | -------------------------------------------------------------------------------- /hashtable/hashtable.go: -------------------------------------------------------------------------------- 1 | // Copyright © 2014,2015 Lawrence E. Bakst. All rights reserved. 2 | 3 | package hashtable 4 | 5 | import ( 6 | "fmt" 7 | "time" 8 | 9 | "leb.io/cuckoo/primes" 10 | "leb.io/hashland/hashf" 11 | "leb.io/hrff" 12 | ) 13 | 14 | type Bucket struct { 15 | Key []byte 16 | } 17 | 18 | type Stats struct { 19 | Inserts int // number of elements inserted 20 | Cols int // number of collisions 21 | Probes int // number of probes 22 | Heads int // number of chains > 1 23 | Dups int // number of dup hashes on the same chain 24 | Dups2 int // number of dup hashes 25 | Nbuckets int // number of new buckets added 26 | Entries int 27 | LongestChain int // longest chain of entries 28 | Q float64 29 | Dur time.Duration 30 | // 31 | Lines int 32 | Size uint64 33 | SizeLog2 uint64 34 | SizeMask uint64 35 | } 36 | 37 | type TBS struct { 38 | t int 39 | b int 40 | s int 41 | } 42 | 43 | type HashTable struct { 44 | Buckets [][]Bucket 45 | Stats 46 | tbs []TBS 47 | Seed uint64 48 | Tcnt int // trace counter 49 | extra int 50 | pd bool 51 | oa bool 52 | prime bool 53 | } 54 | 55 | var Trace bool 56 | 57 | // Henry Warren, "Hacker's Delight", ch. 5.3 58 | func NextLog2(x uint32) uint32 { 59 | if x <= 1 { 60 | return x 61 | } 62 | x-- 63 | n := uint32(0) 64 | y := uint32(0) 65 | y = x >> 16 66 | if y != 0 { 67 | n += 16 68 | x = y 69 | } 70 | y = x >> 8 71 | if y != 0 { 72 | n += 8 73 | x = y 74 | } 75 | y = x >> 4 76 | if y != 0 { 77 | n += 4 78 | x = y 79 | } 80 | y = x >> 2 81 | if y != 0 { 82 | n += 2 83 | x = y 84 | } 85 | y = x >> 1 86 | if y != 0 { 87 | return n + 2 88 | } 89 | return n + x 90 | } 91 | 92 | func NewHashTable(size int, seed int64, extra int, pd, oa, prime bool) *HashTable { 93 | ht := new(HashTable) 94 | ht.Lines = size 95 | ht.extra = extra 96 | if size < 0 { 97 | ht.Size = uint64(-size) 98 | } else { 99 | ht.SizeLog2 = uint64(NextLog2(uint32(ht.Lines)) + uint32(extra)) 100 | ht.Size = 1 << ht.SizeLog2 101 | } 102 | ht.prime = prime 103 | if prime { 104 | ht.Size = uint64(primes.NextPrime(int(ht.Size))) 105 | } 106 | ht.Seed = uint64(seed) 107 | ht.pd = pd 108 | ht.oa = oa 109 | ht.SizeMask = ht.Size - 1 110 | ht.Buckets = make([][]Bucket, ht.Size, ht.Size) 111 | 112 | //ht.Nbuckets = int(ht.Size) 113 | return ht 114 | } 115 | 116 | func btoi(b []byte) int { 117 | return int(b[3])<<24 | int(b[2])<<16 | int(b[1])<<8 | int(b[0]) 118 | } 119 | 120 | var ph uint64 121 | 122 | var Ones = [16]int{0, 1, 1, 2, 1, 2, 2, 3, 1, 2, 2, 3, 2, 3, 3, 4} 123 | var Zeros = [16]int{4, 3, 3, 2, 3, 2, 2, 1, 3, 2, 2, 1, 2, 1, 1, 0} 124 | 125 | func diff(d uint64) (zeros int, ones int) { 126 | for i := 0; i < 16; i++ { 127 | four := d & 0xF 128 | zeros += Zeros[four] 129 | ones += Ones[four] 130 | d = d >> 4 131 | } 132 | if zeros+ones != 64 { 133 | panic("diff") 134 | } 135 | return 136 | } 137 | 138 | func (ht *HashTable) Insert(ka []byte) { 139 | k := make([]byte, len(ka), len(ka)) 140 | k = k[:] 141 | amt := copy(k, ka) 142 | if amt != len(ka) { 143 | panic("Add") 144 | } 145 | ht.Inserts++ 146 | idx := uint64(0) 147 | h := hashf.Hashf(k, ht.Seed) // jenkins.Hash232(k, 0) 148 | if ht.prime { 149 | idx = h % ht.Size 150 | //fmt.Printf("idx=%d\n", idx) 151 | } else { 152 | idx = h & ht.SizeMask 153 | } 154 | //fmt.Printf("k=%d, idx=%d, ht.Size=%d, h=%#016x\n", btoi(k), idx, ht.Size, h) 155 | cnt := 0 156 | pass := 0 157 | 158 | //fmt.Printf("Add: %x\n", k) 159 | //ht.Buckets[idx].Key = k 160 | //len(ht.Buckets[idx].Key) == 0 161 | for { 162 | if ht.Buckets[idx] == nil { 163 | // no entry or chain at this location, make it 164 | ht.Buckets[idx] = append(ht.Buckets[idx], Bucket{Key: k}) 165 | //fmt.Printf("Insert: ins idx=%d, len=%d, hash=%#016x, key=%q\n", idx, len(ht.Buckets[idx]), h, ht.Buckets[idx][0].Key) 166 | //z, o := diff(h) 167 | //fmt.Printf("%02d %02d %#064b z=%02d o=%02d", btoi(k), idx, h, z, o) 168 | if Trace { 169 | fmt.Printf("{%q: %d, %q: %d, %q: %q, %q: %d, %q: %d, %q: %d, %q: %v, %q: %v},\n", 170 | "i", ht.Tcnt, "l", cnt, "op", "I", "t", 0, "b", idx, "s", 0, "k", btoi(k), "v", btoi(k)) 171 | ht.Tcnt++ 172 | //fmt.Printf("len(ht.tbs)=%d\n", ht.tbs) 173 | /* 174 | for _, _ := range ht.tbs { 175 | fmt.Printf("{%q: %d, %q: %d, %q: %q, %q: %d, %q: %d, %q: %d, %q: %v, %q: %v},\n", 176 | "i", ht.Tcnt, "l", cnt, "op", "U", "t", tbs.t, "b", tbs.b, "s", tbs.s, "k", btoi(k), "v", btoi(k)) 177 | ht.Tcnt++ 178 | } 179 | */ 180 | ht.tbs = nil 181 | } 182 | ht.Probes++ 183 | ht.Heads++ 184 | break 185 | } 186 | if ht.oa { 187 | //fmt.Printf("Insert: OA col idx=%d, len=%d, hash=0x%08x, key=%q\n", idx, len(ht.Buckets[idx]), h, ht.Buckets[idx][0].Key) 188 | if cnt == 0 { 189 | ht.Probes++ 190 | } else { 191 | ht.Cols++ 192 | } 193 | if Trace { 194 | /* 195 | ht.tbs = append(ht.tbs, TBS{0, int(idx), 0}) 196 | */ 197 | fmt.Printf("{%q: %d, %q: %d, %q: %q, %q: %d, %q: %d, %q: %d, %q: %v, %q: %v},\n", 198 | "i", ht.Tcnt, "l", cnt, "op", "P", "t", 0, "b", idx, "s", 0, "k", btoi(k), "v", btoi(k)) 199 | ht.Tcnt++ 200 | } 201 | // check for a duplicate key 202 | bh := hashf.Hashf(ht.Buckets[idx][0].Key, ht.Seed) 203 | if bh == h { 204 | if ht.pd { 205 | fmt.Printf("hash=0x%08x, idx=%d, key=%q\n", h, idx, k) 206 | fmt.Printf("hash=0x%08x, idx=%d, key=%q\n", bh, idx, ht.Buckets[idx][0].Key) 207 | } 208 | ht.Dups++ 209 | } 210 | idx++ 211 | cnt++ 212 | if idx > ht.Size-1 { 213 | pass++ 214 | if pass > 1 { 215 | panic("Add: pass") 216 | } 217 | idx = 0 218 | } 219 | } else { 220 | // first scan slice for dups 221 | for j := range ht.Buckets[idx] { 222 | bh := hashf.Hashf(ht.Buckets[idx][j].Key, ht.Seed) 223 | //fmt.Printf("idx=%d, j=%d/%d, bh=%#016x, h=%#016x, key=%q\n", idx, j, len(ht.Buckets[idx]), bh, h, ht.Buckets[idx][j].Key) 224 | if bh == h { 225 | if ht.pd { 226 | //fmt.Printf("idx=%d, j=%d/%d, bh=0x%08x, h=0x%08x, key=%q, bkey=%q\n", idx, j, len(ht.Buckets[idx]), bh, h, k, ht.Buckets[idx][j].Key) 227 | //fmt.Printf("hash=0x%08x, idx=%d, key=%q\n", h, idx, k) 228 | //fmt.Printf("hash=0x%08x, idx=%d, key=%q\n", bh, idx, ht.Buckets[idx][0].Key) 229 | } 230 | ht.Dups++ 231 | } 232 | } 233 | // add element 234 | ht.Buckets[idx] = append(ht.Buckets[idx], Bucket{Key: k}) 235 | if len(ht.Buckets[idx]) > ht.LongestChain { 236 | //fmt.Printf("len(ht.Buckets[idx])=%d, ht.LongestChain=%d\n", len(ht.Buckets[idx]), ht.LongestChain) 237 | ht.LongestChain = len(ht.Buckets[idx]) 238 | } 239 | //z, o := diff(h) 240 | //fmt.Printf("%02d %02d %#064b z=%02d o=%02d", btoi(k), idx, h, z, o) 241 | if Trace { 242 | fmt.Printf("{%q: %d, %q: %d, %q: %q, %q: %d, %q: %d, %q: %d, %q: %v, %q: %v},\n", 243 | "i", ht.Tcnt, "l", cnt, "op", "I", "t", len(ht.Buckets[idx])-1, "b", idx, "s", 0, "k", btoi(k), "v", btoi(k)) 244 | ht.Tcnt++ 245 | } 246 | ht.Nbuckets++ 247 | ht.Probes++ 248 | break 249 | } 250 | } 251 | if ph != 0 { 252 | //xor := h ^ ph 253 | //z, o := diff(xor) 254 | //fmt.Printf(" xor=%#064b z=%02d o=%02d\n", xor, z, o) 255 | } else { 256 | //fmt.Printf("\n") 257 | } 258 | ph = h 259 | } 260 | 261 | // The theoretical metric from "Red Dragon Book" 262 | // appears to be useless 263 | func (ht *HashTable) HashQuality() float64 { 264 | if ht.Inserts == 0 { 265 | return 0.0 266 | } 267 | n := float64(0.0) 268 | buckets := 0 269 | entries := 0 270 | for _, v := range ht.Buckets { 271 | if v != nil { 272 | buckets++ 273 | count := float64(len(v)) 274 | entries += len(v) 275 | n += count * (count + 1.0) 276 | } 277 | } 278 | n *= float64(ht.Size) 279 | d := float64(ht.Inserts) * (float64(ht.Inserts) + 2.0*float64(ht.Size) - 1.0) // (n / 2m) * (n + 2m - 1) 280 | //fmt.Printf("buckets=%d, entries=%d, inserts=%d, size=%d, n=%f, d=%f, n/d=%f\n", buckets, entries, ht.Inserts, ht.Size, n, d, n/d) 281 | //ht.Nbuckets = buckets 282 | //ht.Entries = entries 283 | ht.Q = n / d 284 | return n / d 285 | } 286 | 287 | func (s *HashTable) Print() { 288 | var cvt = func(t float64) (ret float64, unit string) { 289 | unit = "s" 290 | if t < 1.0 { 291 | unit = "ms" 292 | t *= 1000.0 293 | if t < 1.0 { 294 | unit = "us" 295 | t *= 1000.0 296 | } 297 | } 298 | ret = t 299 | return 300 | } 301 | 302 | q := s.HashQuality() 303 | t, units := cvt(s.Dur.Seconds()) 304 | if s.oa { 305 | /* 306 | if test.name != "TestI" && test.name != "TestJ" && (s.Lines != s.Inserts || s.Lines != s.Heads || s.Lines != s.Nbuckets || s.Lines != s.Entries) { 307 | panic("runTestsWithFileAndHashes") 308 | } 309 | */ 310 | fmt.Printf("size=%h, inserts=%04.2h, probes=%04.2h, cols=%04.2h, cpi=%0.2f%%, ppi=%04.2f, dups=%d, time=%0.2f%s\n", 311 | hrff.Int64{int64(s.Size), ""}, hrff.Float64{float64(s.Inserts), ""}, hrff.Float64{float64(s.Probes), ""}, hrff.Float64{float64(s.Cols), ""}, 312 | float64(s.Cols)/float64(s.Inserts)*100.0, float64(s.Probes)/float64(s.Inserts), s.Dups, t, units) 313 | } else { 314 | /* 315 | if test.name != "TestI" && test.name != "TestJ" && (s.Lines != s.Inserts || s.Lines != s.Probes || s.Lines != s.Entries) { 316 | fmt.Printf("lines=%d, inserts=%d, probes=%d, entries=%d\n", s.Lines, s.Inserts, s.Probes, s.Entries) 317 | panic("runTestsWithFileAndHashes") 318 | } 319 | */ 320 | //fmt.Printf("%#v\n", s) 321 | fmt.Printf("size=%h, inserts=%h, heads=%h, newBuckets=%h, LongestChain=%h, dups=%d, dups2=%d, q=%0.2f, time=%0.2f%s\n", 322 | hrff.Int64{int64(s.Size), ""}, hrff.Int64{int64(s.Inserts), ""}, hrff.Int64{int64(s.Heads), ""}, 323 | hrff.Int64{int64(s.Nbuckets), ""}, hrff.Int64{int64(s.LongestChain), ""}, s.Dups, s.Dups2, q, t, units) 324 | } 325 | } 326 | -------------------------------------------------------------------------------- /siphash/siphash.go: -------------------------------------------------------------------------------- 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 | package siphash 11 | 12 | import "hash" 13 | 14 | const ( 15 | // The block size of hash algorithm in bytes. 16 | BlockSize = 8 17 | 18 | // The size of hash output in bytes. 19 | Size = 8 20 | 21 | // The size of 128-bit hash output in bytes. 22 | Size128 = 16 23 | ) 24 | 25 | type digest struct { 26 | v0, v1, v2, v3 uint64 // state 27 | k0, k1 uint64 // two parts of key 28 | t uint8 // message bytes counter (mod 256) 29 | nx int // number of bytes in buffer x 30 | x [8]byte // buffer for unprocessed bytes 31 | size int // output size in bytes (8 or 16) 32 | } 33 | 34 | // newDigest returns a new digest with the given output size in bytes (must be 8 or 16). 35 | func newDigest(size int, key []byte) *digest { 36 | if size != Size && size != Size128 { 37 | panic("size must be 8 or 16") 38 | } 39 | d := new(digest) 40 | d.k0 = uint64(key[0]) | uint64(key[1])<<8 | uint64(key[2])<<16 | uint64(key[3])<<24 | 41 | uint64(key[4])<<32 | uint64(key[5])<<40 | uint64(key[6])<<48 | uint64(key[7])<<56 42 | d.k1 = uint64(key[8]) | uint64(key[9])<<8 | uint64(key[10])<<16 | uint64(key[11])<<24 | 43 | uint64(key[12])<<32 | uint64(key[13])<<40 | uint64(key[14])<<48 | uint64(key[15])<<56 44 | d.size = size 45 | d.Reset() 46 | return d 47 | } 48 | 49 | // New returns a new hash.Hash64 computing SipHash-2-4 with 16-byte key and 8-byte output. 50 | func New(key []byte) hash.Hash64 { 51 | return newDigest(Size, key) 52 | } 53 | 54 | // New128 returns a new hash.Hash computing SipHash-2-4 with 16-byte key and 16-byte output. 55 | // 56 | // Note that 16-byte output is considered experimental by SipHash authors at this time. 57 | func New128(key []byte) hash.Hash { 58 | return newDigest(Size128, key) 59 | } 60 | 61 | func (d *digest) Reset() { 62 | d.v0 = d.k0 ^ 0x736f6d6570736575 63 | d.v1 = d.k1 ^ 0x646f72616e646f6d 64 | d.v2 = d.k0 ^ 0x6c7967656e657261 65 | d.v3 = d.k1 ^ 0x7465646279746573 66 | d.t = 0 67 | d.nx = 0 68 | if d.size == Size128 { 69 | d.v1 ^= 0xee 70 | } 71 | } 72 | 73 | func (d *digest) Size() int { return d.size } 74 | 75 | func (d *digest) BlockSize() int { return BlockSize } 76 | 77 | func blocks(d *digest, p []uint8) { 78 | v0, v1, v2, v3 := d.v0, d.v1, d.v2, d.v3 79 | 80 | for len(p) >= BlockSize { 81 | m := uint64(p[0]) | uint64(p[1])<<8 | uint64(p[2])<<16 | uint64(p[3])<<24 | 82 | uint64(p[4])<<32 | uint64(p[5])<<40 | uint64(p[6])<<48 | uint64(p[7])<<56 83 | 84 | v3 ^= m 85 | 86 | // Round 1. 87 | v0 += v1 88 | v1 = v1<<13 | v1>>(64-13) 89 | v1 ^= v0 90 | v0 = v0<<32 | v0>>(64-32) 91 | 92 | v2 += v3 93 | v3 = v3<<16 | v3>>(64-16) 94 | v3 ^= v2 95 | 96 | v0 += v3 97 | v3 = v3<<21 | v3>>(64-21) 98 | v3 ^= v0 99 | 100 | v2 += v1 101 | v1 = v1<<17 | v1>>(64-17) 102 | v1 ^= v2 103 | v2 = v2<<32 | v2>>(64-32) 104 | 105 | // Round 2. 106 | v0 += v1 107 | v1 = v1<<13 | v1>>(64-13) 108 | v1 ^= v0 109 | v0 = v0<<32 | v0>>(64-32) 110 | 111 | v2 += v3 112 | v3 = v3<<16 | v3>>(64-16) 113 | v3 ^= v2 114 | 115 | v0 += v3 116 | v3 = v3<<21 | v3>>(64-21) 117 | v3 ^= v0 118 | 119 | v2 += v1 120 | v1 = v1<<17 | v1>>(64-17) 121 | v1 ^= v2 122 | v2 = v2<<32 | v2>>(64-32) 123 | 124 | v0 ^= m 125 | 126 | p = p[BlockSize:] 127 | } 128 | 129 | d.v0, d.v1, d.v2, d.v3 = v0, v1, v2, v3 130 | } 131 | 132 | func (d *digest) Write(p []byte) (nn int, err error) { 133 | nn = len(p) 134 | d.t += uint8(nn) 135 | if d.nx > 0 { 136 | n := len(p) 137 | if n > BlockSize-d.nx { 138 | n = BlockSize - d.nx 139 | } 140 | d.nx += copy(d.x[d.nx:], p) 141 | if d.nx == BlockSize { 142 | blocks(d, d.x[:]) 143 | d.nx = 0 144 | } 145 | p = p[n:] 146 | } 147 | if len(p) >= BlockSize { 148 | n := len(p) &^ (BlockSize - 1) 149 | blocks(d, p[:n]) 150 | p = p[n:] 151 | } 152 | if len(p) > 0 { 153 | d.nx = copy(d.x[:], p) 154 | } 155 | return 156 | } 157 | 158 | func (d0 *digest) Sum64() uint64 { 159 | // Make a copy of d0 so that caller can keep writing and summing. 160 | d := *d0 161 | 162 | for i := d.nx; i < BlockSize-1; i++ { 163 | d.x[i] = 0 164 | } 165 | d.x[7] = d.t 166 | blocks(&d, d.x[:]) 167 | 168 | v0, v1, v2, v3 := d.v0, d.v1, d.v2, d.v3 169 | v2 ^= 0xff 170 | 171 | // Round 1. 172 | v0 += v1 173 | v1 = v1<<13 | v1>>(64-13) 174 | v1 ^= v0 175 | v0 = v0<<32 | v0>>(64-32) 176 | 177 | v2 += v3 178 | v3 = v3<<16 | v3>>(64-16) 179 | v3 ^= v2 180 | 181 | v0 += v3 182 | v3 = v3<<21 | v3>>(64-21) 183 | v3 ^= v0 184 | 185 | v2 += v1 186 | v1 = v1<<17 | v1>>(64-17) 187 | v1 ^= v2 188 | v2 = v2<<32 | v2>>(64-32) 189 | 190 | // Round 2. 191 | v0 += v1 192 | v1 = v1<<13 | v1>>(64-13) 193 | v1 ^= v0 194 | v0 = v0<<32 | v0>>(64-32) 195 | 196 | v2 += v3 197 | v3 = v3<<16 | v3>>(64-16) 198 | v3 ^= v2 199 | 200 | v0 += v3 201 | v3 = v3<<21 | v3>>(64-21) 202 | v3 ^= v0 203 | 204 | v2 += v1 205 | v1 = v1<<17 | v1>>(64-17) 206 | v1 ^= v2 207 | v2 = v2<<32 | v2>>(64-32) 208 | 209 | // Round 3. 210 | v0 += v1 211 | v1 = v1<<13 | v1>>(64-13) 212 | v1 ^= v0 213 | v0 = v0<<32 | v0>>(64-32) 214 | 215 | v2 += v3 216 | v3 = v3<<16 | v3>>(64-16) 217 | v3 ^= v2 218 | 219 | v0 += v3 220 | v3 = v3<<21 | v3>>(64-21) 221 | v3 ^= v0 222 | 223 | v2 += v1 224 | v1 = v1<<17 | v1>>(64-17) 225 | v1 ^= v2 226 | v2 = v2<<32 | v2>>(64-32) 227 | 228 | // Round 4. 229 | v0 += v1 230 | v1 = v1<<13 | v1>>(64-13) 231 | v1 ^= v0 232 | v0 = v0<<32 | v0>>(64-32) 233 | 234 | v2 += v3 235 | v3 = v3<<16 | v3>>(64-16) 236 | v3 ^= v2 237 | 238 | v0 += v3 239 | v3 = v3<<21 | v3>>(64-21) 240 | v3 ^= v0 241 | 242 | v2 += v1 243 | v1 = v1<<17 | v1>>(64-17) 244 | v1 ^= v2 245 | v2 = v2<<32 | v2>>(64-32) 246 | 247 | return v0 ^ v1 ^ v2 ^ v3 248 | } 249 | 250 | func (d0 *digest) sum128() (r0, r1 uint64) { 251 | // Make a copy of d0 so that caller can keep writing and summing. 252 | d := *d0 253 | 254 | for i := d.nx; i < BlockSize-1; i++ { 255 | d.x[i] = 0 256 | } 257 | d.x[7] = d.t 258 | blocks(&d, d.x[:]) 259 | 260 | v0, v1, v2, v3 := d.v0, d.v1, d.v2, d.v3 261 | v2 ^= 0xee 262 | 263 | // Round 1. 264 | v0 += v1 265 | v1 = v1<<13 | v1>>(64-13) 266 | v1 ^= v0 267 | v0 = v0<<32 | v0>>(64-32) 268 | 269 | v2 += v3 270 | v3 = v3<<16 | v3>>(64-16) 271 | v3 ^= v2 272 | 273 | v0 += v3 274 | v3 = v3<<21 | v3>>(64-21) 275 | v3 ^= v0 276 | 277 | v2 += v1 278 | v1 = v1<<17 | v1>>(64-17) 279 | v1 ^= v2 280 | v2 = v2<<32 | v2>>(64-32) 281 | 282 | // Round 2. 283 | v0 += v1 284 | v1 = v1<<13 | v1>>(64-13) 285 | v1 ^= v0 286 | v0 = v0<<32 | v0>>(64-32) 287 | 288 | v2 += v3 289 | v3 = v3<<16 | v3>>(64-16) 290 | v3 ^= v2 291 | 292 | v0 += v3 293 | v3 = v3<<21 | v3>>(64-21) 294 | v3 ^= v0 295 | 296 | v2 += v1 297 | v1 = v1<<17 | v1>>(64-17) 298 | v1 ^= v2 299 | v2 = v2<<32 | v2>>(64-32) 300 | 301 | // Round 3. 302 | v0 += v1 303 | v1 = v1<<13 | v1>>(64-13) 304 | v1 ^= v0 305 | v0 = v0<<32 | v0>>(64-32) 306 | 307 | v2 += v3 308 | v3 = v3<<16 | v3>>(64-16) 309 | v3 ^= v2 310 | 311 | v0 += v3 312 | v3 = v3<<21 | v3>>(64-21) 313 | v3 ^= v0 314 | 315 | v2 += v1 316 | v1 = v1<<17 | v1>>(64-17) 317 | v1 ^= v2 318 | v2 = v2<<32 | v2>>(64-32) 319 | 320 | // Round 4. 321 | v0 += v1 322 | v1 = v1<<13 | v1>>(64-13) 323 | v1 ^= v0 324 | v0 = v0<<32 | v0>>(64-32) 325 | 326 | v2 += v3 327 | v3 = v3<<16 | v3>>(64-16) 328 | v3 ^= v2 329 | 330 | v0 += v3 331 | v3 = v3<<21 | v3>>(64-21) 332 | v3 ^= v0 333 | 334 | v2 += v1 335 | v1 = v1<<17 | v1>>(64-17) 336 | v1 ^= v2 337 | v2 = v2<<32 | v2>>(64-32) 338 | 339 | r0 = v0 ^ v1 ^ v2 ^ v3 340 | 341 | v1 ^= 0xdd 342 | 343 | // Round 1. 344 | v0 += v1 345 | v1 = v1<<13 | v1>>(64-13) 346 | v1 ^= v0 347 | v0 = v0<<32 | v0>>(64-32) 348 | 349 | v2 += v3 350 | v3 = v3<<16 | v3>>(64-16) 351 | v3 ^= v2 352 | 353 | v0 += v3 354 | v3 = v3<<21 | v3>>(64-21) 355 | v3 ^= v0 356 | 357 | v2 += v1 358 | v1 = v1<<17 | v1>>(64-17) 359 | v1 ^= v2 360 | v2 = v2<<32 | v2>>(64-32) 361 | 362 | // Round 2. 363 | v0 += v1 364 | v1 = v1<<13 | v1>>(64-13) 365 | v1 ^= v0 366 | v0 = v0<<32 | v0>>(64-32) 367 | 368 | v2 += v3 369 | v3 = v3<<16 | v3>>(64-16) 370 | v3 ^= v2 371 | 372 | v0 += v3 373 | v3 = v3<<21 | v3>>(64-21) 374 | v3 ^= v0 375 | 376 | v2 += v1 377 | v1 = v1<<17 | v1>>(64-17) 378 | v1 ^= v2 379 | v2 = v2<<32 | v2>>(64-32) 380 | 381 | // Round 3. 382 | v0 += v1 383 | v1 = v1<<13 | v1>>(64-13) 384 | v1 ^= v0 385 | v0 = v0<<32 | v0>>(64-32) 386 | 387 | v2 += v3 388 | v3 = v3<<16 | v3>>(64-16) 389 | v3 ^= v2 390 | 391 | v0 += v3 392 | v3 = v3<<21 | v3>>(64-21) 393 | v3 ^= v0 394 | 395 | v2 += v1 396 | v1 = v1<<17 | v1>>(64-17) 397 | v1 ^= v2 398 | v2 = v2<<32 | v2>>(64-32) 399 | 400 | // Round 4. 401 | v0 += v1 402 | v1 = v1<<13 | v1>>(64-13) 403 | v1 ^= v0 404 | v0 = v0<<32 | v0>>(64-32) 405 | 406 | v2 += v3 407 | v3 = v3<<16 | v3>>(64-16) 408 | v3 ^= v2 409 | 410 | v0 += v3 411 | v3 = v3<<21 | v3>>(64-21) 412 | v3 ^= v0 413 | 414 | v2 += v1 415 | v1 = v1<<17 | v1>>(64-17) 416 | v1 ^= v2 417 | v2 = v2<<32 | v2>>(64-32) 418 | 419 | r1 = v0 ^ v1 ^ v2 ^ v3 420 | 421 | return r0, r1 422 | } 423 | 424 | func (d *digest) Sum(in []byte) []byte { 425 | if d.size == Size { 426 | r := d.Sum64() 427 | in = append(in, 428 | byte(r), 429 | byte(r>>8), 430 | byte(r>>16), 431 | byte(r>>24), 432 | byte(r>>32), 433 | byte(r>>40), 434 | byte(r>>48), 435 | byte(r>>56)) 436 | } else { 437 | r0, r1 := d.sum128() 438 | in = append(in, 439 | byte(r0), 440 | byte(r0>>8), 441 | byte(r0>>16), 442 | byte(r0>>24), 443 | byte(r0>>32), 444 | byte(r0>>40), 445 | byte(r0>>48), 446 | byte(r0>>56), 447 | byte(r1), 448 | byte(r1>>8), 449 | byte(r1>>16), 450 | byte(r1>>24), 451 | byte(r1>>32), 452 | byte(r1>>40), 453 | byte(r1>>48), 454 | byte(r1>>56)) 455 | } 456 | return in 457 | } 458 | -------------------------------------------------------------------------------- /keccak/KeccakSponge.c: -------------------------------------------------------------------------------- 1 | /* 2 | The Keccak sponge function, designed by Guido Bertoni, Joan Daemen, 3 | Michaël Peeters and Gilles Van Assche. For more information, feedback or 4 | questions, please refer to our website: http://keccak.noekeon.org/ 5 | 6 | Implementation by the designers, 7 | hereby denoted as "the implementer". 8 | 9 | To the extent possible under law, the implementer has waived all copyright 10 | and related or neighboring rights to the source code in this file. 11 | http://creativecommons.org/publicdomain/zero/1.0/ 12 | */ 13 | 14 | #include 15 | #include "KeccakSponge.h" 16 | #include "KeccakF-1600-interface.h" 17 | #ifdef KeccakReference 18 | #include "displayIntermediateValues.h" 19 | #endif 20 | 21 | int InitSponge(spongeState *state, unsigned int rate, unsigned int capacity) 22 | { 23 | if (rate+capacity != 1600) 24 | return 1; 25 | if ((rate <= 0) || (rate >= 1600) || ((rate % 64) != 0)) 26 | return 1; 27 | KeccakInitialize(); 28 | state->rate = rate; 29 | state->capacity = capacity; 30 | state->fixedOutputLength = 0; 31 | KeccakInitializeState(state->state); 32 | memset(state->dataQueue, 0, KeccakMaximumRateInBytes); 33 | state->bitsInQueue = 0; 34 | state->squeezing = 0; 35 | state->bitsAvailableForSqueezing = 0; 36 | 37 | return 0; 38 | } 39 | 40 | void AbsorbQueue(spongeState *state) 41 | { 42 | // state->bitsInQueue is assumed to be equal to state->rate 43 | #ifdef KeccakReference 44 | displayBytes(1, "Block to be absorbed", state->dataQueue, state->rate/8); 45 | #endif 46 | #ifdef ProvideFast576 47 | if (state->rate == 576) 48 | KeccakAbsorb576bits(state->state, state->dataQueue); 49 | else 50 | #endif 51 | #ifdef ProvideFast832 52 | if (state->rate == 832) 53 | KeccakAbsorb832bits(state->state, state->dataQueue); 54 | else 55 | #endif 56 | #ifdef ProvideFast1024 57 | if (state->rate == 1024) 58 | KeccakAbsorb1024bits(state->state, state->dataQueue); 59 | else 60 | #endif 61 | #ifdef ProvideFast1088 62 | if (state->rate == 1088) 63 | KeccakAbsorb1088bits(state->state, state->dataQueue); 64 | else 65 | #endif 66 | #ifdef ProvideFast1152 67 | if (state->rate == 1152) 68 | KeccakAbsorb1152bits(state->state, state->dataQueue); 69 | else 70 | #endif 71 | #ifdef ProvideFast1344 72 | if (state->rate == 1344) 73 | KeccakAbsorb1344bits(state->state, state->dataQueue); 74 | else 75 | #endif 76 | KeccakAbsorb(state->state, state->dataQueue, state->rate/64); 77 | state->bitsInQueue = 0; 78 | } 79 | 80 | int Absorb(spongeState *state, const unsigned char *data, unsigned long long databitlen) 81 | { 82 | unsigned long long i, j, wholeBlocks; 83 | unsigned int partialBlock, partialByte; 84 | const unsigned char *curData; 85 | 86 | if ((state->bitsInQueue % 8) != 0) 87 | return 1; // Only the last call may contain a partial byte 88 | if (state->squeezing) 89 | return 1; // Too late for additional input 90 | 91 | i = 0; 92 | while(i < databitlen) { 93 | if ((state->bitsInQueue == 0) && (databitlen >= state->rate) && (i <= (databitlen-state->rate))) { 94 | wholeBlocks = (databitlen-i)/state->rate; 95 | curData = data+i/8; 96 | #ifdef ProvideFast576 97 | if (state->rate == 576) { 98 | for(j=0; jrate/8); 101 | #endif 102 | KeccakAbsorb576bits(state->state, curData); 103 | } 104 | } 105 | else 106 | #endif 107 | #ifdef ProvideFast832 108 | if (state->rate == 832) { 109 | for(j=0; jrate/8); 112 | #endif 113 | KeccakAbsorb832bits(state->state, curData); 114 | } 115 | } 116 | else 117 | #endif 118 | #ifdef ProvideFast1024 119 | if (state->rate == 1024) { 120 | for(j=0; jrate/8); 123 | #endif 124 | KeccakAbsorb1024bits(state->state, curData); 125 | } 126 | } 127 | else 128 | #endif 129 | #ifdef ProvideFast1088 130 | if (state->rate == 1088) { 131 | for(j=0; jrate/8); 134 | #endif 135 | KeccakAbsorb1088bits(state->state, curData); 136 | } 137 | } 138 | else 139 | #endif 140 | #ifdef ProvideFast1152 141 | if (state->rate == 1152) { 142 | for(j=0; jrate/8); 145 | #endif 146 | KeccakAbsorb1152bits(state->state, curData); 147 | } 148 | } 149 | else 150 | #endif 151 | #ifdef ProvideFast1344 152 | if (state->rate == 1344) { 153 | for(j=0; jrate/8); 156 | #endif 157 | KeccakAbsorb1344bits(state->state, curData); 158 | } 159 | } 160 | else 161 | #endif 162 | { 163 | for(j=0; jrate/8) { 164 | #ifdef KeccakReference 165 | displayBytes(1, "Block to be absorbed", curData, state->rate/8); 166 | #endif 167 | KeccakAbsorb(state->state, curData, state->rate/64); 168 | } 169 | } 170 | i += wholeBlocks*state->rate; 171 | } 172 | else { 173 | partialBlock = (unsigned int)(databitlen - i); 174 | if (partialBlock+state->bitsInQueue > state->rate) 175 | partialBlock = state->rate-state->bitsInQueue; 176 | partialByte = partialBlock % 8; 177 | partialBlock -= partialByte; 178 | memcpy(state->dataQueue+state->bitsInQueue/8, data+i/8, partialBlock/8); 179 | state->bitsInQueue += partialBlock; 180 | i += partialBlock; 181 | if (state->bitsInQueue == state->rate) 182 | AbsorbQueue(state); 183 | if (partialByte > 0) { 184 | unsigned char mask = (1 << partialByte)-1; 185 | state->dataQueue[state->bitsInQueue/8] = data[i/8] & mask; 186 | state->bitsInQueue += partialByte; 187 | i += partialByte; 188 | } 189 | } 190 | } 191 | return 0; 192 | } 193 | 194 | void PadAndSwitchToSqueezingPhase(spongeState *state) 195 | { 196 | // Note: the bits are numbered from 0=LSB to 7=MSB 197 | if (state->bitsInQueue + 1 == state->rate) { 198 | state->dataQueue[state->bitsInQueue/8 ] |= 1 << (state->bitsInQueue % 8); 199 | AbsorbQueue(state); 200 | memset(state->dataQueue, 0, state->rate/8); 201 | } 202 | else { 203 | memset(state->dataQueue + (state->bitsInQueue+7)/8, 0, state->rate/8 - (state->bitsInQueue+7)/8); 204 | state->dataQueue[state->bitsInQueue/8 ] |= 1 << (state->bitsInQueue % 8); 205 | } 206 | state->dataQueue[(state->rate-1)/8] |= 1 << ((state->rate-1) % 8); 207 | AbsorbQueue(state); 208 | 209 | #ifdef KeccakReference 210 | displayText(1, "--- Switching to squeezing phase ---"); 211 | #endif 212 | #ifdef ProvideFast1024 213 | if (state->rate == 1024) { 214 | KeccakExtract1024bits(state->state, state->dataQueue); 215 | state->bitsAvailableForSqueezing = 1024; 216 | } 217 | else 218 | #endif 219 | { 220 | KeccakExtract(state->state, state->dataQueue, state->rate/64); 221 | state->bitsAvailableForSqueezing = state->rate; 222 | } 223 | #ifdef KeccakReference 224 | displayBytes(1, "Block available for squeezing", state->dataQueue, state->bitsAvailableForSqueezing/8); 225 | #endif 226 | state->squeezing = 1; 227 | } 228 | 229 | int Squeeze(spongeState *state, unsigned char *output, unsigned long long outputLength) 230 | { 231 | unsigned long long i; 232 | unsigned int partialBlock; 233 | 234 | if (!state->squeezing) 235 | PadAndSwitchToSqueezingPhase(state); 236 | if ((outputLength % 8) != 0) 237 | return 1; // Only multiple of 8 bits are allowed, truncation can be done at user level 238 | 239 | i = 0; 240 | while(i < outputLength) { 241 | if (state->bitsAvailableForSqueezing == 0) { 242 | KeccakPermutation(state->state); 243 | #ifdef ProvideFast1024 244 | if (state->rate == 1024) { 245 | KeccakExtract1024bits(state->state, state->dataQueue); 246 | state->bitsAvailableForSqueezing = 1024; 247 | } 248 | else 249 | #endif 250 | { 251 | KeccakExtract(state->state, state->dataQueue, state->rate/64); 252 | state->bitsAvailableForSqueezing = state->rate; 253 | } 254 | #ifdef KeccakReference 255 | displayBytes(1, "Block available for squeezing", state->dataQueue, state->bitsAvailableForSqueezing/8); 256 | #endif 257 | } 258 | partialBlock = state->bitsAvailableForSqueezing; 259 | if ((unsigned long long)partialBlock > outputLength - i) 260 | partialBlock = (unsigned int)(outputLength - i); 261 | memcpy(output+i/8, state->dataQueue+(state->rate-state->bitsAvailableForSqueezing)/8, partialBlock/8); 262 | state->bitsAvailableForSqueezing -= partialBlock; 263 | i += partialBlock; 264 | } 265 | return 0; 266 | } 267 | --------------------------------------------------------------------------------