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  // Clone implements [hash.Cloner].
   170  func (d *SHA3) Clone() (hash.Cloner, error) {
   171  	r := *d
   172  	return &r, nil
   173  }
   174  
   175  // SHAKE is an instance of a SHAKE extendable output function.
   176  type SHAKE struct {
   177  	s sha3.SHAKE
   178  }
   179  
   180  // NewSHAKE128 creates a new SHAKE128 XOF.
   181  func NewSHAKE128() *SHAKE {
   182  	return &SHAKE{*sha3.NewShake128()}
   183  }
   184  
   185  // NewSHAKE256 creates a new SHAKE256 XOF.
   186  func NewSHAKE256() *SHAKE {
   187  	return &SHAKE{*sha3.NewShake256()}
   188  }
   189  
   190  // NewCSHAKE128 creates a new cSHAKE128 XOF.
   191  //
   192  // N is used to define functions based on cSHAKE, it can be empty when plain
   193  // cSHAKE is desired. S is a customization byte string used for domain
   194  // separation. When N and S are both empty, this is equivalent to NewSHAKE128.
   195  func NewCSHAKE128(N, S []byte) *SHAKE {
   196  	return &SHAKE{*sha3.NewCShake128(N, S)}
   197  }
   198  
   199  // NewCSHAKE256 creates a new cSHAKE256 XOF.
   200  //
   201  // N is used to define functions based on cSHAKE, it can be empty when plain
   202  // cSHAKE is desired. S is a customization byte string used for domain
   203  // separation. When N and S are both empty, this is equivalent to NewSHAKE256.
   204  func NewCSHAKE256(N, S []byte) *SHAKE {
   205  	return &SHAKE{*sha3.NewCShake256(N, S)}
   206  }
   207  
   208  // Write absorbs more data into the XOF's state.
   209  //
   210  // It panics if any output has already been read.
   211  func (s *SHAKE) Write(p []byte) (n int, err error) {
   212  	return s.s.Write(p)
   213  }
   214  
   215  // Read squeezes more output from the XOF.
   216  //
   217  // Any call to Write after a call to Read will panic.
   218  func (s *SHAKE) Read(p []byte) (n int, err error) {
   219  	return s.s.Read(p)
   220  }
   221  
   222  // Reset resets the XOF to its initial state.
   223  func (s *SHAKE) Reset() {
   224  	s.s.Reset()
   225  }
   226  
   227  // BlockSize returns the rate of the XOF.
   228  func (s *SHAKE) BlockSize() int {
   229  	return s.s.BlockSize()
   230  }
   231  
   232  // MarshalBinary implements [encoding.BinaryMarshaler].
   233  func (s *SHAKE) MarshalBinary() ([]byte, error) {
   234  	return s.s.MarshalBinary()
   235  }
   236  
   237  // AppendBinary implements [encoding.BinaryAppender].
   238  func (s *SHAKE) AppendBinary(p []byte) ([]byte, error) {
   239  	return s.s.AppendBinary(p)
   240  }
   241  
   242  // UnmarshalBinary implements [encoding.BinaryUnmarshaler].
   243  func (s *SHAKE) UnmarshalBinary(data []byte) error {
   244  	return s.s.UnmarshalBinary(data)
   245  }
   246  

View as plain text