// Copyright 2024 The Go Authors. All rights reserved.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.

// Package sha3 implements the SHA-3 hash algorithms and the SHAKE extendable // output functions defined in FIPS 202.
package sha3 import ( ) func init() { crypto.RegisterHash(crypto.SHA3_224, func() hash.Hash { return New224() }) crypto.RegisterHash(crypto.SHA3_256, func() hash.Hash { return New256() }) crypto.RegisterHash(crypto.SHA3_384, func() hash.Hash { return New384() }) crypto.RegisterHash(crypto.SHA3_512, func() hash.Hash { return New512() }) } // Sum224 returns the SHA3-224 hash of data. func ( []byte) [28]byte { var [28]byte := sha3.New224() .Write() .Sum([:0]) return } // Sum256 returns the SHA3-256 hash of data. func ( []byte) [32]byte { var [32]byte := sha3.New256() .Write() .Sum([:0]) return } // Sum384 returns the SHA3-384 hash of data. func ( []byte) [48]byte { var [48]byte := sha3.New384() .Write() .Sum([:0]) return } // Sum512 returns the SHA3-512 hash of data. func ( []byte) [64]byte { var [64]byte := sha3.New512() .Write() .Sum([:0]) return } // SumSHAKE128 applies the SHAKE128 extendable output function to data and // returns an output of the given length in bytes. func ( []byte, int) []byte { // Outline the allocation for up to 256 bits of output to the caller's stack. := make([]byte, 32) return sumSHAKE128(, , ) } func sumSHAKE128(, []byte, int) []byte { if len() < { = make([]byte, ) } else { = [:] } := sha3.NewShake128() .Write() .Read() return } // SumSHAKE256 applies the SHAKE256 extendable output function to data and // returns an output of the given length in bytes. func ( []byte, int) []byte { // Outline the allocation for up to 512 bits of output to the caller's stack. := make([]byte, 64) return sumSHAKE256(, , ) } func sumSHAKE256(, []byte, int) []byte { if len() < { = make([]byte, ) } else { = [:] } := sha3.NewShake256() .Write() .Read() return } // SHA3 is an instance of a SHA-3 hash. It implements [hash.Hash]. type SHA3 struct { s sha3.Digest } // New224 creates a new SHA3-224 hash. func () *SHA3 { return &SHA3{*sha3.New224()} } // New256 creates a new SHA3-256 hash. func () *SHA3 { return &SHA3{*sha3.New256()} } // New384 creates a new SHA3-384 hash. func () *SHA3 { return &SHA3{*sha3.New384()} } // New512 creates a new SHA3-512 hash. func () *SHA3 { return &SHA3{*sha3.New512()} } // Write absorbs more data into the hash's state. func ( *SHA3) ( []byte) ( int, error) { return .s.Write() } // Sum appends the current hash to b and returns the resulting slice. func ( *SHA3) ( []byte) []byte { return .s.Sum() } // Reset resets the hash to its initial state. func ( *SHA3) () { .s.Reset() } // Size returns the number of bytes Sum will produce. func ( *SHA3) () int { return .s.Size() } // BlockSize returns the hash's rate. func ( *SHA3) () int { return .s.BlockSize() } // MarshalBinary implements [encoding.BinaryMarshaler]. func ( *SHA3) () ([]byte, error) { return .s.MarshalBinary() } // AppendBinary implements [encoding.BinaryAppender]. func ( *SHA3) ( []byte) ([]byte, error) { return .s.AppendBinary() } // UnmarshalBinary implements [encoding.BinaryUnmarshaler]. func ( *SHA3) ( []byte) error { return .s.UnmarshalBinary() } // SHAKE is an instance of a SHAKE extendable output function. type SHAKE struct { s sha3.SHAKE } // NewSHAKE128 creates a new SHAKE128 XOF. func () *SHAKE { return &SHAKE{*sha3.NewShake128()} } // NewSHAKE256 creates a new SHAKE256 XOF. func () *SHAKE { return &SHAKE{*sha3.NewShake256()} } // NewCSHAKE128 creates a new cSHAKE128 XOF. // // N is used to define functions based on cSHAKE, it can be empty when plain // cSHAKE is desired. S is a customization byte string used for domain // separation. When N and S are both empty, this is equivalent to NewSHAKE128. func (, []byte) *SHAKE { return &SHAKE{*sha3.NewCShake128(, )} } // NewCSHAKE256 creates a new cSHAKE256 XOF. // // N is used to define functions based on cSHAKE, it can be empty when plain // cSHAKE is desired. S is a customization byte string used for domain // separation. When N and S are both empty, this is equivalent to NewSHAKE256. func (, []byte) *SHAKE { return &SHAKE{*sha3.NewCShake256(, )} } // Write absorbs more data into the XOF's state. // // It panics if any output has already been read. func ( *SHAKE) ( []byte) ( int, error) { return .s.Write() } // Read squeezes more output from the XOF. // // Any call to Write after a call to Read will panic. func ( *SHAKE) ( []byte) ( int, error) { return .s.Read() } // Reset resets the XOF to its initial state. func ( *SHAKE) () { .s.Reset() } // BlockSize returns the rate of the XOF. func ( *SHAKE) () int { return .s.BlockSize() } // MarshalBinary implements [encoding.BinaryMarshaler]. func ( *SHAKE) () ([]byte, error) { return .s.MarshalBinary() } // AppendBinary implements [encoding.BinaryAppender]. func ( *SHAKE) ( []byte) ([]byte, error) { return .s.AppendBinary() } // UnmarshalBinary implements [encoding.BinaryUnmarshaler]. func ( *SHAKE) ( []byte) error { return .s.UnmarshalBinary() }