github.com/andy2046/gopie@v0.7.0/pkg/bloom/siphash.go (about)

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