github.com/waltonchain/waltonchain_gwtc_src@v1.1.4-0.20201225072101-8a298c95a819/crypto/x11/blake/blake.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 blake
     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(128)
    17  
    18  ////////////////
    19  
    20  type digest struct {
    21  	ptr uintptr
    22  
    23  	h [8]uint64
    24  	t [2]uint64
    25  
    26  	b [BlockSize]byte
    27  }
    28  
    29  // New returns a new digest compute a BLAKE512 hash.
    30  func New() hash.Digest {
    31  	ref := &digest{}
    32  	ref.Reset()
    33  	return ref
    34  }
    35  
    36  ////////////////
    37  
    38  // Reset resets the digest to its initial state.
    39  func (ref *digest) Reset() {
    40  	ref.ptr = 0
    41  	copy(ref.h[:], kInit[:])
    42  	ref.t[0], ref.t[1] = 0, 0
    43  }
    44  
    45  // Sum appends the current hash to dst and returns the result
    46  // as a slice. It does not change the underlying hash state.
    47  func (ref *digest) Sum(dst []byte) []byte {
    48  	dgt := *ref
    49  	hsh := [64]byte{}
    50  	dgt.Close(hsh[:], 0, 0)
    51  	return append(dst, hsh[:]...)
    52  }
    53  
    54  // Write more data to the running hash, never returns an error.
    55  func (ref *digest) Write(src []byte) (int, error) {
    56  	sln := uintptr(len(src))
    57  	fln := len(src)
    58  	ptr := ref.ptr
    59  
    60  	if sln < (BlockSize - ptr) {
    61  		copy(ref.b[ptr:], src)
    62  		ref.ptr += sln
    63  		return int(sln), nil
    64  	}
    65  
    66  	for sln > 0 {
    67  		cln := BlockSize - ptr
    68  
    69  		if cln > sln {
    70  			cln = sln
    71  		}
    72  		sln -= cln
    73  
    74  		copy(ref.b[ptr:], src[:cln])
    75  		src = src[cln:]
    76  		ptr += cln
    77  
    78  		if ptr == BlockSize {
    79  			h := ref.h[:]
    80  			t := ref.t[:]
    81  
    82  			t[0] = t[0] + 1024
    83  			if t[0] < 1024 {
    84  				t[1] += 1
    85  			}
    86  			ptr = 0
    87  
    88  			var vec [16]uint64
    89  			vec[0x0] = h[0]
    90  			vec[0x1] = h[1]
    91  			vec[0x2] = h[2]
    92  			vec[0x3] = h[3]
    93  			vec[0x4] = h[4]
    94  			vec[0x5] = h[5]
    95  			vec[0x6] = h[6]
    96  			vec[0x7] = h[7]
    97  			vec[0x8] = kSpec[0]
    98  			vec[0x9] = kSpec[1]
    99  			vec[0xA] = kSpec[2]
   100  			vec[0xB] = kSpec[3]
   101  			vec[0xC] = t[0] ^ kSpec[4]
   102  			vec[0xD] = t[0] ^ kSpec[5]
   103  			vec[0xE] = t[1] ^ kSpec[6]
   104  			vec[0xF] = t[1] ^ kSpec[7]
   105  
   106  			var mat [16]uint64
   107  			mat[0x0] = decUInt64be(ref.b[0:])
   108  			mat[0x1] = decUInt64be(ref.b[8:])
   109  			mat[0x2] = decUInt64be(ref.b[16:])
   110  			mat[0x3] = decUInt64be(ref.b[24:])
   111  			mat[0x4] = decUInt64be(ref.b[32:])
   112  			mat[0x5] = decUInt64be(ref.b[40:])
   113  			mat[0x6] = decUInt64be(ref.b[48:])
   114  			mat[0x7] = decUInt64be(ref.b[56:])
   115  			mat[0x8] = decUInt64be(ref.b[64:])
   116  			mat[0x9] = decUInt64be(ref.b[72:])
   117  			mat[0xA] = decUInt64be(ref.b[80:])
   118  			mat[0xB] = decUInt64be(ref.b[88:])
   119  			mat[0xC] = decUInt64be(ref.b[96:])
   120  			mat[0xD] = decUInt64be(ref.b[104:])
   121  			mat[0xE] = decUInt64be(ref.b[112:])
   122  			mat[0xF] = decUInt64be(ref.b[120:])
   123  
   124  			var sig []uint8
   125  			for r := uint8(0); r < 16; r++ {
   126  				sig = kSigma[r][:]
   127  
   128  				vec[0x0] = (vec[0x0] + vec[0x4] + (mat[sig[0x0]] ^ kSpec[sig[0x1]]))
   129  				vec[0xC] = (((vec[0xC] ^ vec[0x0]) << (32)) | ((vec[0xC] ^ vec[0x0]) >> 32))
   130  				vec[0x8] = (vec[0x8] + vec[0xC])
   131  				vec[0x4] = (((vec[0x4] ^ vec[0x8]) << (39)) | ((vec[0x4] ^ vec[0x8]) >> 25))
   132  				vec[0x0] = (vec[0x0] + vec[0x4] + (mat[sig[0x1]] ^ kSpec[sig[0x0]]))
   133  				vec[0xC] = (((vec[0xC] ^ vec[0x0]) << (48)) | ((vec[0xC] ^ vec[0x0]) >> 16))
   134  				vec[0x8] = (vec[0x8] + vec[0xC])
   135  				vec[0x4] = (((vec[0x4] ^ vec[0x8]) << (53)) | ((vec[0x4] ^ vec[0x8]) >> 11))
   136  
   137  				vec[0x1] = (vec[0x1] + vec[0x5] + (mat[sig[0x2]] ^ kSpec[sig[0x3]]))
   138  				vec[0xD] = (((vec[0xD] ^ vec[0x1]) << (32)) | ((vec[0xD] ^ vec[0x1]) >> 32))
   139  				vec[0x9] = (vec[0x9] + vec[0xD])
   140  				vec[0x5] = (((vec[0x5] ^ vec[0x9]) << (39)) | ((vec[0x5] ^ vec[0x9]) >> 25))
   141  				vec[0x1] = (vec[0x1] + vec[0x5] + (mat[sig[0x3]] ^ kSpec[sig[0x2]]))
   142  				vec[0xD] = (((vec[0xD] ^ vec[0x1]) << (48)) | ((vec[0xD] ^ vec[0x1]) >> 16))
   143  				vec[0x9] = (vec[0x9] + vec[0xD])
   144  				vec[0x5] = (((vec[0x5] ^ vec[0x9]) << (53)) | ((vec[0x5] ^ vec[0x9]) >> 11))
   145  
   146  				vec[0x2] = (vec[0x2] + vec[0x6] + (mat[sig[0x4]] ^ kSpec[sig[0x5]]))
   147  				vec[0xE] = (((vec[0xE] ^ vec[0x2]) << (32)) | ((vec[0xE] ^ vec[0x2]) >> 32))
   148  				vec[0xA] = (vec[0xA] + vec[0xE])
   149  				vec[0x6] = (((vec[0x6] ^ vec[0xA]) << (39)) | ((vec[0x6] ^ vec[0xA]) >> 25))
   150  				vec[0x2] = (vec[0x2] + vec[0x6] + (mat[sig[0x5]] ^ kSpec[sig[0x4]]))
   151  				vec[0xE] = (((vec[0xE] ^ vec[0x2]) << (48)) | ((vec[0xE] ^ vec[0x2]) >> 16))
   152  				vec[0xA] = (vec[0xA] + vec[0xE])
   153  				vec[0x6] = (((vec[0x6] ^ vec[0xA]) << (53)) | ((vec[0x6] ^ vec[0xA]) >> 11))
   154  
   155  				vec[0x3] = (vec[0x3] + vec[0x7] + (mat[sig[0x6]] ^ kSpec[sig[0x7]]))
   156  				vec[0xF] = (((vec[0xF] ^ vec[0x3]) << (32)) | ((vec[0xF] ^ vec[0x3]) >> 32))
   157  				vec[0xB] = (vec[0xB] + vec[0xF])
   158  				vec[0x7] = (((vec[0x7] ^ vec[0xB]) << (39)) | ((vec[0x7] ^ vec[0xB]) >> 25))
   159  				vec[0x3] = (vec[0x3] + vec[0x7] + (mat[sig[0x7]] ^ kSpec[sig[0x6]]))
   160  				vec[0xF] = (((vec[0xF] ^ vec[0x3]) << (48)) | ((vec[0xF] ^ vec[0x3]) >> 16))
   161  				vec[0xB] = (vec[0xB] + vec[0xF])
   162  				vec[0x7] = (((vec[0x7] ^ vec[0xB]) << (53)) | ((vec[0x7] ^ vec[0xB]) >> 11))
   163  
   164  				vec[0x0] = (vec[0x0] + vec[0x5] + (mat[sig[0x8]] ^ kSpec[sig[0x9]]))
   165  				vec[0xF] = (((vec[0xF] ^ vec[0x0]) << (32)) | ((vec[0xF] ^ vec[0x0]) >> 32))
   166  				vec[0xA] = (vec[0xA] + vec[0xF])
   167  				vec[0x5] = (((vec[0x5] ^ vec[0xA]) << (39)) | ((vec[0x5] ^ vec[0xA]) >> 25))
   168  				vec[0x0] = (vec[0x0] + vec[0x5] + (mat[sig[0x9]] ^ kSpec[sig[0x8]]))
   169  				vec[0xF] = (((vec[0xF] ^ vec[0x0]) << (48)) | ((vec[0xF] ^ vec[0x0]) >> 16))
   170  				vec[0xA] = (vec[0xA] + vec[0xF])
   171  				vec[0x5] = (((vec[0x5] ^ vec[0xA]) << (53)) | ((vec[0x5] ^ vec[0xA]) >> 11))
   172  
   173  				vec[0x1] = (vec[0x1] + vec[0x6] + (mat[sig[0xA]] ^ kSpec[sig[0xB]]))
   174  				vec[0xC] = (((vec[0xC] ^ vec[0x1]) << (32)) | ((vec[0xC] ^ vec[0x1]) >> 32))
   175  				vec[0xB] = (vec[0xB] + vec[0xC])
   176  				vec[0x6] = (((vec[0x6] ^ vec[0xB]) << (39)) | ((vec[0x6] ^ vec[0xB]) >> 25))
   177  				vec[0x1] = (vec[0x1] + vec[0x6] + (mat[sig[0xB]] ^ kSpec[sig[0xA]]))
   178  				vec[0xC] = (((vec[0xC] ^ vec[0x1]) << (48)) | ((vec[0xC] ^ vec[0x1]) >> 16))
   179  				vec[0xB] = (vec[0xB] + vec[0xC])
   180  				vec[0x6] = (((vec[0x6] ^ vec[0xB]) << (53)) | ((vec[0x6] ^ vec[0xB]) >> 11))
   181  
   182  				vec[0x2] = (vec[0x2] + vec[0x7] + (mat[sig[0xC]] ^ kSpec[sig[0xD]]))
   183  				vec[0xD] = (((vec[0xD] ^ vec[0x2]) << (32)) | ((vec[0xD] ^ vec[0x2]) >> 32))
   184  				vec[0x8] = (vec[0x8] + vec[0xD])
   185  				vec[0x7] = (((vec[0x7] ^ vec[0x8]) << (39)) | ((vec[0x7] ^ vec[0x8]) >> 25))
   186  				vec[0x2] = (vec[0x2] + vec[0x7] + (mat[sig[0xD]] ^ kSpec[sig[0xC]]))
   187  				vec[0xD] = (((vec[0xD] ^ vec[0x2]) << (48)) | ((vec[0xD] ^ vec[0x2]) >> 16))
   188  				vec[0x8] = (vec[0x8] + vec[0xD])
   189  				vec[0x7] = (((vec[0x7] ^ vec[0x8]) << (53)) | ((vec[0x7] ^ vec[0x8]) >> 11))
   190  
   191  				vec[0x3] = (vec[0x3] + vec[0x4] + (mat[sig[0xE]] ^ kSpec[sig[0xF]]))
   192  				vec[0xE] = (((vec[0xE] ^ vec[0x3]) << (32)) | ((vec[0xE] ^ vec[0x3]) >> 32))
   193  				vec[0x9] = (vec[0x9] + vec[0xE])
   194  				vec[0x4] = (((vec[0x4] ^ vec[0x9]) << (39)) | ((vec[0x4] ^ vec[0x9]) >> 25))
   195  				vec[0x3] = (vec[0x3] + vec[0x4] + (mat[sig[0xF]] ^ kSpec[sig[0xE]]))
   196  				vec[0xE] = (((vec[0xE] ^ vec[0x3]) << (48)) | ((vec[0xE] ^ vec[0x3]) >> 16))
   197  				vec[0x9] = (vec[0x9] + vec[0xE])
   198  				vec[0x4] = (((vec[0x4] ^ vec[0x9]) << (53)) | ((vec[0x4] ^ vec[0x9]) >> 11))
   199  			}
   200  
   201  			h[0] ^= vec[0x0] ^ vec[0x8]
   202  			h[1] ^= vec[0x1] ^ vec[0x9]
   203  			h[2] ^= vec[0x2] ^ vec[0xA]
   204  			h[3] ^= vec[0x3] ^ vec[0xB]
   205  			h[4] ^= vec[0x4] ^ vec[0xC]
   206  			h[5] ^= vec[0x5] ^ vec[0xD]
   207  			h[6] ^= vec[0x6] ^ vec[0xE]
   208  			h[7] ^= vec[0x7] ^ vec[0xF]
   209  		}
   210  	}
   211  
   212  	ref.ptr = ptr
   213  	return fln, nil
   214  }
   215  
   216  // Close the digest by writing the last bits and storing the hash
   217  // in dst. This prepares the digest for reuse by calling reset. A call
   218  // to Close with a dst that is smaller then HashSize will return an error.
   219  func (ref *digest) Close(dst []byte, bits uint8, bcnt uint8) error {
   220  	if ln := len(dst); HashSize > ln {
   221  		return fmt.Errorf("Blake Close: dst min length: %d, got %d", HashSize, ln)
   222  	}
   223  
   224  	ptr := ref.ptr
   225  	bln := uint64((ref.ptr << 3) + uintptr(bcnt))
   226  
   227  	tpl := ref.t[0] + bln
   228  	tph := ref.t[1]
   229  
   230  	var buf [BlockSize]uint8
   231  
   232  	{
   233  		off := uint8(0x80) >> bcnt
   234  		buf[ptr] = uint8((bits & -off) | off)
   235  	}
   236  
   237  	if ptr == 0 && bcnt == 0 {
   238  		ref.t[0] = uint64(0xFFFFFFFFFFFFFC00)
   239  		ref.t[1] = uint64(0xFFFFFFFFFFFFFFFF)
   240  	} else if ref.t[0] == 0 {
   241  		ref.t[0] = uint64(0xFFFFFFFFFFFFFC00) + bln
   242  		ref.t[1] = uint64(ref.t[1] - 1)
   243  	} else {
   244  		ref.t[0] -= 1024 - bln
   245  	}
   246  
   247  	if bln <= 894 {
   248  		buf[111] |= 1
   249  
   250  		encUInt64be(buf[112:], tph)
   251  		encUInt64be(buf[120:], tpl)
   252  		ref.Write(buf[ptr:])
   253  	} else {
   254  		ref.Write(buf[ptr:])
   255  
   256  		ref.t[0] = uint64(0xFFFFFFFFFFFFFC00)
   257  		ref.t[1] = uint64(0xFFFFFFFFFFFFFFFF)
   258  
   259  		memset(buf[:112], 0)
   260  		buf[111] = 1
   261  
   262  		encUInt64be(buf[112:], tph)
   263  		encUInt64be(buf[120:], tpl)
   264  		ref.Write(buf[:])
   265  	}
   266  
   267  	for k := uintptr(0); k < 8; k++ {
   268  		encUInt64be(dst[(k<<3):], ref.h[k])
   269  	}
   270  
   271  	ref.Reset()
   272  	return nil
   273  }
   274  
   275  // Size returns the number of bytes Sum will return.
   276  func (*digest) Size() int {
   277  	return HashSize
   278  }
   279  
   280  // BlockSize returns the block size of the hash.
   281  func (*digest) BlockSize() int {
   282  	return int(BlockSize)
   283  }
   284  
   285  ////////////////
   286  
   287  func memset(dst []byte, src byte) {
   288  	for i := range dst {
   289  		dst[i] = src
   290  	}
   291  }
   292  
   293  func decUInt64be(src []byte) uint64 {
   294  	return (uint64(src[0])<<56 |
   295  		uint64(src[1])<<48 |
   296  		uint64(src[2])<<40 |
   297  		uint64(src[3])<<32 |
   298  		uint64(src[4])<<24 |
   299  		uint64(src[5])<<16 |
   300  		uint64(src[6])<<8 |
   301  		uint64(src[7]))
   302  }
   303  
   304  func encUInt64be(dst []byte, src uint64) {
   305  	dst[0] = uint8(src >> 56)
   306  	dst[1] = uint8(src >> 48)
   307  	dst[2] = uint8(src >> 40)
   308  	dst[3] = uint8(src >> 32)
   309  	dst[4] = uint8(src >> 24)
   310  	dst[5] = uint8(src >> 16)
   311  	dst[6] = uint8(src >> 8)
   312  	dst[7] = uint8(src)
   313  }
   314  
   315  ////////////////
   316  
   317  var kInit = [8]uint64{
   318  	uint64(0x6A09E667F3BCC908), uint64(0xBB67AE8584CAA73B),
   319  	uint64(0x3C6EF372FE94F82B), uint64(0xA54FF53A5F1D36F1),
   320  	uint64(0x510E527FADE682D1), uint64(0x9B05688C2B3E6C1F),
   321  	uint64(0x1F83D9ABFB41BD6B), uint64(0x5BE0CD19137E2179),
   322  }
   323  
   324  var kSpec = [16]uint64{
   325  	uint64(0x243F6A8885A308D3), uint64(0x13198A2E03707344),
   326  	uint64(0xA4093822299F31D0), uint64(0x082EFA98EC4E6C89),
   327  	uint64(0x452821E638D01377), uint64(0xBE5466CF34E90C6C),
   328  	uint64(0xC0AC29B7C97C50DD), uint64(0x3F84D5B5B5470917),
   329  	uint64(0x9216D5D98979FB1B), uint64(0xD1310BA698DFB5AC),
   330  	uint64(0x2FFD72DBD01ADFB7), uint64(0xB8E1AFED6A267E96),
   331  	uint64(0xBA7C9045F12C7F99), uint64(0x24A19947B3916CF7),
   332  	uint64(0x0801F2E2858EFC16), uint64(0x636920D871574E69),
   333  }
   334  
   335  var kSigma = [16][16]uint8{
   336  	{0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15},
   337  	{14, 10, 4, 8, 9, 15, 13, 6, 1, 12, 0, 2, 11, 7, 5, 3},
   338  	{11, 8, 12, 0, 5, 2, 15, 13, 10, 14, 3, 6, 7, 1, 9, 4},
   339  	{7, 9, 3, 1, 13, 12, 11, 14, 2, 6, 5, 10, 4, 0, 15, 8},
   340  	{9, 0, 5, 7, 2, 4, 10, 15, 14, 1, 11, 12, 6, 8, 3, 13},
   341  	{2, 12, 6, 10, 0, 11, 8, 3, 4, 13, 7, 5, 15, 14, 1, 9},
   342  	{12, 5, 1, 15, 14, 13, 4, 10, 0, 7, 6, 3, 9, 2, 8, 11},
   343  	{13, 11, 7, 14, 12, 1, 3, 9, 5, 0, 15, 4, 8, 6, 2, 10},
   344  	{6, 15, 14, 9, 11, 3, 0, 8, 12, 2, 13, 7, 1, 4, 10, 5},
   345  	{10, 2, 8, 4, 7, 6, 1, 5, 15, 11, 9, 14, 3, 12, 13, 0},
   346  	{0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15},
   347  	{14, 10, 4, 8, 9, 15, 13, 6, 1, 12, 0, 2, 11, 7, 5, 3},
   348  	{11, 8, 12, 0, 5, 2, 15, 13, 10, 14, 3, 6, 7, 1, 9, 4},
   349  	{7, 9, 3, 1, 13, 12, 11, 14, 2, 6, 5, 10, 4, 0, 15, 8},
   350  	{9, 0, 5, 7, 2, 4, 10, 15, 14, 1, 11, 12, 6, 8, 3, 13},
   351  	{2, 12, 6, 10, 0, 11, 8, 3, 4, 13, 7, 5, 15, 14, 1, 9},
   352  }