github.com/turingchain2020/turingchain@v1.1.21/common/crypto/sha3/sha3.go (about)

     1  // Copyright Turing Corp. 2018 All Rights Reserved.
     2  // Use of this source code is governed by a BSD-style
     3  // license that can be found in the LICENSE file.
     4  
     5  // Copyright 2014 The Go Authors. All rights reserved.
     6  // Use of this source code is governed by a BSD-style
     7  // license that can be found in the LICENSE file.
     8  
     9  package sha3
    10  
    11  // spongeDirection indicates the direction bytes are flowing through the sponge.
    12  type spongeDirection int
    13  
    14  const (
    15  	// spongeAbsorbing indicates that the sponge is absorbing input.
    16  	spongeAbsorbing spongeDirection = iota
    17  	// spongeSqueezing indicates that the sponge is being squeezed.
    18  	spongeSqueezing
    19  )
    20  
    21  const (
    22  	// maxRate is the maximum size of the internal buffer. SHAKE-256
    23  	// currently needs the largest buffer.
    24  	maxRate = 168
    25  )
    26  
    27  type state struct {
    28  	// Generic sponge components.
    29  	a    [25]uint64 // main state of the hash
    30  	buf  []byte     // points into storage
    31  	rate int        // the number of bytes of state to use
    32  
    33  	// dsbyte contains the "domain separation" bits and the first bit of
    34  	// the padding. Sections 6.1 and 6.2 of [1] separate the outputs of the
    35  	// SHA-3 and SHAKE functions by appending bitstrings to the message.
    36  	// Using a little-endian bit-ordering convention, these are "01" for SHA-3
    37  	// and "1111" for SHAKE, or 00000010b and 00001111b, respectively. Then the
    38  	// padding rule from section 5.1 is applied to pad the message to a multiple
    39  	// of the rate, which involves adding a "1" bit, zero or more "0" bits, and
    40  	// a final "1" bit. We merge the first "1" bit from the padding into dsbyte,
    41  	// giving 00000110b (0x06) and 00011111b (0x1f).
    42  	// [1] http://csrc.nist.gov/publications/drafts/fips-202/fips_202_draft.pdf
    43  	//     "Draft FIPS 202: SHA-3 Standard: Permutation-Based Hash and
    44  	//      Extendable-Output Functions (May 2014)"
    45  	dsbyte  byte
    46  	storage [maxRate]byte
    47  
    48  	// Specific to SHA-3 and SHAKE.
    49  	outputLen int             // the default output size in bytes
    50  	state     spongeDirection // whether the sponge is absorbing or squeezing
    51  }
    52  
    53  // BlockSize returns the rate of sponge underlying this hash function.
    54  func (d *state) BlockSize() int { return d.rate }
    55  
    56  // Size returns the output size of the hash function in bytes.
    57  func (d *state) Size() int { return d.outputLen }
    58  
    59  // Reset clears the internal state by zeroing the sponge state and
    60  // the byte buffer, and setting Sponge.state to absorbing.
    61  func (d *state) Reset() {
    62  	// Zero the permutation's state.
    63  	for i := range d.a {
    64  		d.a[i] = 0
    65  	}
    66  	d.state = spongeAbsorbing
    67  	d.buf = d.storage[:0]
    68  }
    69  
    70  func (d *state) clone() *state {
    71  	ret := *d
    72  	if ret.state == spongeAbsorbing {
    73  		ret.buf = ret.storage[:len(ret.buf)]
    74  	} else {
    75  		ret.buf = ret.storage[d.rate-cap(d.buf) : d.rate]
    76  	}
    77  
    78  	return &ret
    79  }
    80  
    81  // permute applies the KeccakF-1600 permutation. It handles
    82  // any input-output buffering.
    83  func (d *state) permute() {
    84  	switch d.state {
    85  	case spongeAbsorbing:
    86  		// If we're absorbing, we need to xor the input into the state
    87  		// before applying the permutation.
    88  		xorIn(d, d.buf)
    89  		d.buf = d.storage[:0]
    90  		keccakF1600(&d.a)
    91  	case spongeSqueezing:
    92  		// If we're squeezing, we need to apply the permutatin before
    93  		// copying more output.
    94  		keccakF1600(&d.a)
    95  		d.buf = d.storage[:d.rate]
    96  		copyOut(d, d.buf)
    97  	}
    98  }
    99  
   100  // pads appends the domain separation bits in dsbyte, applies
   101  // the multi-bitrate 10..1 padding rule, and permutes the state.
   102  func (d *state) padAndPermute(dsbyte byte) {
   103  	if d.buf == nil {
   104  		d.buf = d.storage[:0]
   105  	}
   106  	// Pad with this instance's domain-separator bits. We know that there's
   107  	// at least one byte of space in d.buf because, if it were full,
   108  	// permute would have been called to empty it. dsbyte also contains the
   109  	// first one bit for the padding. See the comment in the state struct.
   110  	d.buf = append(d.buf, dsbyte)
   111  	zerosStart := len(d.buf)
   112  	d.buf = d.storage[:d.rate]
   113  	for i := zerosStart; i < d.rate; i++ {
   114  		d.buf[i] = 0
   115  	}
   116  	// This adds the final one bit for the padding. Because of the way that
   117  	// bits are numbered from the LSB upwards, the final bit is the MSB of
   118  	// the last byte.
   119  	d.buf[d.rate-1] ^= 0x80
   120  	// Apply the permutation
   121  	d.permute()
   122  	d.state = spongeSqueezing
   123  	d.buf = d.storage[:d.rate]
   124  	copyOut(d, d.buf)
   125  }
   126  
   127  // Write absorbs more data into the hash's state. It produces an error
   128  // if more data is written to the ShakeHash after writing
   129  func (d *state) Write(p []byte) (written int, err error) {
   130  	if d.state != spongeAbsorbing {
   131  		panic("sha3: write to sponge after read")
   132  	}
   133  	if d.buf == nil {
   134  		d.buf = d.storage[:0]
   135  	}
   136  	written = len(p)
   137  
   138  	for len(p) > 0 {
   139  		if len(d.buf) == 0 && len(p) >= d.rate {
   140  			// The fast path; absorb a full "rate" bytes of input and apply the permutation.
   141  			xorIn(d, p[:d.rate])
   142  			p = p[d.rate:]
   143  			keccakF1600(&d.a)
   144  		} else {
   145  			// The slow path; buffer the input until we can fill the sponge, and then xor it in.
   146  			todo := d.rate - len(d.buf)
   147  			if todo > len(p) {
   148  				todo = len(p)
   149  			}
   150  			d.buf = append(d.buf, p[:todo]...)
   151  			p = p[todo:]
   152  
   153  			// If the sponge is full, apply the permutation.
   154  			if len(d.buf) == d.rate {
   155  				d.permute()
   156  			}
   157  		}
   158  	}
   159  
   160  	return
   161  }
   162  
   163  // Read squeezes an arbitrary number of bytes from the sponge.
   164  func (d *state) Read(out []byte) (n int, err error) {
   165  	// If we're still absorbing, pad and apply the permutation.
   166  	if d.state == spongeAbsorbing {
   167  		d.padAndPermute(d.dsbyte)
   168  	}
   169  
   170  	n = len(out)
   171  
   172  	// Now, do the squeezing.
   173  	for len(out) > 0 {
   174  		n := copy(out, d.buf)
   175  		d.buf = d.buf[n:]
   176  		out = out[n:]
   177  
   178  		// Apply the permutation if we've squeezed the sponge dry.
   179  		if len(d.buf) == 0 {
   180  			d.permute()
   181  		}
   182  	}
   183  
   184  	return
   185  }
   186  
   187  // Sum applies padding to the hash state and then squeezes out the desired
   188  // number of output bytes.
   189  func (d *state) Sum(in []byte) []byte {
   190  	// Make a copy of the original hash so that caller can keep writing
   191  	// and summing.
   192  	dup := d.clone()
   193  	hash := make([]byte, dup.outputLen)
   194  	dup.Read(hash)
   195  	return append(in, hash...)
   196  }