...

Source file src/crypto/sha3/sha3.go

Documentation: crypto/sha3

     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  // The zero value is a usable SHA3-256 hash.
   101  type SHA3 struct {
   102  	s sha3.Digest
   103  }
   104  
   105  //go:linkname fips140hash_sha3Unwrap crypto/internal/fips140hash.sha3Unwrap
   106  func fips140hash_sha3Unwrap(s *SHA3) *sha3.Digest {
   107  	s.init()
   108  	return &s.s
   109  }
   110  
   111  // New224 creates a new SHA3-224 hash.
   112  func New224() *SHA3 {
   113  	return &SHA3{*sha3.New224()}
   114  }
   115  
   116  // New256 creates a new SHA3-256 hash.
   117  func New256() *SHA3 {
   118  	return &SHA3{*sha3.New256()}
   119  }
   120  
   121  // New384 creates a new SHA3-384 hash.
   122  func New384() *SHA3 {
   123  	return &SHA3{*sha3.New384()}
   124  }
   125  
   126  // New512 creates a new SHA3-512 hash.
   127  func New512() *SHA3 {
   128  	return &SHA3{*sha3.New512()}
   129  }
   130  
   131  func (s *SHA3) init() {
   132  	if s.s.Size() == 0 {
   133  		*s = *New256()
   134  	}
   135  }
   136  
   137  // Write absorbs more data into the hash's state.
   138  func (s *SHA3) Write(p []byte) (n int, err error) {
   139  	s.init()
   140  	return s.s.Write(p)
   141  }
   142  
   143  // Sum appends the current hash to b and returns the resulting slice.
   144  func (s *SHA3) Sum(b []byte) []byte {
   145  	s.init()
   146  	return s.s.Sum(b)
   147  }
   148  
   149  // Reset resets the hash to its initial state.
   150  func (s *SHA3) Reset() {
   151  	s.init()
   152  	s.s.Reset()
   153  }
   154  
   155  // Size returns the number of bytes Sum will produce.
   156  func (s *SHA3) Size() int {
   157  	s.init()
   158  	return s.s.Size()
   159  }
   160  
   161  // BlockSize returns the hash's rate.
   162  func (s *SHA3) BlockSize() int {
   163  	s.init()
   164  	return s.s.BlockSize()
   165  }
   166  
   167  // MarshalBinary implements [encoding.BinaryMarshaler].
   168  func (s *SHA3) MarshalBinary() ([]byte, error) {
   169  	s.init()
   170  	return s.s.MarshalBinary()
   171  }
   172  
   173  // AppendBinary implements [encoding.BinaryAppender].
   174  func (s *SHA3) AppendBinary(p []byte) ([]byte, error) {
   175  	s.init()
   176  	return s.s.AppendBinary(p)
   177  }
   178  
   179  // UnmarshalBinary implements [encoding.BinaryUnmarshaler].
   180  func (s *SHA3) UnmarshalBinary(data []byte) error {
   181  	s.init()
   182  	return s.s.UnmarshalBinary(data)
   183  }
   184  
   185  // Clone implements [hash.Cloner].
   186  func (d *SHA3) Clone() (hash.Cloner, error) {
   187  	r := *d
   188  	return &r, nil
   189  }
   190  
   191  // SHAKE is an instance of a SHAKE extendable output function.
   192  // The zero value is a usable SHAKE256 hash.
   193  type SHAKE struct {
   194  	s sha3.SHAKE
   195  }
   196  
   197  func (s *SHAKE) init() {
   198  	if s.s.Size() == 0 {
   199  		*s = *NewSHAKE256()
   200  	}
   201  }
   202  
   203  // NewSHAKE128 creates a new SHAKE128 XOF.
   204  func NewSHAKE128() *SHAKE {
   205  	return &SHAKE{*sha3.NewShake128()}
   206  }
   207  
   208  // NewSHAKE256 creates a new SHAKE256 XOF.
   209  func NewSHAKE256() *SHAKE {
   210  	return &SHAKE{*sha3.NewShake256()}
   211  }
   212  
   213  // NewCSHAKE128 creates a new cSHAKE128 XOF.
   214  //
   215  // N is used to define functions based on cSHAKE, it can be empty when plain
   216  // cSHAKE is desired. S is a customization byte string used for domain
   217  // separation. When N and S are both empty, this is equivalent to NewSHAKE128.
   218  func NewCSHAKE128(N, S []byte) *SHAKE {
   219  	return &SHAKE{*sha3.NewCShake128(N, S)}
   220  }
   221  
   222  // NewCSHAKE256 creates a new cSHAKE256 XOF.
   223  //
   224  // N is used to define functions based on cSHAKE, it can be empty when plain
   225  // cSHAKE is desired. S is a customization byte string used for domain
   226  // separation. When N and S are both empty, this is equivalent to NewSHAKE256.
   227  func NewCSHAKE256(N, S []byte) *SHAKE {
   228  	return &SHAKE{*sha3.NewCShake256(N, S)}
   229  }
   230  
   231  // Write absorbs more data into the XOF's state.
   232  //
   233  // It panics if any output has already been read.
   234  func (s *SHAKE) Write(p []byte) (n int, err error) {
   235  	s.init()
   236  	return s.s.Write(p)
   237  }
   238  
   239  // Read squeezes more output from the XOF.
   240  //
   241  // Any call to Write after a call to Read will panic.
   242  func (s *SHAKE) Read(p []byte) (n int, err error) {
   243  	s.init()
   244  	return s.s.Read(p)
   245  }
   246  
   247  // Reset resets the XOF to its initial state.
   248  func (s *SHAKE) Reset() {
   249  	s.init()
   250  	s.s.Reset()
   251  }
   252  
   253  // BlockSize returns the rate of the XOF.
   254  func (s *SHAKE) BlockSize() int {
   255  	s.init()
   256  	return s.s.BlockSize()
   257  }
   258  
   259  // MarshalBinary implements [encoding.BinaryMarshaler].
   260  func (s *SHAKE) MarshalBinary() ([]byte, error) {
   261  	s.init()
   262  	return s.s.MarshalBinary()
   263  }
   264  
   265  // AppendBinary implements [encoding.BinaryAppender].
   266  func (s *SHAKE) AppendBinary(p []byte) ([]byte, error) {
   267  	s.init()
   268  	return s.s.AppendBinary(p)
   269  }
   270  
   271  // UnmarshalBinary implements [encoding.BinaryUnmarshaler].
   272  func (s *SHAKE) UnmarshalBinary(data []byte) error {
   273  	s.init()
   274  	return s.s.UnmarshalBinary(data)
   275  }
   276  

View as plain text