1
2
3
4
5 package sha3
6
7
8
9
10
11
12
13
14
15
16
17
18 import (
19 "bytes"
20 "encoding/binary"
21 "errors"
22 "hash"
23 "io"
24 "math/bits"
25 )
26
27
28
29
30
31 type ShakeHash interface {
32 hash.Hash
33
34
35
36
37
38 io.Reader
39
40
41 Clone() ShakeHash
42 }
43
44
45 type cshakeState struct {
46 *state
47
48
49
50
51
52
53 initBlock []byte
54 }
55
56 func bytepad(data []byte, rate int) []byte {
57 out := make([]byte, 0, 9+len(data)+rate-1)
58 out = append(out, leftEncode(uint64(rate))...)
59 out = append(out, data...)
60 if padlen := rate - len(out)%rate; padlen < rate {
61 out = append(out, make([]byte, padlen)...)
62 }
63 return out
64 }
65
66 func leftEncode(x uint64) []byte {
67
68 n := (bits.Len64(x) + 7) / 8
69 if n == 0 {
70 n = 1
71 }
72
73 b := make([]byte, 9)
74 binary.BigEndian.PutUint64(b[1:], x)
75 b = b[9-n-1:]
76 b[0] = byte(n)
77 return b
78 }
79
80 func newCShake(N, S []byte, rate, outputLen int, dsbyte byte) ShakeHash {
81 c := cshakeState{state: &state{rate: rate, outputLen: outputLen, dsbyte: dsbyte}}
82 c.initBlock = make([]byte, 0, 9+len(N)+9+len(S))
83 c.initBlock = append(c.initBlock, leftEncode(uint64(len(N))*8)...)
84 c.initBlock = append(c.initBlock, N...)
85 c.initBlock = append(c.initBlock, leftEncode(uint64(len(S))*8)...)
86 c.initBlock = append(c.initBlock, S...)
87 c.Write(bytepad(c.initBlock, c.rate))
88 return &c
89 }
90
91
92 func (c *cshakeState) Reset() {
93 c.state.Reset()
94 c.Write(bytepad(c.initBlock, c.rate))
95 }
96
97
98 func (c *cshakeState) Clone() ShakeHash {
99 b := make([]byte, len(c.initBlock))
100 copy(b, c.initBlock)
101 return &cshakeState{state: c.clone(), initBlock: b}
102 }
103
104
105 func (c *state) Clone() ShakeHash {
106 return c.clone()
107 }
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
133
134
135
136 func NewShake128() ShakeHash {
137 return newShake128()
138 }
139
140
141
142
143 func NewShake256() ShakeHash {
144 return newShake256()
145 }
146
147 func newShake128Generic() *state {
148 return &state{rate: rateK256, outputLen: 32, dsbyte: dsbyteShake}
149 }
150
151 func newShake256Generic() *state {
152 return &state{rate: rateK512, outputLen: 64, dsbyte: dsbyteShake}
153 }
154
155
156
157
158
159
160
161 func NewCShake128(N, S []byte) ShakeHash {
162 if len(N) == 0 && len(S) == 0 {
163 return NewShake128()
164 }
165 return newCShake(N, S, rateK256, 32, dsbyteCShake)
166 }
167
168
169
170
171
172
173
174 func NewCShake256(N, S []byte) ShakeHash {
175 if len(N) == 0 && len(S) == 0 {
176 return NewShake256()
177 }
178 return newCShake(N, S, rateK512, 64, dsbyteCShake)
179 }
180
181
182 func ShakeSum128(hash, data []byte) {
183 h := NewShake128()
184 h.Write(data)
185 h.Read(hash)
186 }
187
188
189 func ShakeSum256(hash, data []byte) {
190 h := NewShake256()
191 h.Write(data)
192 h.Read(hash)
193 }
194
View as plain text