aboutsummaryrefslogtreecommitdiff
path: root/sha3/shake.go
diff options
context:
space:
mode:
authorMatthew Dempsky <mdempsky@google.com>2023-09-09 18:06:46 -0700
committerGopher Robot <gobot@golang.org>2023-09-10 18:25:15 +0000
commit3f0842a46434ea6f56bf6e684c2b83d90e9cff07 (patch)
tree8fe050a8c6dd303fd8cdfc140af062c25ae762f1 /sha3/shake.go
parente90f1e17ee2ffe351a8295e8ae8b66afda2969c6 (diff)
downloadgo-x-crypto-3f0842a46434ea6f56bf6e684c2b83d90e9cff07.tar.xz
sha3: have ShakeHash extend hash.Hash
Package sha3 recommends the SHAKE functions for new uses, but this is currently somewhat inconvenient because ShakeHash does not implement hash.Hash. This is understandable, as SHAKE supports arbitrary-length outputs whereas hash.Hash only supports fixed-length outputs. But there's a natural fixed-length output to provide: the minimum output that still provides SHAKE's full-strength generic security. While here, tweak Sum so that its temporary buffer can be stack allocated. Also, tweak the panic message in Write so that the error text is more readily understandable to Go programmers without needing to be familiar with crypto jargon, and add a similar check in Sum. Change-Id: Icf037d3990a71de5630f8825606614443f8c5245 Reviewed-on: https://go-review.googlesource.com/c/crypto/+/526937 LUCI-TryBot-Result: Go LUCI <golang-scoped@luci-project-accounts.iam.gserviceaccount.com> Reviewed-by: Adam Langley <agl@google.com> Auto-Submit: Matthew Dempsky <mdempsky@google.com>
Diffstat (limited to 'sha3/shake.go')
-rw-r--r--sha3/shake.go29
1 files changed, 14 insertions, 15 deletions
diff --git a/sha3/shake.go b/sha3/shake.go
index d7be295..bb69984 100644
--- a/sha3/shake.go
+++ b/sha3/shake.go
@@ -17,26 +17,25 @@ package sha3
import (
"encoding/binary"
+ "hash"
"io"
)
-// ShakeHash defines the interface to hash functions that
-// support arbitrary-length output.
+// ShakeHash defines the interface to hash functions that support
+// arbitrary-length output. When used as a plain [hash.Hash], it
+// produces minimum-length outputs that provide full-strength generic
+// security.
type ShakeHash interface {
- // Write absorbs more data into the hash's state. It panics if input is
- // written to it after output has been read from it.
- io.Writer
+ hash.Hash
// Read reads more output from the hash; reading affects the hash's
// state. (ShakeHash.Read is thus very different from Hash.Sum)
- // It never returns an error.
+ // It never returns an error, but subsequent calls to Write or Sum
+ // will panic.
io.Reader
// Clone returns a copy of the ShakeHash in its current state.
Clone() ShakeHash
-
- // Reset resets the ShakeHash to its initial state.
- Reset()
}
// cSHAKE specific context
@@ -81,8 +80,8 @@ func leftEncode(value uint64) []byte {
return b[i-1:]
}
-func newCShake(N, S []byte, rate int, dsbyte byte) ShakeHash {
- c := cshakeState{state: &state{rate: rate, dsbyte: dsbyte}}
+func newCShake(N, S []byte, rate, outputLen int, dsbyte byte) ShakeHash {
+ c := cshakeState{state: &state{rate: rate, outputLen: outputLen, dsbyte: dsbyte}}
// leftEncode returns max 9 bytes
c.initBlock = make([]byte, 0, 9*2+len(N)+len(S))
@@ -119,7 +118,7 @@ func NewShake128() ShakeHash {
if h := newShake128Asm(); h != nil {
return h
}
- return &state{rate: rate128, dsbyte: dsbyteShake}
+ return &state{rate: rate128, outputLen: 32, dsbyte: dsbyteShake}
}
// NewShake256 creates a new SHAKE256 variable-output-length ShakeHash.
@@ -129,7 +128,7 @@ func NewShake256() ShakeHash {
if h := newShake256Asm(); h != nil {
return h
}
- return &state{rate: rate256, dsbyte: dsbyteShake}
+ return &state{rate: rate256, outputLen: 64, dsbyte: dsbyteShake}
}
// NewCShake128 creates a new instance of cSHAKE128 variable-output-length ShakeHash,
@@ -142,7 +141,7 @@ func NewCShake128(N, S []byte) ShakeHash {
if len(N) == 0 && len(S) == 0 {
return NewShake128()
}
- return newCShake(N, S, rate128, dsbyteCShake)
+ return newCShake(N, S, rate128, 32, dsbyteCShake)
}
// NewCShake256 creates a new instance of cSHAKE256 variable-output-length ShakeHash,
@@ -155,7 +154,7 @@ func NewCShake256(N, S []byte) ShakeHash {
if len(N) == 0 && len(S) == 0 {
return NewShake256()
}
- return newCShake(N, S, rate256, dsbyteCShake)
+ return newCShake(N, S, rate256, 64, dsbyteCShake)
}
// ShakeSum128 writes an arbitrary-length digest of data into hash.