Source file src/crypto/sha3/sha3.go

     1  // Copyright 2024 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 hash algorithms and the SHAKE extendable
     6  // output functions defined in FIPS 202.
     7  package sha3
     8  
     9  import (
    10  	"crypto"
    11  	"crypto/internal/fips140/sha3"
    12  	"hash"
    13  	_ "unsafe"
    14  )
    15  
    16  func init() {
    17  	crypto.RegisterHash(crypto.SHA3_224, func() hash.Hash { return New224() })
    18  	crypto.RegisterHash(crypto.SHA3_256, func() hash.Hash { return New256() })
    19  	crypto.RegisterHash(crypto.SHA3_384, func() hash.Hash { return New384() })
    20  	crypto.RegisterHash(crypto.SHA3_512, func() hash.Hash { return New512() })
    21  }
    22  
    23  // Sum224 returns the SHA3-224 hash of data.
    24  func Sum224(data []byte) [28]byte {
    25  	var out [28]byte
    26  	h := sha3.New224()
    27  	h.Write(data)
    28  	h.Sum(out[:0])
    29  	return out
    30  }
    31  
    32  // Sum256 returns the SHA3-256 hash of data.
    33  func Sum256(data []byte) [32]byte {
    34  	var out [32]byte
    35  	h := sha3.New256()
    36  	h.Write(data)
    37  	h.Sum(out[:0])
    38  	return out
    39  }
    40  
    41  // Sum384 returns the SHA3-384 hash of data.
    42  func Sum384(data []byte) [48]byte {
    43  	var out [48]byte
    44  	h := sha3.New384()
    45  	h.Write(data)
    46  	h.Sum(out[:0])
    47  	return out
    48  }
    49  
    50  // Sum512 returns the SHA3-512 hash of data.
    51  func Sum512(data []byte) [64]byte {
    52  	var out [64]byte
    53  	h := sha3.New512()
    54  	h.Write(data)
    55  	h.Sum(out[:0])
    56  	return out
    57  }
    58  
    59  // SumSHAKE128 applies the SHAKE128 extendable output function to data and
    60  // returns an output of the given length in bytes.
    61  func SumSHAKE128(data []byte, length int) []byte {
    62  	// Outline the allocation for up to 256 bits of output to the caller's stack.
    63  	out := make([]byte, 32)
    64  	return sumSHAKE128(out, data, length)
    65  }
    66  
    67  func sumSHAKE128(out, data []byte, length int) []byte {
    68  	if len(out) < length {
    69  		out = make([]byte, length)
    70  	} else {
    71  		out = out[:length]
    72  	}
    73  	h := sha3.NewShake128()
    74  	h.Write(data)
    75  	h.Read(out)
    76  	return out
    77  }
    78  
    79  // SumSHAKE256 applies the SHAKE256 extendable output function to data and
    80  // returns an output of the given length in bytes.
    81  func SumSHAKE256(data []byte, length int) []byte {
    82  	// Outline the allocation for up to 512 bits of output to the caller's stack.
    83  	out := make([]byte, 64)
    84  	return sumSHAKE256(out, data, length)
    85  }
    86  
    87  func sumSHAKE256(out, data []byte, length int) []byte {
    88  	if len(out) < length {
    89  		out = make([]byte, length)
    90  	} else {
    91  		out = out[:length]
    92  	}
    93  	h := sha3.NewShake256()
    94  	h.Write(data)
    95  	h.Read(out)
    96  	return out
    97  }
    98  
    99  // SHA3 is an instance of a SHA-3 hash. It implements [hash.Hash].
   100  type SHA3 struct {
   101  	s sha3.Digest
   102  }
   103  
   104  //go:linkname fips140hash_sha3Unwrap crypto/internal/fips140hash.sha3Unwrap
   105  func fips140hash_sha3Unwrap(sha3 *SHA3) *sha3.Digest {
   106  	return &sha3.s
   107  }
   108  
   109  // New224 creates a new SHA3-224 hash.
   110  func New224() *SHA3 {
   111  	return &SHA3{*sha3.New224()}
   112  }
   113  
   114  // New256 creates a new SHA3-256 hash.
   115  func New256() *SHA3 {
   116  	return &SHA3{*sha3.New256()}
   117  }
   118  
   119  // New384 creates a new SHA3-384 hash.
   120  func New384() *SHA3 {
   121  	return &SHA3{*sha3.New384()}
   122  }
   123  
   124  // New512 creates a new SHA3-512 hash.
   125  func New512() *SHA3 {
   126  	return &SHA3{*sha3.New512()}
   127  }
   128  
   129  // Write absorbs more data into the hash's state.
   130  func (s *SHA3) Write(p []byte) (n int, err error) {
   131  	return s.s.Write(p)
   132  }
   133  
   134  // Sum appends the current hash to b and returns the resulting slice.
   135  func (s *SHA3) Sum(b []byte) []byte {
   136  	return s.s.Sum(b)
   137  }
   138  
   139  // Reset resets the hash to its initial state.
   140  func (s *SHA3) Reset() {
   141  	s.s.Reset()
   142  }
   143  
   144  // Size returns the number of bytes Sum will produce.
   145  func (s *SHA3) Size() int {
   146  	return s.s.Size()
   147  }
   148  
   149  // BlockSize returns the hash's rate.
   150  func (s *SHA3) BlockSize() int {
   151  	return s.s.BlockSize()
   152  }
   153  
   154  // MarshalBinary implements [encoding.BinaryMarshaler].
   155  func (s *SHA3) MarshalBinary() ([]byte, error) {
   156  	return s.s.MarshalBinary()
   157  }
   158  
   159  // AppendBinary implements [encoding.BinaryAppender].
   160  func (s *SHA3) AppendBinary(p []byte) ([]byte, error) {
   161  	return s.s.AppendBinary(p)
   162  }
   163  
   164  // UnmarshalBinary implements [encoding.BinaryUnmarshaler].
   165  func (s *SHA3) UnmarshalBinary(data []byte) error {
   166  	return s.s.UnmarshalBinary(data)
   167  }
   168  
   169  // SHAKE is an instance of a SHAKE extendable output function.
   170  type SHAKE struct {
   171  	s sha3.SHAKE
   172  }
   173  
   174  // NewSHAKE128 creates a new SHAKE128 XOF.
   175  func NewSHAKE128() *SHAKE {
   176  	return &SHAKE{*sha3.NewShake128()}
   177  }
   178  
   179  // NewSHAKE256 creates a new SHAKE256 XOF.
   180  func NewSHAKE256() *SHAKE {
   181  	return &SHAKE{*sha3.NewShake256()}
   182  }
   183  
   184  // NewCSHAKE128 creates a new cSHAKE128 XOF.
   185  //
   186  // N is used to define functions based on cSHAKE, it can be empty when plain
   187  // cSHAKE is desired. S is a customization byte string used for domain
   188  // separation. When N and S are both empty, this is equivalent to NewSHAKE128.
   189  func NewCSHAKE128(N, S []byte) *SHAKE {
   190  	return &SHAKE{*sha3.NewCShake128(N, S)}
   191  }
   192  
   193  // NewCSHAKE256 creates a new cSHAKE256 XOF.
   194  //
   195  // N is used to define functions based on cSHAKE, it can be empty when plain
   196  // cSHAKE is desired. S is a customization byte string used for domain
   197  // separation. When N and S are both empty, this is equivalent to NewSHAKE256.
   198  func NewCSHAKE256(N, S []byte) *SHAKE {
   199  	return &SHAKE{*sha3.NewCShake256(N, S)}
   200  }
   201  
   202  // Write absorbs more data into the XOF's state.
   203  //
   204  // It panics if any output has already been read.
   205  func (s *SHAKE) Write(p []byte) (n int, err error) {
   206  	return s.s.Write(p)
   207  }
   208  
   209  // Read squeezes more output from the XOF.
   210  //
   211  // Any call to Write after a call to Read will panic.
   212  func (s *SHAKE) Read(p []byte) (n int, err error) {
   213  	return s.s.Read(p)
   214  }
   215  
   216  // Reset resets the XOF to its initial state.
   217  func (s *SHAKE) Reset() {
   218  	s.s.Reset()
   219  }
   220  
   221  // BlockSize returns the rate of the XOF.
   222  func (s *SHAKE) BlockSize() int {
   223  	return s.s.BlockSize()
   224  }
   225  
   226  // MarshalBinary implements [encoding.BinaryMarshaler].
   227  func (s *SHAKE) MarshalBinary() ([]byte, error) {
   228  	return s.s.MarshalBinary()
   229  }
   230  
   231  // AppendBinary implements [encoding.BinaryAppender].
   232  func (s *SHAKE) AppendBinary(p []byte) ([]byte, error) {
   233  	return s.s.AppendBinary(p)
   234  }
   235  
   236  // UnmarshalBinary implements [encoding.BinaryUnmarshaler].
   237  func (s *SHAKE) UnmarshalBinary(data []byte) error {
   238  	return s.s.UnmarshalBinary(data)
   239  }
   240  

View as plain text