@@ -16,7 +16,9 @@ package sha3
16
16
// [2] https://doi.org/10.6028/NIST.SP.800-185
17
17
18
18
import (
19
+ "bytes"
19
20
"encoding/binary"
21
+ "errors"
20
22
"hash"
21
23
"io"
22
24
"math/bits"
@@ -51,14 +53,6 @@ type cshakeState struct {
51
53
initBlock []byte
52
54
}
53
55
54
- // Consts for configuring initial SHA-3 state
55
- const (
56
- dsbyteShake = 0x1f
57
- dsbyteCShake = 0x04
58
- rate128 = 168
59
- rate256 = 136
60
- )
61
-
62
56
func bytepad (data []byte , rate int ) []byte {
63
57
out := make ([]byte , 0 , 9 + len (data )+ rate - 1 )
64
58
out = append (out , leftEncode (uint64 (rate ))... )
@@ -112,6 +106,30 @@ func (c *state) Clone() ShakeHash {
112
106
return c .clone ()
113
107
}
114
108
109
+ func (c * cshakeState ) MarshalBinary () ([]byte , error ) {
110
+ return c .AppendBinary (make ([]byte , 0 , marshaledSize + len (c .initBlock )))
111
+ }
112
+
113
+ func (c * cshakeState ) AppendBinary (b []byte ) ([]byte , error ) {
114
+ b , err := c .state .AppendBinary (b )
115
+ if err != nil {
116
+ return nil , err
117
+ }
118
+ b = append (b , c .initBlock ... )
119
+ return b , nil
120
+ }
121
+
122
+ func (c * cshakeState ) UnmarshalBinary (b []byte ) error {
123
+ if len (b ) <= marshaledSize {
124
+ return errors .New ("sha3: invalid hash state" )
125
+ }
126
+ if err := c .state .UnmarshalBinary (b [:marshaledSize ]); err != nil {
127
+ return err
128
+ }
129
+ c .initBlock = bytes .Clone (b [marshaledSize :])
130
+ return nil
131
+ }
132
+
115
133
// NewShake128 creates a new SHAKE128 variable-output-length ShakeHash.
116
134
// Its generic security strength is 128 bits against all attacks if at
117
135
// least 32 bytes of its output are used.
@@ -127,11 +145,11 @@ func NewShake256() ShakeHash {
127
145
}
128
146
129
147
func newShake128Generic () * state {
130
- return & state {rate : rate128 , outputLen : 32 , dsbyte : dsbyteShake }
148
+ return & state {rate : rateK256 , outputLen : 32 , dsbyte : dsbyteShake }
131
149
}
132
150
133
151
func newShake256Generic () * state {
134
- return & state {rate : rate256 , outputLen : 64 , dsbyte : dsbyteShake }
152
+ return & state {rate : rateK512 , outputLen : 64 , dsbyte : dsbyteShake }
135
153
}
136
154
137
155
// NewCShake128 creates a new instance of cSHAKE128 variable-output-length ShakeHash,
@@ -144,7 +162,7 @@ func NewCShake128(N, S []byte) ShakeHash {
144
162
if len (N ) == 0 && len (S ) == 0 {
145
163
return NewShake128 ()
146
164
}
147
- return newCShake (N , S , rate128 , 32 , dsbyteCShake )
165
+ return newCShake (N , S , rateK256 , 32 , dsbyteCShake )
148
166
}
149
167
150
168
// NewCShake256 creates a new instance of cSHAKE256 variable-output-length ShakeHash,
@@ -157,7 +175,7 @@ func NewCShake256(N, S []byte) ShakeHash {
157
175
if len (N ) == 0 && len (S ) == 0 {
158
176
return NewShake256 ()
159
177
}
160
- return newCShake (N , S , rate256 , 64 , dsbyteCShake )
178
+ return newCShake (N , S , rateK512 , 64 , dsbyteCShake )
161
179
}
162
180
163
181
// ShakeSum128 writes an arbitrary-length digest of data into hash.
0 commit comments