sha3.mx raw

   1  // Copyright 2014 The Go Authors. 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  // Package sha3 implements the SHA-3 fixed-output-length hash functions and
   6  // the SHAKE variable-output-length functions defined by [FIPS 202], as well as
   7  // the cSHAKE extendable-output-length functions defined by [SP 800-185].
   8  //
   9  // [FIPS 202]: https://doi.org/10.6028/NIST.FIPS.202
  10  // [SP 800-185]: https://doi.org/10.6028/NIST.SP.800-185
  11  package sha3
  12  
  13  import (
  14  	"crypto/internal/fips140"
  15  	"crypto/internal/fips140/subtle"
  16  	"errors"
  17  )
  18  
  19  // spongeDirection indicates the direction bytes are flowing through the sponge.
  20  type spongeDirection int
  21  
  22  const (
  23  	// spongeAbsorbing indicates that the sponge is absorbing input.
  24  	spongeAbsorbing spongeDirection = iota
  25  	// spongeSqueezing indicates that the sponge is being squeezed.
  26  	spongeSqueezing
  27  )
  28  
  29  type Digest struct {
  30  	a [1600 / 8]byte // main state of the hash
  31  
  32  	// a[n:rate] is the buffer. If absorbing, it's the remaining space to XOR
  33  	// into before running the permutation. If squeezing, it's the remaining
  34  	// output to produce before running the permutation.
  35  	n, rate int
  36  
  37  	// dsbyte contains the "domain separation" bits and the first bit of
  38  	// the padding. Sections 6.1 and 6.2 of [1] separate the outputs of the
  39  	// SHA-3 and SHAKE functions by appending bitstrings to the message.
  40  	// Using a little-endian bit-ordering convention, these are "01" for SHA-3
  41  	// and "1111" for SHAKE, or 00000010b and 00001111b, respectively. Then the
  42  	// padding rule from section 5.1 is applied to pad the message to a multiple
  43  	// of the rate, which involves adding a "1" bit, zero or more "0" bits, and
  44  	// a final "1" bit. We merge the first "1" bit from the padding into dsbyte,
  45  	// giving 00000110b (0x06) and 00011111b (0x1f).
  46  	// [1] http://csrc.nist.gov/publications/drafts/fips-202/fips_202_draft.pdf
  47  	//     "Draft FIPS 202: SHA-3 Standard: Permutation-Based Hash and
  48  	//      Extendable-Output Functions (May 2014)"
  49  	dsbyte byte
  50  
  51  	outputLen int             // the default output size in bytes
  52  	state     spongeDirection // whether the sponge is absorbing or squeezing
  53  }
  54  
  55  // BlockSize returns the rate of sponge underlying this hash function.
  56  func (d *Digest) BlockSize() int { return d.rate }
  57  
  58  // Size returns the output size of the hash function in bytes.
  59  func (d *Digest) Size() int { return d.outputLen }
  60  
  61  // Reset resets the Digest to its initial state.
  62  func (d *Digest) Reset() {
  63  	// Zero the permutation's state.
  64  	for i := range d.a {
  65  		d.a[i] = 0
  66  	}
  67  	d.state = spongeAbsorbing
  68  	d.n = 0
  69  }
  70  
  71  func (d *Digest) Clone() *Digest {
  72  	ret := *d
  73  	return &ret
  74  }
  75  
  76  // permute applies the KeccakF-1600 permutation.
  77  func (d *Digest) permute() {
  78  	keccakF1600(&d.a)
  79  	d.n = 0
  80  }
  81  
  82  // padAndPermute appends the domain separation bits in dsbyte, applies
  83  // the multi-bitrate 10..1 padding rule, and permutes the state.
  84  func (d *Digest) padAndPermute() {
  85  	// Pad with this instance's domain-separator bits. We know that there's
  86  	// at least one byte of space in the sponge because, if it were full,
  87  	// permute would have been called to empty it. dsbyte also contains the
  88  	// first one bit for the padding. See the comment in the state struct.
  89  	d.a[d.n] ^= d.dsbyte
  90  	// This adds the final one bit for the padding. Because of the way that
  91  	// bits are numbered from the LSB upwards, the final bit is the MSB of
  92  	// the last byte.
  93  	d.a[d.rate-1] ^= 0x80
  94  	// Apply the permutation
  95  	d.permute()
  96  	d.state = spongeSqueezing
  97  }
  98  
  99  // Write absorbs more data into the hash's state.
 100  func (d *Digest) Write(p []byte) (n int, err error) { return d.write(p) }
 101  func (d *Digest) writeGeneric(p []byte) (n int, err error) {
 102  	if d.state != spongeAbsorbing {
 103  		panic("sha3: Write after Read")
 104  	}
 105  
 106  	n = len(p)
 107  
 108  	for len(p) > 0 {
 109  		x := subtle.XORBytes(d.a[d.n:d.rate], d.a[d.n:d.rate], p)
 110  		d.n += x
 111  		p = p[x:]
 112  
 113  		// If the sponge is full, apply the permutation.
 114  		if d.n == d.rate {
 115  			d.permute()
 116  		}
 117  	}
 118  
 119  	return
 120  }
 121  
 122  // read squeezes an arbitrary number of bytes from the sponge.
 123  func (d *Digest) readGeneric(out []byte) (n int, err error) {
 124  	// If we're still absorbing, pad and apply the permutation.
 125  	if d.state == spongeAbsorbing {
 126  		d.padAndPermute()
 127  	}
 128  
 129  	n = len(out)
 130  
 131  	// Now, do the squeezing.
 132  	for len(out) > 0 {
 133  		// Apply the permutation if we've squeezed the sponge dry.
 134  		if d.n == d.rate {
 135  			d.permute()
 136  		}
 137  
 138  		x := copy(out, d.a[d.n:d.rate])
 139  		d.n += x
 140  		out = out[x:]
 141  	}
 142  
 143  	return
 144  }
 145  
 146  // Sum appends the current hash to b and returns the resulting slice.
 147  // It does not change the underlying hash state.
 148  func (d *Digest) Sum(b []byte) []byte {
 149  	fips140.RecordApproved()
 150  	return d.sum(b)
 151  }
 152  
 153  func (d *Digest) sumGeneric(b []byte) []byte {
 154  	if d.state != spongeAbsorbing {
 155  		panic("sha3: Sum after Read")
 156  	}
 157  
 158  	// Make a copy of the original hash so that caller can keep writing
 159  	// and summing.
 160  	dup := d.Clone()
 161  	hash := []byte{:dup.outputLen:64} // explicit cap to allow stack allocation
 162  	dup.read(hash)
 163  	return append(b, hash...)
 164  }
 165  
 166  const (
 167  	magicSHA3   = "sha\x08"
 168  	magicShake  = "sha\x09"
 169  	magicCShake = "sha\x0a"
 170  	magicKeccak = "sha\x0b"
 171  	// magic || rate || main state || n || sponge direction
 172  	marshaledSize = 4 + 1 + 200 + 1 + 1
 173  )
 174  
 175  func (d *Digest) MarshalBinary() ([]byte, error) {
 176  	return d.AppendBinary([]byte{:0:marshaledSize})
 177  }
 178  
 179  func (d *Digest) AppendBinary(b []byte) ([]byte, error) {
 180  	switch d.dsbyte {
 181  	case dsbyteSHA3:
 182  		b = append(b, magicSHA3...)
 183  	case dsbyteShake:
 184  		b = append(b, magicShake...)
 185  	case dsbyteCShake:
 186  		b = append(b, magicCShake...)
 187  	case dsbyteKeccak:
 188  		b = append(b, magicKeccak...)
 189  	default:
 190  		panic("unknown dsbyte")
 191  	}
 192  	// rate is at most 168, and n is at most rate.
 193  	b = append(b, byte(d.rate))
 194  	b = append(b, d.a[:]...)
 195  	b = append(b, byte(d.n), byte(d.state))
 196  	return b, nil
 197  }
 198  
 199  func (d *Digest) UnmarshalBinary(b []byte) error {
 200  	if len(b) != marshaledSize {
 201  		return errors.New("sha3: invalid hash state")
 202  	}
 203  
 204  	magic := b[:len(magicSHA3)]
 205  	b = b[len(magicSHA3):]
 206  	switch {
 207  	case magic == magicSHA3 && d.dsbyte == dsbyteSHA3:
 208  	case magic == magicShake && d.dsbyte == dsbyteShake:
 209  	case magic == magicCShake && d.dsbyte == dsbyteCShake:
 210  	case magic == magicKeccak && d.dsbyte == dsbyteKeccak:
 211  	default:
 212  		return errors.New("sha3: invalid hash state identifier")
 213  	}
 214  
 215  	rate := int(b[0])
 216  	b = b[1:]
 217  	if rate != d.rate {
 218  		return errors.New("sha3: invalid hash state function")
 219  	}
 220  
 221  	copy(d.a[:], b)
 222  	b = b[len(d.a):]
 223  
 224  	n, state := int(b[0]), spongeDirection(b[1])
 225  	if n > d.rate {
 226  		return errors.New("sha3: invalid hash state")
 227  	}
 228  	d.n = n
 229  	if state != spongeAbsorbing && state != spongeSqueezing {
 230  		return errors.New("sha3: invalid hash state")
 231  	}
 232  	d.state = state
 233  
 234  	return nil
 235  }
 236