github.com/cloudflare/circl@v1.5.0/internal/sha3/shake.go (about)

     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
     6  
     7  // This file defines the ShakeHash interface, and provides
     8  // functions for creating SHAKE and cSHAKE instances, as well as utility
     9  // functions for hashing bytes to arbitrary-length output.
    10  //
    11  //
    12  // SHAKE implementation is based on FIPS PUB 202 [1]
    13  // cSHAKE implementations is based on NIST SP 800-185 [2]
    14  //
    15  // [1] https://nvlpubs.nist.gov/nistpubs/FIPS/NIST.FIPS.202.pdf
    16  // [2] https://doi.org/10.6028/NIST.SP.800-185
    17  
    18  import (
    19  	"io"
    20  )
    21  
    22  // ShakeHash defines the interface to hash functions that
    23  // support arbitrary-length output.
    24  type ShakeHash interface {
    25  	// Write absorbs more data into the hash's state. It panics if input is
    26  	// written to it after output has been read from it.
    27  	io.Writer
    28  
    29  	// Read reads more output from the hash; reading affects the hash's
    30  	// state. (ShakeHash.Read is thus very different from Hash.Sum)
    31  	// It never returns an error.
    32  	io.Reader
    33  
    34  	// Clone returns a copy of the ShakeHash in its current state.
    35  	Clone() ShakeHash
    36  
    37  	// Reset resets the ShakeHash to its initial state.
    38  	Reset()
    39  }
    40  
    41  // Consts for configuring initial SHA-3 state
    42  const (
    43  	dsbyteShake = 0x1f
    44  	rate128     = 168
    45  	rate256     = 136
    46  )
    47  
    48  // Clone returns copy of SHAKE context within its current state.
    49  func (d *State) Clone() ShakeHash {
    50  	return d.clone()
    51  }
    52  
    53  // NewShake128 creates a new SHAKE128 variable-output-length ShakeHash.
    54  // Its generic security strength is 128 bits against all attacks if at
    55  // least 32 bytes of its output are used.
    56  func NewShake128() State {
    57  	return State{rate: rate128, dsbyte: dsbyteShake}
    58  }
    59  
    60  // NewTurboShake128 creates a new TurboSHAKE128 variable-output-length ShakeHash.
    61  // Its generic security strength is 128 bits against all attacks if at
    62  // least 32 bytes of its output are used.
    63  // D is the domain separation byte and must be between 0x01 and 0x7f inclusive.
    64  func NewTurboShake128(D byte) State {
    65  	if D == 0 || D > 0x7f {
    66  		panic("turboshake: D out of range")
    67  	}
    68  	return State{rate: rate128, dsbyte: D, turbo: true}
    69  }
    70  
    71  // NewShake256 creates a new SHAKE256 variable-output-length ShakeHash.
    72  // Its generic security strength is 256 bits against all attacks if
    73  // at least 64 bytes of its output are used.
    74  func NewShake256() State {
    75  	return State{rate: rate256, dsbyte: dsbyteShake}
    76  }
    77  
    78  // NewTurboShake256 creates a new TurboSHAKE256 variable-output-length ShakeHash.
    79  // Its generic security strength is 256 bits against all attacks if
    80  // at least 64 bytes of its output are used.
    81  // D is the domain separation byte and must be between 0x01 and 0x7f inclusive.
    82  func NewTurboShake256(D byte) State {
    83  	if D == 0 || D > 0x7f {
    84  		panic("turboshake: D out of range")
    85  	}
    86  	return State{rate: rate256, dsbyte: D, turbo: true}
    87  }
    88  
    89  // ShakeSum128 writes an arbitrary-length digest of data into hash.
    90  func ShakeSum128(hash, data []byte) {
    91  	h := NewShake128()
    92  	_, _ = h.Write(data)
    93  	_, _ = h.Read(hash)
    94  }
    95  
    96  // ShakeSum256 writes an arbitrary-length digest of data into hash.
    97  func ShakeSum256(hash, data []byte) {
    98  	h := NewShake256()
    99  	_, _ = h.Write(data)
   100  	_, _ = h.Read(hash)
   101  }
   102  
   103  // TurboShakeSum128 writes an arbitrary-length digest of data into hash.
   104  func TurboShakeSum128(hash, data []byte, D byte) {
   105  	h := NewTurboShake128(D)
   106  	_, _ = h.Write(data)
   107  	_, _ = h.Read(hash)
   108  }
   109  
   110  // TurboShakeSum256 writes an arbitrary-length digest of data into hash.
   111  func TurboShakeSum256(hash, data []byte, D byte) {
   112  	h := NewTurboShake256(D)
   113  	_, _ = h.Write(data)
   114  	_, _ = h.Read(hash)
   115  }
   116  
   117  func (d *State) SwitchDS(D byte) {
   118  	d.dsbyte = D
   119  }