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

     1  // +build !arm,!amd64 appengine gccgo
     2  
     3  package siphash
     4  
     5  func once(d *digest) {
     6  	blocks(d, d.x[:])
     7  }
     8  
     9  func finalize(d *digest) uint64 {
    10  	d0 := *d
    11  	once(&d0)
    12  
    13  	v0, v1, v2, v3 := d0.v0, d0.v1, d0.v2, d0.v3
    14  	v2 ^= 0xff
    15  
    16  	// Round 1.
    17  	v0 += v1
    18  	v1 = v1<<13 | v1>>(64-13)
    19  	v1 ^= v0
    20  	v0 = v0<<32 | v0>>(64-32)
    21  
    22  	v2 += v3
    23  	v3 = v3<<16 | v3>>(64-16)
    24  	v3 ^= v2
    25  
    26  	v0 += v3
    27  	v3 = v3<<21 | v3>>(64-21)
    28  	v3 ^= v0
    29  
    30  	v2 += v1
    31  	v1 = v1<<17 | v1>>(64-17)
    32  	v1 ^= v2
    33  	v2 = v2<<32 | v2>>(64-32)
    34  
    35  	// Round 2.
    36  	v0 += v1
    37  	v1 = v1<<13 | v1>>(64-13)
    38  	v1 ^= v0
    39  	v0 = v0<<32 | v0>>(64-32)
    40  
    41  	v2 += v3
    42  	v3 = v3<<16 | v3>>(64-16)
    43  	v3 ^= v2
    44  
    45  	v0 += v3
    46  	v3 = v3<<21 | v3>>(64-21)
    47  	v3 ^= v0
    48  
    49  	v2 += v1
    50  	v1 = v1<<17 | v1>>(64-17)
    51  	v1 ^= v2
    52  	v2 = v2<<32 | v2>>(64-32)
    53  
    54  	// Round 3.
    55  	v0 += v1
    56  	v1 = v1<<13 | v1>>(64-13)
    57  	v1 ^= v0
    58  	v0 = v0<<32 | v0>>(64-32)
    59  
    60  	v2 += v3
    61  	v3 = v3<<16 | v3>>(64-16)
    62  	v3 ^= v2
    63  
    64  	v0 += v3
    65  	v3 = v3<<21 | v3>>(64-21)
    66  	v3 ^= v0
    67  
    68  	v2 += v1
    69  	v1 = v1<<17 | v1>>(64-17)
    70  	v1 ^= v2
    71  	v2 = v2<<32 | v2>>(64-32)
    72  
    73  	// Round 4.
    74  	v0 += v1
    75  	v1 = v1<<13 | v1>>(64-13)
    76  	v1 ^= v0
    77  	v0 = v0<<32 | v0>>(64-32)
    78  
    79  	v2 += v3
    80  	v3 = v3<<16 | v3>>(64-16)
    81  	v3 ^= v2
    82  
    83  	v0 += v3
    84  	v3 = v3<<21 | v3>>(64-21)
    85  	v3 ^= v0
    86  
    87  	v2 += v1
    88  	v1 = v1<<17 | v1>>(64-17)
    89  	v1 ^= v2
    90  	v2 = v2<<32 | v2>>(64-32)
    91  
    92  	return v0 ^ v1 ^ v2 ^ v3
    93  }
    94  
    95  func blocks(d *digest, p []uint8) {
    96  	v0, v1, v2, v3 := d.v0, d.v1, d.v2, d.v3
    97  
    98  	for len(p) >= BlockSize {
    99  		m := uint64(p[0]) | uint64(p[1])<<8 | uint64(p[2])<<16 | uint64(p[3])<<24 |
   100  			uint64(p[4])<<32 | uint64(p[5])<<40 | uint64(p[6])<<48 | uint64(p[7])<<56
   101  
   102  		v3 ^= m
   103  
   104  		// Round 1.
   105  		v0 += v1
   106  		v1 = v1<<13 | v1>>(64-13)
   107  		v1 ^= v0
   108  		v0 = v0<<32 | v0>>(64-32)
   109  
   110  		v2 += v3
   111  		v3 = v3<<16 | v3>>(64-16)
   112  		v3 ^= v2
   113  
   114  		v0 += v3
   115  		v3 = v3<<21 | v3>>(64-21)
   116  		v3 ^= v0
   117  
   118  		v2 += v1
   119  		v1 = v1<<17 | v1>>(64-17)
   120  		v1 ^= v2
   121  		v2 = v2<<32 | v2>>(64-32)
   122  
   123  		// Round 2.
   124  		v0 += v1
   125  		v1 = v1<<13 | v1>>(64-13)
   126  		v1 ^= v0
   127  		v0 = v0<<32 | v0>>(64-32)
   128  
   129  		v2 += v3
   130  		v3 = v3<<16 | v3>>(64-16)
   131  		v3 ^= v2
   132  
   133  		v0 += v3
   134  		v3 = v3<<21 | v3>>(64-21)
   135  		v3 ^= v0
   136  
   137  		v2 += v1
   138  		v1 = v1<<17 | v1>>(64-17)
   139  		v1 ^= v2
   140  		v2 = v2<<32 | v2>>(64-32)
   141  
   142  		v0 ^= m
   143  
   144  		p = p[BlockSize:]
   145  	}
   146  
   147  	d.v0, d.v1, d.v2, d.v3 = v0, v1, v2, v3
   148  }