github.com/waltonchain/waltonchain_gwtc_src@v1.1.4-0.20201225072101-8a298c95a819/crypto/x11/cubed/cubed.go (about)

     1  // Use of this source code is governed by an ISC
     2  // license that can be found in the LICENSE file.
     3  
     4  package cubed
     5  
     6  import (
     7  	"fmt"
     8  
     9  	"github.com/wtc/go-wtc/crypto/hash"
    10  )
    11  
    12  // HashSize holds the size of a hash in bytes.
    13  const HashSize = int(64)
    14  
    15  // BlockSize holds the size of a block in bytes.
    16  const BlockSize = uintptr(32)
    17  
    18  ////////////////
    19  
    20  type digest struct {
    21  	ptr uintptr
    22  
    23  	h [32]uint32
    24  
    25  	b [BlockSize]byte
    26  }
    27  
    28  // New returns a new digest compute a CUBEHASH512 hash.
    29  func New() hash.Digest {
    30  	ref := &digest{}
    31  	ref.Reset()
    32  	return ref
    33  }
    34  
    35  ////////////////
    36  
    37  // Reset resets the digest to its initial state.
    38  func (ref *digest) Reset() {
    39  	ref.ptr = 0
    40  	copy(ref.h[:], kInit[:])
    41  }
    42  
    43  // Sum appends the current hash to dst and returns the result
    44  // as a slice. It does not change the underlying hash state.
    45  func (ref *digest) Sum(dst []byte) []byte {
    46  	dgt := *ref
    47  	hsh := [64]byte{}
    48  	dgt.Close(hsh[:], 0, 0)
    49  	return append(dst, hsh[:]...)
    50  }
    51  
    52  // Write more data to the running hash, never returns an error.
    53  func (ref *digest) Write(src []byte) (int, error) {
    54  	sln := uintptr(len(src))
    55  	fln := len(src)
    56  	ptr := ref.ptr
    57  
    58  	if sln < (BlockSize - ptr) {
    59  		copy(ref.b[ptr:], src[:sln])
    60  		ref.ptr += sln
    61  		return int(sln), nil
    62  	}
    63  
    64  	st := ref.h[:]
    65  	buf := ref.b[:]
    66  	for sln > 0 {
    67  		cln := BlockSize - ptr
    68  
    69  		if cln > sln {
    70  			cln = sln
    71  		}
    72  		sln -= cln
    73  
    74  		copy(buf[ptr:], src[:cln])
    75  		src = src[cln:]
    76  		ptr += cln
    77  
    78  		if ptr == BlockSize {
    79  			st[0x00] ^= decUInt32le(buf[0:])
    80  			st[0x01] ^= decUInt32le(buf[4:])
    81  			st[0x02] ^= decUInt32le(buf[8:])
    82  			st[0x03] ^= decUInt32le(buf[12:])
    83  			st[0x04] ^= decUInt32le(buf[16:])
    84  			st[0x05] ^= decUInt32le(buf[20:])
    85  			st[0x06] ^= decUInt32le(buf[24:])
    86  			st[0x07] ^= decUInt32le(buf[28:])
    87  
    88  			runRounds(st)
    89  			runRounds(st)
    90  
    91  			runRounds(st)
    92  			runRounds(st)
    93  
    94  			runRounds(st)
    95  			runRounds(st)
    96  
    97  			runRounds(st)
    98  			runRounds(st)
    99  
   100  			ptr = 0
   101  		}
   102  	}
   103  
   104  	ref.ptr = ptr
   105  	return fln, nil
   106  }
   107  
   108  // Close the digest by writing the last bits and storing the hash
   109  // in dst. This prepares the digest for reuse by calling reset. A call
   110  // to Close with a dst that is smaller then HashSize will return an error.
   111  func (ref *digest) Close(dst []byte, bits uint8, bcnt uint8) error {
   112  	if ln := len(dst); HashSize > ln {
   113  		return fmt.Errorf("Cubed Close: dst min length: %d, got %d", HashSize, ln)
   114  	}
   115  	st := ref.h[:]
   116  
   117  	{
   118  		buf := ref.b[:]
   119  		ptr := ref.ptr + 1
   120  
   121  		z := uint8(0x80) >> bcnt
   122  		buf[ref.ptr] = uint8((bits & -z) | z)
   123  
   124  		memset(buf[ptr:], 0)
   125  		st[0x00] ^= decUInt32le(buf[0:])
   126  		st[0x01] ^= decUInt32le(buf[4:])
   127  		st[0x02] ^= decUInt32le(buf[8:])
   128  		st[0x03] ^= decUInt32le(buf[12:])
   129  		st[0x04] ^= decUInt32le(buf[16:])
   130  		st[0x05] ^= decUInt32le(buf[20:])
   131  		st[0x06] ^= decUInt32le(buf[24:])
   132  		st[0x07] ^= decUInt32le(buf[28:])
   133  	}
   134  
   135  	for i := uint8(0); i < 11; i++ {
   136  		runRounds(st)
   137  		runRounds(st)
   138  
   139  		runRounds(st)
   140  		runRounds(st)
   141  
   142  		runRounds(st)
   143  		runRounds(st)
   144  
   145  		runRounds(st)
   146  		runRounds(st)
   147  
   148  		if i == 0 {
   149  			st[0x1F] ^= uint32(1)
   150  		}
   151  	}
   152  
   153  	for i := uint8(0); i < 16; i++ {
   154  		encUInt32le(dst[(i<<2):], ref.h[i])
   155  	}
   156  
   157  	ref.Reset()
   158  	return nil
   159  }
   160  
   161  // Size returns the number of bytes required to store the hash.
   162  func (*digest) Size() int {
   163  	return int(HashSize)
   164  }
   165  
   166  // BlockSize returns the block size of the hash.
   167  func (*digest) BlockSize() int {
   168  	return int(BlockSize)
   169  }
   170  
   171  ////////////////
   172  
   173  func memset(dst []byte, src byte) {
   174  	for i := range dst {
   175  		dst[i] = src
   176  	}
   177  }
   178  
   179  func decUInt32le(src []byte) uint32 {
   180  	return (uint32(src[0]) |
   181  		uint32(src[1])<<8 |
   182  		uint32(src[2])<<16 |
   183  		uint32(src[3])<<24)
   184  }
   185  
   186  func encUInt32le(dst []byte, src uint32) {
   187  	dst[0] = uint8(src)
   188  	dst[1] = uint8(src >> 8)
   189  	dst[2] = uint8(src >> 16)
   190  	dst[3] = uint8(src >> 24)
   191  }
   192  
   193  func runRounds(st []uint32) {
   194  	st[0x10] = (st[0x00] + st[0x10])
   195  	st[0x00] = (st[0x00] << 7) | (st[0x00] >> (32 - 7))
   196  	st[0x11] = (st[0x01] + st[0x11])
   197  	st[0x01] = (st[0x01] << 7) | (st[0x01] >> (32 - 7))
   198  	st[0x12] = (st[0x02] + st[0x12])
   199  	st[0x02] = (st[0x02] << 7) | (st[0x02] >> (32 - 7))
   200  	st[0x13] = (st[0x03] + st[0x13])
   201  	st[0x03] = (st[0x03] << 7) | (st[0x03] >> (32 - 7))
   202  	st[0x14] = (st[0x04] + st[0x14])
   203  	st[0x04] = (st[0x04] << 7) | (st[0x04] >> (32 - 7))
   204  	st[0x15] = (st[0x05] + st[0x15])
   205  	st[0x05] = (st[0x05] << 7) | (st[0x05] >> (32 - 7))
   206  	st[0x16] = (st[0x06] + st[0x16])
   207  	st[0x06] = (st[0x06] << 7) | (st[0x06] >> (32 - 7))
   208  	st[0x17] = (st[0x07] + st[0x17])
   209  	st[0x07] = (st[0x07] << 7) | (st[0x07] >> (32 - 7))
   210  	st[0x18] = (st[0x08] + st[0x18])
   211  	st[0x08] = (st[0x08] << 7) | (st[0x08] >> (32 - 7))
   212  	st[0x19] = (st[0x09] + st[0x19])
   213  	st[0x09] = (st[0x09] << 7) | (st[0x09] >> (32 - 7))
   214  	st[0x1A] = (st[0x0A] + st[0x1A])
   215  	st[0x0A] = (st[0x0A] << 7) | (st[0x0A] >> (32 - 7))
   216  	st[0x1B] = (st[0x0B] + st[0x1B])
   217  	st[0x0B] = (st[0x0B] << 7) | (st[0x0B] >> (32 - 7))
   218  	st[0x1C] = (st[0x0C] + st[0x1C])
   219  	st[0x0C] = (st[0x0C] << 7) | (st[0x0C] >> (32 - 7))
   220  	st[0x1D] = (st[0x0D] + st[0x1D])
   221  	st[0x0D] = (st[0x0D] << 7) | (st[0x0D] >> (32 - 7))
   222  	st[0x1E] = (st[0x0E] + st[0x1E])
   223  	st[0x0E] = (st[0x0E] << 7) | (st[0x0E] >> (32 - 7))
   224  	st[0x1F] = (st[0x0F] + st[0x1F])
   225  	st[0x0F] = (st[0x0F] << 7) | (st[0x0F] >> (32 - 7))
   226  	st[0x08] ^= st[0x10]
   227  	st[0x09] ^= st[0x11]
   228  	st[0x0A] ^= st[0x12]
   229  	st[0x0B] ^= st[0x13]
   230  	st[0x0C] ^= st[0x14]
   231  	st[0x0D] ^= st[0x15]
   232  	st[0x0E] ^= st[0x16]
   233  	st[0x0F] ^= st[0x17]
   234  	st[0x00] ^= st[0x18]
   235  	st[0x01] ^= st[0x19]
   236  	st[0x02] ^= st[0x1A]
   237  	st[0x03] ^= st[0x1B]
   238  	st[0x04] ^= st[0x1C]
   239  	st[0x05] ^= st[0x1D]
   240  	st[0x06] ^= st[0x1E]
   241  	st[0x07] ^= st[0x1F]
   242  	st[0x12] = (st[0x08] + st[0x12])
   243  	st[0x08] = (st[0x08] << 11) | (st[0x08] >> (32 - 11))
   244  	st[0x13] = (st[0x09] + st[0x13])
   245  	st[0x09] = (st[0x09] << 11) | (st[0x09] >> (32 - 11))
   246  	st[0x10] = (st[0x0A] + st[0x10])
   247  	st[0x0A] = (st[0x0A] << 11) | (st[0x0A] >> (32 - 11))
   248  	st[0x11] = (st[0x0B] + st[0x11])
   249  	st[0x0B] = (st[0x0B] << 11) | (st[0x0B] >> (32 - 11))
   250  	st[0x16] = (st[0x0C] + st[0x16])
   251  	st[0x0C] = (st[0x0C] << 11) | (st[0x0C] >> (32 - 11))
   252  	st[0x17] = (st[0x0D] + st[0x17])
   253  	st[0x0D] = (st[0x0D] << 11) | (st[0x0D] >> (32 - 11))
   254  	st[0x14] = (st[0x0E] + st[0x14])
   255  	st[0x0E] = (st[0x0E] << 11) | (st[0x0E] >> (32 - 11))
   256  	st[0x15] = (st[0x0F] + st[0x15])
   257  	st[0x0F] = (st[0x0F] << 11) | (st[0x0F] >> (32 - 11))
   258  	st[0x1A] = (st[0x00] + st[0x1A])
   259  	st[0x00] = (st[0x00] << 11) | (st[0x00] >> (32 - 11))
   260  	st[0x1B] = (st[0x01] + st[0x1B])
   261  	st[0x01] = (st[0x01] << 11) | (st[0x01] >> (32 - 11))
   262  	st[0x18] = (st[0x02] + st[0x18])
   263  	st[0x02] = (st[0x02] << 11) | (st[0x02] >> (32 - 11))
   264  	st[0x19] = (st[0x03] + st[0x19])
   265  	st[0x03] = (st[0x03] << 11) | (st[0x03] >> (32 - 11))
   266  	st[0x1E] = (st[0x04] + st[0x1E])
   267  	st[0x04] = (st[0x04] << 11) | (st[0x04] >> (32 - 11))
   268  	st[0x1F] = (st[0x05] + st[0x1F])
   269  	st[0x05] = (st[0x05] << 11) | (st[0x05] >> (32 - 11))
   270  	st[0x1C] = (st[0x06] + st[0x1C])
   271  	st[0x06] = (st[0x06] << 11) | (st[0x06] >> (32 - 11))
   272  	st[0x1D] = (st[0x07] + st[0x1D])
   273  	st[0x07] = (st[0x07] << 11) | (st[0x07] >> (32 - 11))
   274  	st[0x0C] ^= st[0x12]
   275  	st[0x0D] ^= st[0x13]
   276  	st[0x0E] ^= st[0x10]
   277  	st[0x0F] ^= st[0x11]
   278  	st[0x08] ^= st[0x16]
   279  	st[0x09] ^= st[0x17]
   280  	st[0x0A] ^= st[0x14]
   281  	st[0x0B] ^= st[0x15]
   282  	st[0x04] ^= st[0x1A]
   283  	st[0x05] ^= st[0x1B]
   284  	st[0x06] ^= st[0x18]
   285  	st[0x07] ^= st[0x19]
   286  	st[0x00] ^= st[0x1E]
   287  	st[0x01] ^= st[0x1F]
   288  	st[0x02] ^= st[0x1C]
   289  	st[0x03] ^= st[0x1D]
   290  
   291  	st[0x13] = (st[0x0C] + st[0x13])
   292  	st[0x0C] = (st[0x0C] << 7) | (st[0x0C] >> (32 - 7))
   293  	st[0x12] = (st[0x0D] + st[0x12])
   294  	st[0x0D] = (st[0x0D] << 7) | (st[0x0D] >> (32 - 7))
   295  	st[0x11] = (st[0x0E] + st[0x11])
   296  	st[0x0E] = (st[0x0E] << 7) | (st[0x0E] >> (32 - 7))
   297  	st[0x10] = (st[0x0F] + st[0x10])
   298  	st[0x0F] = (st[0x0F] << 7) | (st[0x0F] >> (32 - 7))
   299  	st[0x17] = (st[0x08] + st[0x17])
   300  	st[0x08] = (st[0x08] << 7) | (st[0x08] >> (32 - 7))
   301  	st[0x16] = (st[0x09] + st[0x16])
   302  	st[0x09] = (st[0x09] << 7) | (st[0x09] >> (32 - 7))
   303  	st[0x15] = (st[0x0A] + st[0x15])
   304  	st[0x0A] = (st[0x0A] << 7) | (st[0x0A] >> (32 - 7))
   305  	st[0x14] = (st[0x0B] + st[0x14])
   306  	st[0x0B] = (st[0x0B] << 7) | (st[0x0B] >> (32 - 7))
   307  	st[0x1B] = (st[0x04] + st[0x1B])
   308  	st[0x04] = (st[0x04] << 7) | (st[0x04] >> (32 - 7))
   309  	st[0x1A] = (st[0x05] + st[0x1A])
   310  	st[0x05] = (st[0x05] << 7) | (st[0x05] >> (32 - 7))
   311  	st[0x19] = (st[0x06] + st[0x19])
   312  	st[0x06] = (st[0x06] << 7) | (st[0x06] >> (32 - 7))
   313  	st[0x18] = (st[0x07] + st[0x18])
   314  	st[0x07] = (st[0x07] << 7) | (st[0x07] >> (32 - 7))
   315  	st[0x1F] = (st[0x00] + st[0x1F])
   316  	st[0x00] = (st[0x00] << 7) | (st[0x00] >> (32 - 7))
   317  	st[0x1E] = (st[0x01] + st[0x1E])
   318  	st[0x01] = (st[0x01] << 7) | (st[0x01] >> (32 - 7))
   319  	st[0x1D] = (st[0x02] + st[0x1D])
   320  	st[0x02] = (st[0x02] << 7) | (st[0x02] >> (32 - 7))
   321  	st[0x1C] = (st[0x03] + st[0x1C])
   322  	st[0x03] = (st[0x03] << 7) | (st[0x03] >> (32 - 7))
   323  	st[0x04] ^= st[0x13]
   324  	st[0x05] ^= st[0x12]
   325  	st[0x06] ^= st[0x11]
   326  	st[0x07] ^= st[0x10]
   327  	st[0x00] ^= st[0x17]
   328  	st[0x01] ^= st[0x16]
   329  	st[0x02] ^= st[0x15]
   330  	st[0x03] ^= st[0x14]
   331  	st[0x0C] ^= st[0x1B]
   332  	st[0x0D] ^= st[0x1A]
   333  	st[0x0E] ^= st[0x19]
   334  	st[0x0F] ^= st[0x18]
   335  	st[0x08] ^= st[0x1F]
   336  	st[0x09] ^= st[0x1E]
   337  	st[0x0A] ^= st[0x1D]
   338  	st[0x0B] ^= st[0x1C]
   339  	st[0x11] = (st[0x04] + st[0x11])
   340  	st[0x04] = (st[0x04] << 11) | (st[0x04] >> (32 - 11))
   341  	st[0x10] = (st[0x05] + st[0x10])
   342  	st[0x05] = (st[0x05] << 11) | (st[0x05] >> (32 - 11))
   343  	st[0x13] = (st[0x06] + st[0x13])
   344  	st[0x06] = (st[0x06] << 11) | (st[0x06] >> (32 - 11))
   345  	st[0x12] = (st[0x07] + st[0x12])
   346  	st[0x07] = (st[0x07] << 11) | (st[0x07] >> (32 - 11))
   347  	st[0x15] = (st[0x00] + st[0x15])
   348  	st[0x00] = (st[0x00] << 11) | (st[0x00] >> (32 - 11))
   349  	st[0x14] = (st[0x01] + st[0x14])
   350  	st[0x01] = (st[0x01] << 11) | (st[0x01] >> (32 - 11))
   351  	st[0x17] = (st[0x02] + st[0x17])
   352  	st[0x02] = (st[0x02] << 11) | (st[0x02] >> (32 - 11))
   353  	st[0x16] = (st[0x03] + st[0x16])
   354  	st[0x03] = (st[0x03] << 11) | (st[0x03] >> (32 - 11))
   355  	st[0x19] = (st[0x0C] + st[0x19])
   356  	st[0x0C] = (st[0x0C] << 11) | (st[0x0C] >> (32 - 11))
   357  	st[0x18] = (st[0x0D] + st[0x18])
   358  	st[0x0D] = (st[0x0D] << 11) | (st[0x0D] >> (32 - 11))
   359  	st[0x1B] = (st[0x0E] + st[0x1B])
   360  	st[0x0E] = (st[0x0E] << 11) | (st[0x0E] >> (32 - 11))
   361  	st[0x1A] = (st[0x0F] + st[0x1A])
   362  	st[0x0F] = (st[0x0F] << 11) | (st[0x0F] >> (32 - 11))
   363  	st[0x1D] = (st[0x08] + st[0x1D])
   364  	st[0x08] = (st[0x08] << 11) | (st[0x08] >> (32 - 11))
   365  	st[0x1C] = (st[0x09] + st[0x1C])
   366  	st[0x09] = (st[0x09] << 11) | (st[0x09] >> (32 - 11))
   367  	st[0x1F] = (st[0x0A] + st[0x1F])
   368  	st[0x0A] = (st[0x0A] << 11) | (st[0x0A] >> (32 - 11))
   369  	st[0x1E] = (st[0x0B] + st[0x1E])
   370  	st[0x0B] = (st[0x0B] << 11) | (st[0x0B] >> (32 - 11))
   371  	st[0x00] ^= st[0x11]
   372  	st[0x01] ^= st[0x10]
   373  	st[0x02] ^= st[0x13]
   374  	st[0x03] ^= st[0x12]
   375  	st[0x04] ^= st[0x15]
   376  	st[0x05] ^= st[0x14]
   377  	st[0x06] ^= st[0x17]
   378  	st[0x07] ^= st[0x16]
   379  	st[0x08] ^= st[0x19]
   380  	st[0x09] ^= st[0x18]
   381  	st[0x0A] ^= st[0x1B]
   382  	st[0x0B] ^= st[0x1A]
   383  	st[0x0C] ^= st[0x1D]
   384  	st[0x0D] ^= st[0x1C]
   385  	st[0x0E] ^= st[0x1F]
   386  	st[0x0F] ^= st[0x1E]
   387  }
   388  
   389  ////////////////
   390  
   391  var kInit = [32]uint32{
   392  	uint32(0x2AEA2A61), uint32(0x50F494D4), uint32(0x2D538B8B),
   393  	uint32(0x4167D83E), uint32(0x3FEE2313), uint32(0xC701CF8C),
   394  	uint32(0xCC39968E), uint32(0x50AC5695), uint32(0x4D42C787),
   395  	uint32(0xA647A8B3), uint32(0x97CF0BEF), uint32(0x825B4537),
   396  	uint32(0xEEF864D2), uint32(0xF22090C4), uint32(0xD0E5CD33),
   397  	uint32(0xA23911AE), uint32(0xFCD398D9), uint32(0x148FE485),
   398  	uint32(0x1B017BEF), uint32(0xB6444532), uint32(0x6A536159),
   399  	uint32(0x2FF5781C), uint32(0x91FA7934), uint32(0x0DBADEA9),
   400  	uint32(0xD65C8A2B), uint32(0xA5A70E75), uint32(0xB1C62456),
   401  	uint32(0xBC796576), uint32(0x1921C8F7), uint32(0xE7989AF1),
   402  	uint32(0x7795D246), uint32(0xD43E3B44),
   403  }