diff --git a/hashes.go b/hashes.go index 0d8043f..b9a9018 100644 --- a/hashes.go +++ b/hashes.go @@ -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) { diff --git a/sha3.go b/sha3.go index fa182be..d5a5770 100644 --- a/sha3.go +++ b/sha3.go @@ -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() diff --git a/shake.go b/shake.go index d7be295..90676b6 100644 --- a/shake.go +++ b/shake.go @@ -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, diff --git a/xor_generic.go b/xor_generic.go index 8d94771..4631d7d 100644 --- a/xor_generic.go +++ b/xor_generic.go @@ -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:] diff --git a/xor_unaligned.go b/xor_unaligned.go index 1ce6062..7e329ae 100644 --- a/xor_unaligned.go +++ b/xor_unaligned.go @@ -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[:]) }