}
// SHAKE is an instance of a SHAKE extendable output function.
+// The zero value is a usable SHAKE256 hash.
type SHAKE struct {
s sha3.SHAKE
}
+func (s *SHAKE) init() {
+ if s.s.Size() == 0 {
+ *s = *NewSHAKE256()
+ }
+}
+
// NewSHAKE128 creates a new SHAKE128 XOF.
func NewSHAKE128() *SHAKE {
return &SHAKE{*sha3.NewShake128()}
//
// It panics if any output has already been read.
func (s *SHAKE) Write(p []byte) (n int, err error) {
+ s.init()
return s.s.Write(p)
}
//
// Any call to Write after a call to Read will panic.
func (s *SHAKE) Read(p []byte) (n int, err error) {
+ s.init()
return s.s.Read(p)
}
// Reset resets the XOF to its initial state.
func (s *SHAKE) Reset() {
+ s.init()
s.s.Reset()
}
// BlockSize returns the rate of the XOF.
func (s *SHAKE) BlockSize() int {
+ s.init()
return s.s.BlockSize()
}
// MarshalBinary implements [encoding.BinaryMarshaler].
func (s *SHAKE) MarshalBinary() ([]byte, error) {
+ s.init()
return s.s.MarshalBinary()
}
// AppendBinary implements [encoding.BinaryAppender].
func (s *SHAKE) AppendBinary(p []byte) ([]byte, error) {
+ s.init()
return s.s.AppendBinary(p)
}
// UnmarshalBinary implements [encoding.BinaryUnmarshaler].
func (s *SHAKE) UnmarshalBinary(data []byte) error {
+ s.init()
return s.s.UnmarshalBinary(data)
}
defCustomStr string
}{
// NewCSHAKE without customization produces same result as SHAKE
- "SHAKE128": {NewCSHAKE128, "", ""},
- "SHAKE256": {NewCSHAKE256, "", ""},
- "cSHAKE128": {NewCSHAKE128, "CSHAKE128", "CustomString"},
- "cSHAKE256": {NewCSHAKE256, "CSHAKE256", "CustomString"},
+ "SHAKE128": {NewCSHAKE128, "", ""},
+ "SHAKE256": {NewCSHAKE256, "", ""},
+ "cSHAKE128": {NewCSHAKE128, "CSHAKE128", "CustomString"},
+ "cSHAKE256": {NewCSHAKE256, "CSHAKE256", "CustomString"},
+ "SHAKE-Zero": {func(N []byte, S []byte) *SHAKE { return &SHAKE{} }, "", ""},
}
func TestSHA3Hash(t *testing.T) {