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

View as plain text