github.com/piotrnar/gocoin@v0.0.0-20240512203912-faa0448c5e96/lib/others/siphash/hash128.go (about)

     1  // +build !arm,!amd64 appengine gccgo
     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  }