Export internal state
This commit is contained in:
parent
7ddddb3a08
commit
dde79576dc
16
hashes.go
16
hashes.go
|
@ -19,7 +19,7 @@ func New224() hash.Hash {
|
||||||
if h := new224Asm(); h != nil {
|
if h := new224Asm(); h != nil {
|
||||||
return h
|
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.
|
// New256 creates a new SHA3-256 hash.
|
||||||
|
@ -29,7 +29,7 @@ func New256() hash.Hash {
|
||||||
if h := new256Asm(); h != nil {
|
if h := new256Asm(); h != nil {
|
||||||
return h
|
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.
|
// New384 creates a new SHA3-384 hash.
|
||||||
|
@ -39,7 +39,7 @@ func New384() hash.Hash {
|
||||||
if h := new384Asm(); h != nil {
|
if h := new384Asm(); h != nil {
|
||||||
return h
|
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.
|
// New512 creates a new SHA3-512 hash.
|
||||||
|
@ -49,20 +49,24 @@ func New512() hash.Hash {
|
||||||
if h := new512Asm(); h != nil {
|
if h := new512Asm(); h != nil {
|
||||||
return h
|
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.
|
// NewLegacyKeccak256 creates a new Keccak-256 hash.
|
||||||
//
|
//
|
||||||
// Only use this function if you require compatibility with an existing cryptosystem
|
// Only use this function if you require compatibility with an existing cryptosystem
|
||||||
// that uses non-standard padding. All other users should use New256 instead.
|
// 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.
|
// NewLegacyKeccak512 creates a new Keccak-512 hash.
|
||||||
//
|
//
|
||||||
// Only use this function if you require compatibility with an existing cryptosystem
|
// Only use this function if you require compatibility with an existing cryptosystem
|
||||||
// that uses non-standard padding. All other users should use New512 instead.
|
// 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.
|
// Sum224 returns the SHA3-224 digest of the data.
|
||||||
func Sum224(data []byte) (digest [28]byte) {
|
func Sum224(data []byte) (digest [28]byte) {
|
||||||
|
|
20
sha3.go
20
sha3.go
|
@ -20,7 +20,7 @@ const (
|
||||||
maxRate = 168
|
maxRate = 168
|
||||||
)
|
)
|
||||||
|
|
||||||
type state struct {
|
type HasherState struct {
|
||||||
// Generic sponge components.
|
// Generic sponge components.
|
||||||
a [25]uint64 // main state of the hash
|
a [25]uint64 // main state of the hash
|
||||||
buf []byte // points into storage
|
buf []byte // points into storage
|
||||||
|
@ -48,14 +48,14 @@ type state struct {
|
||||||
}
|
}
|
||||||
|
|
||||||
// BlockSize returns the rate of sponge underlying this hash function.
|
// 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.
|
// 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
|
// Reset clears the internal state by zeroing the sponge state and
|
||||||
// the byte buffer, and setting Sponge.state to absorbing.
|
// the byte buffer, and setting Sponge.state to absorbing.
|
||||||
func (d *state) Reset() {
|
func (d *HasherState) Reset() {
|
||||||
// Zero the permutation's state.
|
// Zero the permutation's state.
|
||||||
for i := range d.a {
|
for i := range d.a {
|
||||||
d.a[i] = 0
|
d.a[i] = 0
|
||||||
|
@ -64,7 +64,7 @@ func (d *state) Reset() {
|
||||||
d.buf = d.storage.asBytes()[:0]
|
d.buf = d.storage.asBytes()[:0]
|
||||||
}
|
}
|
||||||
|
|
||||||
func (d *state) clone() *state {
|
func (d *HasherState) clone() *HasherState {
|
||||||
ret := *d
|
ret := *d
|
||||||
if ret.state == spongeAbsorbing {
|
if ret.state == spongeAbsorbing {
|
||||||
ret.buf = ret.storage.asBytes()[:len(ret.buf)]
|
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
|
// permute applies the KeccakF-1600 permutation. It handles
|
||||||
// any input-output buffering.
|
// any input-output buffering.
|
||||||
func (d *state) permute() {
|
func (d *HasherState) permute() {
|
||||||
switch d.state {
|
switch d.state {
|
||||||
case spongeAbsorbing:
|
case spongeAbsorbing:
|
||||||
// If we're absorbing, we need to xor the input into the state
|
// 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
|
// pads appends the domain separation bits in dsbyte, applies
|
||||||
// the multi-bitrate 10..1 padding rule, and permutes the state.
|
// 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 {
|
if d.buf == nil {
|
||||||
d.buf = d.storage.asBytes()[:0]
|
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
|
// Write absorbs more data into the hash's state. It produces an error
|
||||||
// if more data is written to the ShakeHash after writing
|
// 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 {
|
if d.state != spongeAbsorbing {
|
||||||
panic("sha3: write to sponge after read")
|
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.
|
// 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 we're still absorbing, pad and apply the permutation.
|
||||||
if d.state == spongeAbsorbing {
|
if d.state == spongeAbsorbing {
|
||||||
d.padAndPermute(d.dsbyte)
|
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
|
// Sum applies padding to the hash state and then squeezes out the desired
|
||||||
// number of output bytes.
|
// 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
|
// Make a copy of the original hash so that caller can keep writing
|
||||||
// and summing.
|
// and summing.
|
||||||
dup := d.clone()
|
dup := d.clone()
|
||||||
|
|
14
shake.go
14
shake.go
|
@ -41,7 +41,7 @@ type ShakeHash interface {
|
||||||
|
|
||||||
// cSHAKE specific context
|
// cSHAKE specific context
|
||||||
type cshakeState struct {
|
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
|
// initBlock is the cSHAKE specific initialization set of bytes. It is initialized
|
||||||
// by newCShake function and stores concatenation of N followed by S, encoded
|
// 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 {
|
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
|
// leftEncode returns max 9 bytes
|
||||||
c.initBlock = make([]byte, 0, 9*2+len(N)+len(S))
|
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.
|
// Reset resets the hash to initial state.
|
||||||
func (c *cshakeState) Reset() {
|
func (c *cshakeState) Reset() {
|
||||||
c.state.Reset()
|
c.HasherState.Reset()
|
||||||
c.Write(bytepad(c.initBlock, c.rate))
|
c.Write(bytepad(c.initBlock, c.rate))
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -104,11 +104,11 @@ func (c *cshakeState) Reset() {
|
||||||
func (c *cshakeState) Clone() ShakeHash {
|
func (c *cshakeState) Clone() ShakeHash {
|
||||||
b := make([]byte, len(c.initBlock))
|
b := make([]byte, len(c.initBlock))
|
||||||
copy(b, 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.
|
// Clone returns copy of SHAKE context within its current state.
|
||||||
func (c *state) Clone() ShakeHash {
|
func (c *HasherState) Clone() ShakeHash {
|
||||||
return c.clone()
|
return c.clone()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -119,7 +119,7 @@ func NewShake128() ShakeHash {
|
||||||
if h := newShake128Asm(); h != nil {
|
if h := newShake128Asm(); h != nil {
|
||||||
return h
|
return h
|
||||||
}
|
}
|
||||||
return &state{rate: rate128, dsbyte: dsbyteShake}
|
return &HasherState{rate: rate128, dsbyte: dsbyteShake}
|
||||||
}
|
}
|
||||||
|
|
||||||
// NewShake256 creates a new SHAKE256 variable-output-length ShakeHash.
|
// NewShake256 creates a new SHAKE256 variable-output-length ShakeHash.
|
||||||
|
@ -129,7 +129,7 @@ func NewShake256() ShakeHash {
|
||||||
if h := newShake256Asm(); h != nil {
|
if h := newShake256Asm(); h != nil {
|
||||||
return h
|
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,
|
// NewCShake128 creates a new instance of cSHAKE128 variable-output-length ShakeHash,
|
||||||
|
|
|
@ -9,7 +9,7 @@ import "encoding/binary"
|
||||||
// xorInGeneric xors the bytes in buf into the state; it
|
// xorInGeneric xors the bytes in buf into the state; it
|
||||||
// makes no non-portable assumptions about memory layout
|
// makes no non-portable assumptions about memory layout
|
||||||
// or alignment.
|
// or alignment.
|
||||||
func xorInGeneric(d *state, buf []byte) {
|
func xorInGeneric(d *HasherState, buf []byte) {
|
||||||
n := len(buf) / 8
|
n := len(buf) / 8
|
||||||
|
|
||||||
for i := 0; i < n; i++ {
|
for i := 0; i < n; i++ {
|
||||||
|
@ -20,7 +20,7 @@ func xorInGeneric(d *state, buf []byte) {
|
||||||
}
|
}
|
||||||
|
|
||||||
// copyOutGeneric copies uint64s to a byte buffer.
|
// 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++ {
|
for i := 0; len(b) >= 8; i++ {
|
||||||
binary.LittleEndian.PutUint64(b, d.a[i])
|
binary.LittleEndian.PutUint64(b, d.a[i])
|
||||||
b = b[8:]
|
b = b[8:]
|
||||||
|
|
|
@ -19,7 +19,7 @@ func (b *storageBuf) asBytes() *[maxRate]byte {
|
||||||
|
|
||||||
// xorInUnaligned uses unaligned reads and writes to update d.a to contain d.a
|
// xorInUnaligned uses unaligned reads and writes to update d.a to contain d.a
|
||||||
// XOR buf.
|
// XOR buf.
|
||||||
func xorInUnaligned(d *state, buf []byte) {
|
func xorInUnaligned(d *HasherState, buf []byte) {
|
||||||
n := len(buf)
|
n := len(buf)
|
||||||
bw := (*[maxRate / 8]uint64)(unsafe.Pointer(&buf[0]))[: n/8 : n/8]
|
bw := (*[maxRate / 8]uint64)(unsafe.Pointer(&buf[0]))[: n/8 : n/8]
|
||||||
if n >= 72 {
|
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]))
|
ab := (*[maxRate]uint8)(unsafe.Pointer(&d.a[0]))
|
||||||
copy(buf, ab[:])
|
copy(buf, ab[:])
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in a new issue