Export internal state

This commit is contained in:
DataHoarder 2023-05-12 08:42:07 +02:00
parent 7ddddb3a08
commit dde79576dc
Signed by: DataHoarder
SSH key fingerprint: SHA256:OLTRf6Fl87G52SiR7sWLGNzlJt4WOX+tfI2yxo0z7xk
5 changed files with 31 additions and 27 deletions

View file

@ -19,7 +19,7 @@ func New224() hash.Hash {
if h := new224Asm(); h != nil {
return h
}
return &state{rate: 144, outputLen: 28, dsbyte: 0x06}
return &HasherState{rate: 144, outputLen: 28, dsbyte: 0x06}
}
// New256 creates a new SHA3-256 hash.
@ -29,7 +29,7 @@ func New256() hash.Hash {
if h := new256Asm(); h != nil {
return h
}
return &state{rate: 136, outputLen: 32, dsbyte: 0x06}
return &HasherState{rate: 136, outputLen: 32, dsbyte: 0x06}
}
// New384 creates a new SHA3-384 hash.
@ -39,7 +39,7 @@ func New384() hash.Hash {
if h := new384Asm(); h != nil {
return h
}
return &state{rate: 104, outputLen: 48, dsbyte: 0x06}
return &HasherState{rate: 104, outputLen: 48, dsbyte: 0x06}
}
// New512 creates a new SHA3-512 hash.
@ -49,20 +49,24 @@ func New512() hash.Hash {
if h := new512Asm(); h != nil {
return h
}
return &state{rate: 72, outputLen: 64, dsbyte: 0x06}
return &HasherState{rate: 72, outputLen: 64, dsbyte: 0x06}
}
// NewLegacyKeccak256 creates a new Keccak-256 hash.
//
// Only use this function if you require compatibility with an existing cryptosystem
// that uses non-standard padding. All other users should use New256 instead.
func NewLegacyKeccak256() hash.Hash { return &state{rate: 136, outputLen: 32, dsbyte: 0x01} }
func NewLegacyKeccak256() *HasherState {
return &HasherState{rate: 136, outputLen: 32, dsbyte: 0x01}
}
// NewLegacyKeccak512 creates a new Keccak-512 hash.
//
// Only use this function if you require compatibility with an existing cryptosystem
// that uses non-standard padding. All other users should use New512 instead.
func NewLegacyKeccak512() hash.Hash { return &state{rate: 72, outputLen: 64, dsbyte: 0x01} }
func NewLegacyKeccak512() *HasherState {
return &HasherState{rate: 72, outputLen: 64, dsbyte: 0x01}
}
// Sum224 returns the SHA3-224 digest of the data.
func Sum224(data []byte) (digest [28]byte) {

20
sha3.go
View file

@ -20,7 +20,7 @@ const (
maxRate = 168
)
type state struct {
type HasherState struct {
// Generic sponge components.
a [25]uint64 // main state of the hash
buf []byte // points into storage
@ -48,14 +48,14 @@ type state struct {
}
// BlockSize returns the rate of sponge underlying this hash function.
func (d *state) BlockSize() int { return d.rate }
func (d *HasherState) BlockSize() int { return d.rate }
// Size returns the output size of the hash function in bytes.
func (d *state) Size() int { return d.outputLen }
func (d *HasherState) Size() int { return d.outputLen }
// Reset clears the internal state by zeroing the sponge state and
// the byte buffer, and setting Sponge.state to absorbing.
func (d *state) Reset() {
func (d *HasherState) Reset() {
// Zero the permutation's state.
for i := range d.a {
d.a[i] = 0
@ -64,7 +64,7 @@ func (d *state) Reset() {
d.buf = d.storage.asBytes()[:0]
}
func (d *state) clone() *state {
func (d *HasherState) clone() *HasherState {
ret := *d
if ret.state == spongeAbsorbing {
ret.buf = ret.storage.asBytes()[:len(ret.buf)]
@ -77,7 +77,7 @@ func (d *state) clone() *state {
// permute applies the KeccakF-1600 permutation. It handles
// any input-output buffering.
func (d *state) permute() {
func (d *HasherState) permute() {
switch d.state {
case spongeAbsorbing:
// If we're absorbing, we need to xor the input into the state
@ -96,7 +96,7 @@ func (d *state) permute() {
// pads appends the domain separation bits in dsbyte, applies
// the multi-bitrate 10..1 padding rule, and permutes the state.
func (d *state) padAndPermute(dsbyte byte) {
func (d *HasherState) padAndPermute(dsbyte byte) {
if d.buf == nil {
d.buf = d.storage.asBytes()[:0]
}
@ -123,7 +123,7 @@ func (d *state) padAndPermute(dsbyte byte) {
// Write absorbs more data into the hash's state. It produces an error
// if more data is written to the ShakeHash after writing
func (d *state) Write(p []byte) (written int, err error) {
func (d *HasherState) Write(p []byte) (written int, err error) {
if d.state != spongeAbsorbing {
panic("sha3: write to sponge after read")
}
@ -158,7 +158,7 @@ func (d *state) Write(p []byte) (written int, err error) {
}
// Read squeezes an arbitrary number of bytes from the sponge.
func (d *state) Read(out []byte) (n int, err error) {
func (d *HasherState) Read(out []byte) (n int, err error) {
// If we're still absorbing, pad and apply the permutation.
if d.state == spongeAbsorbing {
d.padAndPermute(d.dsbyte)
@ -183,7 +183,7 @@ func (d *state) Read(out []byte) (n int, err error) {
// Sum applies padding to the hash state and then squeezes out the desired
// number of output bytes.
func (d *state) Sum(in []byte) []byte {
func (d *HasherState) Sum(in []byte) []byte {
// Make a copy of the original hash so that caller can keep writing
// and summing.
dup := d.clone()

View file

@ -41,7 +41,7 @@ type ShakeHash interface {
// cSHAKE specific context
type cshakeState struct {
*state // SHA-3 state context and Read/Write operations
*HasherState // SHA-3 state context and Read/Write operations
// initBlock is the cSHAKE specific initialization set of bytes. It is initialized
// by newCShake function and stores concatenation of N followed by S, encoded
@ -82,7 +82,7 @@ func leftEncode(value uint64) []byte {
}
func newCShake(N, S []byte, rate int, dsbyte byte) ShakeHash {
c := cshakeState{state: &state{rate: rate, dsbyte: dsbyte}}
c := cshakeState{HasherState: &HasherState{rate: rate, dsbyte: dsbyte}}
// leftEncode returns max 9 bytes
c.initBlock = make([]byte, 0, 9*2+len(N)+len(S))
@ -96,7 +96,7 @@ func newCShake(N, S []byte, rate int, dsbyte byte) ShakeHash {
// Reset resets the hash to initial state.
func (c *cshakeState) Reset() {
c.state.Reset()
c.HasherState.Reset()
c.Write(bytepad(c.initBlock, c.rate))
}
@ -104,11 +104,11 @@ func (c *cshakeState) Reset() {
func (c *cshakeState) Clone() ShakeHash {
b := make([]byte, len(c.initBlock))
copy(b, c.initBlock)
return &cshakeState{state: c.clone(), initBlock: b}
return &cshakeState{HasherState: c.clone(), initBlock: b}
}
// Clone returns copy of SHAKE context within its current state.
func (c *state) Clone() ShakeHash {
func (c *HasherState) Clone() ShakeHash {
return c.clone()
}
@ -119,7 +119,7 @@ func NewShake128() ShakeHash {
if h := newShake128Asm(); h != nil {
return h
}
return &state{rate: rate128, dsbyte: dsbyteShake}
return &HasherState{rate: rate128, dsbyte: dsbyteShake}
}
// NewShake256 creates a new SHAKE256 variable-output-length ShakeHash.
@ -129,7 +129,7 @@ func NewShake256() ShakeHash {
if h := newShake256Asm(); h != nil {
return h
}
return &state{rate: rate256, dsbyte: dsbyteShake}
return &HasherState{rate: rate256, dsbyte: dsbyteShake}
}
// NewCShake128 creates a new instance of cSHAKE128 variable-output-length ShakeHash,

View file

@ -9,7 +9,7 @@ import "encoding/binary"
// xorInGeneric xors the bytes in buf into the state; it
// makes no non-portable assumptions about memory layout
// or alignment.
func xorInGeneric(d *state, buf []byte) {
func xorInGeneric(d *HasherState, buf []byte) {
n := len(buf) / 8
for i := 0; i < n; i++ {
@ -20,7 +20,7 @@ func xorInGeneric(d *state, buf []byte) {
}
// copyOutGeneric copies uint64s to a byte buffer.
func copyOutGeneric(d *state, b []byte) {
func copyOutGeneric(d *HasherState, b []byte) {
for i := 0; len(b) >= 8; i++ {
binary.LittleEndian.PutUint64(b, d.a[i])
b = b[8:]

View file

@ -19,7 +19,7 @@ func (b *storageBuf) asBytes() *[maxRate]byte {
// xorInUnaligned uses unaligned reads and writes to update d.a to contain d.a
// XOR buf.
func xorInUnaligned(d *state, buf []byte) {
func xorInUnaligned(d *HasherState, buf []byte) {
n := len(buf)
bw := (*[maxRate / 8]uint64)(unsafe.Pointer(&buf[0]))[: n/8 : n/8]
if n >= 72 {
@ -55,7 +55,7 @@ func xorInUnaligned(d *state, buf []byte) {
}
}
func copyOutUnaligned(d *state, buf []byte) {
func copyOutUnaligned(d *HasherState, buf []byte) {
ab := (*[maxRate]uint8)(unsafe.Pointer(&d.a[0]))
copy(buf, ab[:])
}