github.com/deroproject/derosuite@v2.1.6-1.0.20200307070847-0f2e589c7a2b+incompatible/cryptonight/jhash.go (about)

     1  // Copyright 2017-2018 DERO Project. All rights reserved.
     2  // Use of this source code in any form is governed by RESEARCH license.
     3  // license can be found in the LICENSE file.
     4  // GPG: 0F39 E425 8C65 3947 702A  8234 08B2 0360 A03A 9DE8
     5  //
     6  //
     7  // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY
     8  // EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
     9  // MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL
    10  // THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
    11  // SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
    12  // PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
    13  // INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
    14  // STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF
    15  // THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
    16  
    17  package cryptonight
    18  
    19  import "fmt"
    20  import "gitlab.com/nitya-sattva/go-x11/hash"
    21  
    22  // HashSize holds the size of a hash in bytes.
    23  const HashSize = int(32)
    24  
    25  // BlockSize holds the size of a block in bytes.
    26  const BlockSize = uintptr(64)
    27  
    28  ////////////////
    29  
    30  type digest struct {
    31  	ptr uintptr
    32  	cnt uintptr
    33  	h   [16]uint64
    34  	b   [BlockSize]byte
    35  }
    36  
    37  // New returns a new digest compute a JH256 hash.
    38  func NewJhash256() hash.Digest {
    39  	ref := &digest{}
    40  	ref.Reset()
    41  	return ref
    42  }
    43  
    44  ////////////////
    45  
    46  // Reset resets the digest to its initial state.
    47  func (ref *digest) Reset() {
    48  	ref.ptr = 0
    49  	ref.cnt = 0
    50  	copy(ref.h[:], kInit[:])
    51  }
    52  
    53  // Sum appends the current hash to dst and returns the result
    54  // as a slice. It does not change the underlying hash state.
    55  func (ref *digest) Sum(dst []byte) []byte {
    56  	dgt := *ref
    57  	hsh := [64]byte{}
    58  	dgt.Close(hsh[:], 0, 0)
    59  	return append(dst, hsh[32:]...)
    60  }
    61  
    62  // Write more data to the running hash, never returns an error.
    63  func (ref *digest) Write(src []byte) (int, error) {
    64  	sln := uintptr(len(src))
    65  	fln := len(src)
    66  	buf := ref.b[:]
    67  	ptr := ref.ptr
    68  
    69  	if sln < (BlockSize - ptr) {
    70  		copy(buf[ptr:], src)
    71  		ref.ptr += sln
    72  		return int(sln), nil
    73  	}
    74  
    75  	var hi, lo [8]uint64
    76  	hi[0] = ref.h[0x0]
    77  	lo[0] = ref.h[0x1]
    78  	hi[1] = ref.h[0x2]
    79  	lo[1] = ref.h[0x3]
    80  	hi[2] = ref.h[0x4]
    81  	lo[2] = ref.h[0x5]
    82  	hi[3] = ref.h[0x6]
    83  	lo[3] = ref.h[0x7]
    84  	hi[4] = ref.h[0x8]
    85  	lo[4] = ref.h[0x9]
    86  	hi[5] = ref.h[0xA]
    87  	lo[5] = ref.h[0xB]
    88  	hi[6] = ref.h[0xC]
    89  	lo[6] = ref.h[0xD]
    90  	hi[7] = ref.h[0xE]
    91  	lo[7] = ref.h[0xF]
    92  
    93  	for sln > 0 {
    94  		cln := BlockSize - ptr
    95  
    96  		if cln > sln {
    97  			cln = sln
    98  		}
    99  		sln -= cln
   100  
   101  		copy(ref.b[ptr:], src[:cln])
   102  		src = src[cln:]
   103  		ptr += cln
   104  
   105  		if ptr == BlockSize {
   106  			m0h := decUInt64le(buf[0:])
   107  			m0l := decUInt64le(buf[8:])
   108  			m1h := decUInt64le(buf[16:])
   109  			m1l := decUInt64le(buf[24:])
   110  			m2h := decUInt64le(buf[32:])
   111  			m2l := decUInt64le(buf[40:])
   112  			m3h := decUInt64le(buf[48:])
   113  			m3l := decUInt64le(buf[56:])
   114  
   115  			hi[0] ^= m0h
   116  			lo[0] ^= m0l
   117  			hi[1] ^= m1h
   118  			lo[1] ^= m1l
   119  			hi[2] ^= m2h
   120  			lo[2] ^= m2l
   121  			hi[3] ^= m3h
   122  			lo[3] ^= m3l
   123  
   124  			for r := uint64(0); r < 42; r += 7 {
   125  				slMutateExtend(r+0, 0, hi[:], lo[:])
   126  				slMutateExtend(r+1, 1, hi[:], lo[:])
   127  				slMutateExtend(r+2, 2, hi[:], lo[:])
   128  				slMutateExtend(r+3, 3, hi[:], lo[:])
   129  				slMutateExtend(r+4, 4, hi[:], lo[:])
   130  				slMutateExtend(r+5, 5, hi[:], lo[:])
   131  				slMutateBasic(r+6, hi[:], lo[:])
   132  			}
   133  
   134  			hi[4] ^= m0h
   135  			lo[4] ^= m0l
   136  			hi[5] ^= m1h
   137  			lo[5] ^= m1l
   138  			hi[6] ^= m2h
   139  			lo[6] ^= m2l
   140  			hi[7] ^= m3h
   141  			lo[7] ^= m3l
   142  
   143  			ref.cnt++
   144  			ptr = 0
   145  		}
   146  	}
   147  
   148  	ref.h[0x0] = hi[0]
   149  	ref.h[0x1] = lo[0]
   150  	ref.h[0x2] = hi[1]
   151  	ref.h[0x3] = lo[1]
   152  	ref.h[0x4] = hi[2]
   153  	ref.h[0x5] = lo[2]
   154  	ref.h[0x6] = hi[3]
   155  	ref.h[0x7] = lo[3]
   156  	ref.h[0x8] = hi[4]
   157  	ref.h[0x9] = lo[4]
   158  	ref.h[0xA] = hi[5]
   159  	ref.h[0xB] = lo[5]
   160  	ref.h[0xC] = hi[6]
   161  	ref.h[0xD] = lo[6]
   162  	ref.h[0xE] = hi[7]
   163  	ref.h[0xF] = lo[7]
   164  
   165  	ref.ptr = ptr
   166  	return fln, nil
   167  }
   168  
   169  // Close the digest by writing the last bits and storing the hash
   170  // in dst. This prepares the digest for reuse by calling reset. A call
   171  // to Close with a dst that is smaller then HashSize will return an error.
   172  func (ref *digest) Close(dst []byte, bits uint8, bcnt uint8) error {
   173  	if ln := len(dst); HashSize > ln {
   174  		return fmt.Errorf("JHash Close: dst min length: %d, got %d", HashSize, ln)
   175  	}
   176  
   177  	var ocnt uintptr
   178  	var buf [128]uint8
   179  
   180  	{
   181  		off := uint8(0x80) >> bcnt
   182  		buf[0] = uint8((bits & -off) | off)
   183  	}
   184  
   185  	if ref.ptr == 0 && bcnt == 0 {
   186  		ocnt = 47
   187  	} else {
   188  		ocnt = 111 - ref.ptr
   189  	}
   190  
   191  	l0 := uint64(bcnt)
   192  	l0 += uint64(ref.cnt << 9)
   193  	l0 += uint64(ref.ptr << 3)
   194  	l1 := uint64(ref.cnt >> 55)
   195  
   196  	encUInt64be(buf[ocnt+1:], l1)
   197  	encUInt64be(buf[ocnt+9:], l0)
   198  
   199  	ref.Write(buf[:ocnt+17])
   200  
   201  	for u := uintptr(0); u < 8; u++ {
   202  		encUInt64le(dst[(u<<3):], ref.h[u+8])
   203  	}
   204  
   205  	ref.Reset()
   206  	return nil
   207  }
   208  
   209  // Size returns the number of bytes required to store the hash.
   210  func (*digest) Size() int {
   211  	return HashSize
   212  }
   213  
   214  // BlockSize returns the block size of the hash.
   215  func (*digest) BlockSize() int {
   216  	return int(BlockSize)
   217  }
   218  
   219  ////////////////
   220  
   221  func decUInt64le(src []byte) uint64 {
   222  	return (uint64(src[0]) |
   223  		uint64(src[1])<<8 |
   224  		uint64(src[2])<<16 |
   225  		uint64(src[3])<<24 |
   226  		uint64(src[4])<<32 |
   227  		uint64(src[5])<<40 |
   228  		uint64(src[6])<<48 |
   229  		uint64(src[7])<<56)
   230  }
   231  
   232  func encUInt64le(dst []byte, src uint64) {
   233  	dst[0] = uint8(src)
   234  	dst[1] = uint8(src >> 8)
   235  	dst[2] = uint8(src >> 16)
   236  	dst[3] = uint8(src >> 24)
   237  	dst[4] = uint8(src >> 32)
   238  	dst[5] = uint8(src >> 40)
   239  	dst[6] = uint8(src >> 48)
   240  	dst[7] = uint8(src >> 56)
   241  }
   242  
   243  func encUInt64be(dst []byte, src uint64) {
   244  	dst[0] = uint8(src >> 56)
   245  	dst[1] = uint8(src >> 48)
   246  	dst[2] = uint8(src >> 40)
   247  	dst[3] = uint8(src >> 32)
   248  	dst[4] = uint8(src >> 24)
   249  	dst[5] = uint8(src >> 16)
   250  	dst[6] = uint8(src >> 8)
   251  	dst[7] = uint8(src)
   252  }
   253  
   254  func slMutateBasic(r uint64, hi, lo []uint64) {
   255  	var tmp uint64
   256  
   257  	tmp = kSpec[(r<<2)+0]
   258  	hi[6] = ^hi[6]
   259  	hi[0] ^= tmp & ^hi[4]
   260  	tmp = tmp ^ (hi[0] & hi[2])
   261  	hi[0] ^= hi[4] & hi[6]
   262  	hi[6] ^= ^hi[2] & hi[4]
   263  	hi[2] ^= hi[0] & hi[4]
   264  	hi[4] ^= hi[0] & ^hi[6]
   265  	hi[0] ^= hi[2] | hi[6]
   266  	hi[6] ^= hi[2] & hi[4]
   267  	hi[2] ^= tmp & hi[0]
   268  	hi[4] ^= tmp
   269  
   270  	tmp = kSpec[(r<<2)+1]
   271  	lo[6] = ^lo[6]
   272  	lo[0] ^= tmp & ^lo[4]
   273  	tmp = tmp ^ (lo[0] & lo[2])
   274  	lo[0] ^= lo[4] & lo[6]
   275  	lo[6] ^= ^lo[2] & lo[4]
   276  	lo[2] ^= lo[0] & lo[4]
   277  	lo[4] ^= lo[0] & ^lo[6]
   278  	lo[0] ^= lo[2] | lo[6]
   279  	lo[6] ^= lo[2] & lo[4]
   280  	lo[2] ^= tmp & lo[0]
   281  	lo[4] ^= tmp
   282  
   283  	tmp = kSpec[(r<<2)+2]
   284  	hi[7] = ^hi[7]
   285  	hi[1] ^= tmp & ^hi[5]
   286  	tmp = tmp ^ (hi[1] & hi[3])
   287  	hi[1] ^= hi[5] & hi[7]
   288  	hi[7] ^= ^hi[3] & hi[5]
   289  	hi[3] ^= hi[1] & hi[5]
   290  	hi[5] ^= hi[1] & ^hi[7]
   291  	hi[1] ^= hi[3] | hi[7]
   292  	hi[7] ^= hi[3] & hi[5]
   293  	hi[3] ^= tmp & hi[1]
   294  	hi[5] ^= tmp
   295  
   296  	tmp = kSpec[(r<<2)+3]
   297  	lo[7] = ^lo[7]
   298  	lo[1] ^= tmp & ^lo[5]
   299  	tmp = tmp ^ (lo[1] & lo[3])
   300  	lo[1] ^= lo[5] & lo[7]
   301  	lo[7] ^= ^lo[3] & lo[5]
   302  	lo[3] ^= lo[1] & lo[5]
   303  	lo[5] ^= lo[1] & ^lo[7]
   304  	lo[1] ^= lo[3] | lo[7]
   305  	lo[7] ^= lo[3] & lo[5]
   306  	lo[3] ^= tmp & lo[1]
   307  	lo[5] ^= tmp
   308  
   309  	hi[1] ^= hi[2]
   310  	hi[3] ^= hi[4]
   311  	hi[5] ^= hi[6] ^ hi[0]
   312  	hi[7] ^= hi[0]
   313  	hi[0] ^= hi[3]
   314  	hi[2] ^= hi[5]
   315  	hi[4] ^= hi[7] ^ hi[1]
   316  	hi[6] ^= hi[1]
   317  
   318  	lo[1] ^= lo[2]
   319  	lo[3] ^= lo[4]
   320  	lo[5] ^= lo[6] ^ lo[0]
   321  	lo[7] ^= lo[0]
   322  	lo[0] ^= lo[3]
   323  	lo[2] ^= lo[5]
   324  	lo[4] ^= lo[7] ^ lo[1]
   325  	lo[6] ^= lo[1]
   326  
   327  	tmp = hi[1]
   328  	hi[1] = lo[1]
   329  	lo[1] = tmp
   330  
   331  	tmp = hi[3]
   332  	hi[3] = lo[3]
   333  	lo[3] = tmp
   334  
   335  	tmp = hi[5]
   336  	hi[5] = lo[5]
   337  	lo[5] = tmp
   338  
   339  	tmp = hi[7]
   340  	hi[7] = lo[7]
   341  	lo[7] = tmp
   342  }
   343  
   344  func slMutateExtend(r, ro uint64, hi, lo []uint64) {
   345  	var tmp uint64
   346  
   347  	tmp = kSpec[(r<<2)+0]
   348  	hi[6] = ^hi[6]
   349  	hi[0] ^= tmp & ^hi[4]
   350  	tmp = tmp ^ (hi[0] & hi[2])
   351  	hi[0] ^= hi[4] & hi[6]
   352  	hi[6] ^= ^hi[2] & hi[4]
   353  	hi[2] ^= hi[0] & hi[4]
   354  	hi[4] ^= hi[0] & ^hi[6]
   355  	hi[0] ^= hi[2] | hi[6]
   356  	hi[6] ^= hi[2] & hi[4]
   357  	hi[2] ^= tmp & hi[0]
   358  	hi[4] ^= tmp
   359  
   360  	tmp = kSpec[(r<<2)+1]
   361  	lo[6] = ^lo[6]
   362  	lo[0] ^= tmp & ^lo[4]
   363  	tmp = tmp ^ (lo[0] & lo[2])
   364  	lo[0] ^= lo[4] & lo[6]
   365  	lo[6] ^= ^lo[2] & lo[4]
   366  	lo[2] ^= lo[0] & lo[4]
   367  	lo[4] ^= lo[0] & ^lo[6]
   368  	lo[0] ^= lo[2] | lo[6]
   369  	lo[6] ^= lo[2] & lo[4]
   370  	lo[2] ^= tmp & lo[0]
   371  	lo[4] ^= tmp
   372  
   373  	tmp = kSpec[(r<<2)+2]
   374  	hi[7] = ^hi[7]
   375  	hi[1] ^= tmp & ^hi[5]
   376  	tmp = tmp ^ (hi[1] & hi[3])
   377  	hi[1] ^= hi[5] & hi[7]
   378  	hi[7] ^= ^hi[3] & hi[5]
   379  	hi[3] ^= hi[1] & hi[5]
   380  	hi[5] ^= hi[1] & ^hi[7]
   381  	hi[1] ^= hi[3] | hi[7]
   382  	hi[7] ^= hi[3] & hi[5]
   383  	hi[3] ^= tmp & hi[1]
   384  	hi[5] ^= tmp
   385  
   386  	tmp = kSpec[(r<<2)+3]
   387  	lo[7] = ^lo[7]
   388  	lo[1] ^= tmp & ^lo[5]
   389  	tmp = tmp ^ (lo[1] & lo[3])
   390  	lo[1] ^= lo[5] & lo[7]
   391  	lo[7] ^= ^lo[3] & lo[5]
   392  	lo[3] ^= lo[1] & lo[5]
   393  	lo[5] ^= lo[1] & ^lo[7]
   394  	lo[1] ^= lo[3] | lo[7]
   395  	lo[7] ^= lo[3] & lo[5]
   396  	lo[3] ^= tmp & lo[1]
   397  	lo[5] ^= tmp
   398  
   399  	hi[1] ^= hi[2]
   400  	hi[3] ^= hi[4]
   401  	hi[5] ^= hi[6] ^ hi[0]
   402  	hi[7] ^= hi[0]
   403  	hi[0] ^= hi[3]
   404  	hi[2] ^= hi[5]
   405  	hi[4] ^= hi[7] ^ hi[1]
   406  	hi[6] ^= hi[1]
   407  
   408  	lo[1] ^= lo[2]
   409  	lo[3] ^= lo[4]
   410  	lo[5] ^= lo[6] ^ lo[0]
   411  	lo[7] ^= lo[0]
   412  	lo[0] ^= lo[3]
   413  	lo[2] ^= lo[5]
   414  	lo[4] ^= lo[7] ^ lo[1]
   415  	lo[6] ^= lo[1]
   416  
   417  	tmp = (hi[1] & (kWrapValue[ro])) << (kWrapOffset[ro])
   418  	hi[1] = ((hi[1] >> (kWrapOffset[ro])) & (kWrapValue[ro])) | tmp
   419  	tmp = (lo[1] & (kWrapValue[ro])) << (kWrapOffset[ro])
   420  	lo[1] = ((lo[1] >> (kWrapOffset[ro])) & (kWrapValue[ro])) | tmp
   421  
   422  	tmp = (hi[3] & (kWrapValue[ro])) << (kWrapOffset[ro])
   423  	hi[3] = ((hi[3] >> (kWrapOffset[ro])) & (kWrapValue[ro])) | tmp
   424  	tmp = (lo[3] & (kWrapValue[ro])) << (kWrapOffset[ro])
   425  	lo[3] = ((lo[3] >> (kWrapOffset[ro])) & (kWrapValue[ro])) | tmp
   426  
   427  	tmp = (hi[5] & (kWrapValue[ro])) << (kWrapOffset[ro])
   428  	hi[5] = ((hi[5] >> (kWrapOffset[ro])) & (kWrapValue[ro])) | tmp
   429  	tmp = (lo[5] & (kWrapValue[ro])) << (kWrapOffset[ro])
   430  	lo[5] = ((lo[5] >> (kWrapOffset[ro])) & (kWrapValue[ro])) | tmp
   431  
   432  	tmp = (hi[7] & (kWrapValue[ro])) << (kWrapOffset[ro])
   433  	hi[7] = ((hi[7] >> (kWrapOffset[ro])) & (kWrapValue[ro])) | tmp
   434  	tmp = (lo[7] & (kWrapValue[ro])) << (kWrapOffset[ro])
   435  	lo[7] = ((lo[7] >> (kWrapOffset[ro])) & (kWrapValue[ro])) | tmp
   436  }
   437  
   438  ////////////////
   439  /* these constants are for 512 bit hash */
   440  /*var kInit = []uint64{
   441  	uint64(0x17aa003e964bd16f), uint64(0x43d5157a052e6a63),
   442  	uint64(0x0bef970c8d5e228a), uint64(0x61c3b3f2591234e9),
   443  	uint64(0x1e806f53c1a01d89), uint64(0x806d2bea6b05a92a),
   444  	uint64(0xa6ba7520dbcc8e58), uint64(0xf73bf8ba763a0fa9),
   445  	uint64(0x694ae34105e66901), uint64(0x5ae66f2e8e8ab546),
   446  	uint64(0x243c84c1d0a74710), uint64(0x99c15a2db1716e3b),
   447  	uint64(0x56f8b19decf657cf), uint64(0x56b116577c8806a7),
   448  	uint64(0xfb1785e6dffcc2e3), uint64(0x4bdd8ccc78465a54),
   449  }*/
   450  
   451  // these constants are for 256 bit hash
   452  var kInit = []uint64{
   453  	uint64(0xEBD3202C41A398EB), uint64(0xC145B29C7BBECD92),
   454  	uint64(0xFAC7D4609151931C), uint64(0x38A507ED6820026),
   455  	uint64(0x45B92677269E23A4), uint64(0x77941AD4481AFBE0),
   456  	uint64(0x7A176B0226ABB5CD), uint64(0xA82FFF0F4224F056),
   457  	uint64(0x754D2E7F8996A371), uint64(0x62E27DF70849141D),
   458  	uint64(0x948F2476F7957627), uint64(0x6C29804757B6D587),
   459  	uint64(0x6C0D8EAC2D275E5C), uint64(0xF7A0557C6508451),
   460  	uint64(0xEA12247067D3E47B), uint64(0x69D71CD313ABE389),
   461  }
   462  
   463  var kSpec = []uint64{
   464  	uint64(0x67f815dfa2ded572), uint64(0x571523b70a15847b),
   465  	uint64(0xf6875a4d90d6ab81), uint64(0x402bd1c3c54f9f4e),
   466  	uint64(0x9cfa455ce03a98ea), uint64(0x9a99b26699d2c503),
   467  	uint64(0x8a53bbf2b4960266), uint64(0x31a2db881a1456b5),
   468  	uint64(0xdb0e199a5c5aa303), uint64(0x1044c1870ab23f40),
   469  	uint64(0x1d959e848019051c), uint64(0xdccde75eadeb336f),
   470  	uint64(0x416bbf029213ba10), uint64(0xd027bbf7156578dc),
   471  	uint64(0x5078aa3739812c0a), uint64(0xd3910041d2bf1a3f),
   472  	uint64(0x907eccf60d5a2d42), uint64(0xce97c0929c9f62dd),
   473  	uint64(0xac442bc70ba75c18), uint64(0x23fcc663d665dfd1),
   474  	uint64(0x1ab8e09e036c6e97), uint64(0xa8ec6c447e450521),
   475  	uint64(0xfa618e5dbb03f1ee), uint64(0x97818394b29796fd),
   476  	uint64(0x2f3003db37858e4a), uint64(0x956a9ffb2d8d672a),
   477  	uint64(0x6c69b8f88173fe8a), uint64(0x14427fc04672c78a),
   478  	uint64(0xc45ec7bd8f15f4c5), uint64(0x80bb118fa76f4475),
   479  	uint64(0xbc88e4aeb775de52), uint64(0xf4a3a6981e00b882),
   480  	uint64(0x1563a3a9338ff48e), uint64(0x89f9b7d524565faa),
   481  	uint64(0xfde05a7c20edf1b6), uint64(0x362c42065ae9ca36),
   482  	uint64(0x3d98fe4e433529ce), uint64(0xa74b9a7374f93a53),
   483  	uint64(0x86814e6f591ff5d0), uint64(0x9f5ad8af81ad9d0e),
   484  	uint64(0x6a6234ee670605a7), uint64(0x2717b96ebe280b8b),
   485  	uint64(0x3f1080c626077447), uint64(0x7b487ec66f7ea0e0),
   486  	uint64(0xc0a4f84aa50a550d), uint64(0x9ef18e979fe7e391),
   487  	uint64(0xd48d605081727686), uint64(0x62b0e5f3415a9e7e),
   488  	uint64(0x7a205440ec1f9ffc), uint64(0x84c9f4ce001ae4e3),
   489  	uint64(0xd895fa9df594d74f), uint64(0xa554c324117e2e55),
   490  	uint64(0x286efebd2872df5b), uint64(0xb2c4a50fe27ff578),
   491  	uint64(0x2ed349eeef7c8905), uint64(0x7f5928eb85937e44),
   492  	uint64(0x4a3124b337695f70), uint64(0x65e4d61df128865e),
   493  	uint64(0xe720b95104771bc7), uint64(0x8a87d423e843fe74),
   494  	uint64(0xf2947692a3e8297d), uint64(0xc1d9309b097acbdd),
   495  	uint64(0xe01bdc5bfb301b1d), uint64(0xbf829cf24f4924da),
   496  	uint64(0xffbf70b431bae7a4), uint64(0x48bcf8de0544320d),
   497  	uint64(0x39d3bb5332fcae3b), uint64(0xa08b29e0c1c39f45),
   498  	uint64(0x0f09aef7fd05c9e5), uint64(0x34f1904212347094),
   499  	uint64(0x95ed44e301b771a2), uint64(0x4a982f4f368e3be9),
   500  	uint64(0x15f66ca0631d4088), uint64(0xffaf52874b44c147),
   501  	uint64(0x30c60ae2f14abb7e), uint64(0xe68c6eccc5b67046),
   502  	uint64(0x00ca4fbd56a4d5a4), uint64(0xae183ec84b849dda),
   503  	uint64(0xadd1643045ce5773), uint64(0x67255c1468cea6e8),
   504  	uint64(0x16e10ecbf28cdaa3), uint64(0x9a99949a5806e933),
   505  	uint64(0x7b846fc220b2601f), uint64(0x1885d1a07facced1),
   506  	uint64(0xd319dd8da15b5932), uint64(0x46b4a5aac01c9a50),
   507  	uint64(0xba6b04e467633d9f), uint64(0x7eee560bab19caf6),
   508  	uint64(0x742128a9ea79b11f), uint64(0xee51363b35f7bde9),
   509  	uint64(0x76d350755aac571d), uint64(0x01707da3fec2463a),
   510  	uint64(0x42d8a498afc135f7), uint64(0x79676b9e20eced78),
   511  	uint64(0xa8db3aea15638341), uint64(0x832c83324d3bc3fa),
   512  	uint64(0xf347271c1f3b40a7), uint64(0x9a762db734f04059),
   513  	uint64(0xfd4f21d26c4e3ee7), uint64(0xef5957dc398dfdb8),
   514  	uint64(0xdaeb492b490c9b8d), uint64(0x0d70f36849d7a25b),
   515  	uint64(0x84558d7ad0ae3b7d), uint64(0x658ef8e4f0e9a5f5),
   516  	uint64(0x533b1036f4a2b8a0), uint64(0x5aec3e759e07a80c),
   517  	uint64(0x4f88e85692946891), uint64(0x4cbcbaf8555cb05b),
   518  	uint64(0x7b9487f3993bbbe3), uint64(0x5d1c6b72d6f4da75),
   519  	uint64(0x6db334dc28acae64), uint64(0x71db28b850a5346c),
   520  	uint64(0x2a518d10f2e261f8), uint64(0xfc75dd593364dbe3),
   521  	uint64(0xa23fce43f1bcac1c), uint64(0xb043e8023cd1bb67),
   522  	uint64(0x75a12988ca5b0a33), uint64(0x5c5316b44d19347f),
   523  	uint64(0x1e4d790ec3943b92), uint64(0x3fafeeb6d7757479),
   524  	uint64(0x21391abef7d4a8ea), uint64(0x5127234c097ef45c),
   525  	uint64(0xd23c32ba5324a326), uint64(0xadd5a66d4a17a344),
   526  	uint64(0x08c9f2afa63e1db5), uint64(0x563c6b91983d5983),
   527  	uint64(0x4d608672a17cf84c), uint64(0xf6c76e08cc3ee246),
   528  	uint64(0x5e76bcb1b333982f), uint64(0x2ae6c4efa566d62b),
   529  	uint64(0x36d4c1bee8b6f406), uint64(0x6321efbc1582ee74),
   530  	uint64(0x69c953f40d4ec1fd), uint64(0x26585806c45a7da7),
   531  	uint64(0x16fae0061614c17e), uint64(0x3f9d63283daf907e),
   532  	uint64(0x0cd29b00e3f2c9d2), uint64(0x300cd4b730ceaa5f),
   533  	uint64(0x9832e0f216512a74), uint64(0x9af8cee3d830eb0d),
   534  	uint64(0x9279f1b57b9ec54b), uint64(0xd36886046ee651ff),
   535  	uint64(0x316796e6574d239b), uint64(0x05750a17f3a6e6cc),
   536  	uint64(0xce6c3213d98176b1), uint64(0x62a205f88452173c),
   537  	uint64(0x47154778b3cb2bf4), uint64(0x486a9323825446ff),
   538  	uint64(0x65655e4e0758df38), uint64(0x8e5086fc897cfcf2),
   539  	uint64(0x86ca0bd0442e7031), uint64(0x4e477830a20940f0),
   540  	uint64(0x8338f7d139eea065), uint64(0xbd3a2ce437e95ef7),
   541  	uint64(0x6ff8130126b29721), uint64(0xe7de9fefd1ed44a3),
   542  	uint64(0xd992257615dfa08b), uint64(0xbe42dc12f6f7853c),
   543  	uint64(0x7eb027ab7ceca7d8), uint64(0xdea83eaada7d8d53),
   544  	uint64(0xd86902bd93ce25aa), uint64(0xf908731afd43f65a),
   545  	uint64(0xa5194a17daef5fc0), uint64(0x6a21fd4c33664d97),
   546  	uint64(0x701541db3198b435), uint64(0x9b54cdedbb0f1eea),
   547  	uint64(0x72409751a163d09a), uint64(0xe26f4791bf9d75f6),
   548  }
   549  
   550  var kWrapValue = []uint64{
   551  	uint64(0x5555555555555555),
   552  	uint64(0x3333333333333333),
   553  	uint64(0x0F0F0F0F0F0F0F0F),
   554  	uint64(0x00FF00FF00FF00FF),
   555  	uint64(0x0000FFFF0000FFFF),
   556  	uint64(0x00000000FFFFFFFF),
   557  }
   558  
   559  var kWrapOffset = []uint64{
   560  	1, 2, 4, 8, 16, 32,
   561  }