1
2
3
4
5
6
7 package sha3
8
9
10
11
12
13 import (
14 "hash"
15
16 "golang.org/x/sys/cpu"
17 )
18
19
20
21 type code uint64
22
23 const (
24
25 sha3_224 code = 32
26 sha3_256 = 33
27 sha3_384 = 34
28 sha3_512 = 35
29 shake_128 = 36
30 shake_256 = 37
31 nopad = 0x100
32 )
33
34
35
36
37
38 func kimd(function code, chain *[200]byte, src []byte)
39
40
41
42
43
44 func klmd(function code, chain *[200]byte, dst, src []byte)
45
46 type asmState struct {
47 a [200]byte
48 buf []byte
49 rate int
50 storage [3072]byte
51 outputLen int
52 function code
53 state spongeDirection
54 }
55
56 func newAsmState(function code) *asmState {
57 var s asmState
58 s.function = function
59 switch function {
60 case sha3_224:
61 s.rate = 144
62 s.outputLen = 28
63 case sha3_256:
64 s.rate = 136
65 s.outputLen = 32
66 case sha3_384:
67 s.rate = 104
68 s.outputLen = 48
69 case sha3_512:
70 s.rate = 72
71 s.outputLen = 64
72 case shake_128:
73 s.rate = 168
74 s.outputLen = 32
75 case shake_256:
76 s.rate = 136
77 s.outputLen = 64
78 default:
79 panic("sha3: unrecognized function code")
80 }
81
82
83 s.resetBuf()
84 return &s
85 }
86
87 func (s *asmState) clone() *asmState {
88 c := *s
89 c.buf = c.storage[:len(s.buf):cap(s.buf)]
90 return &c
91 }
92
93
94
95 func (s *asmState) copyIntoBuf(b []byte) {
96 bufLen := len(s.buf)
97 s.buf = s.buf[:len(s.buf)+len(b)]
98 copy(s.buf[bufLen:], b)
99 }
100
101
102
103 func (s *asmState) resetBuf() {
104 max := (cap(s.storage) / s.rate) * s.rate
105 s.buf = s.storage[:0:max]
106 }
107
108
109
110 func (s *asmState) Write(b []byte) (int, error) {
111 if s.state != spongeAbsorbing {
112 panic("sha3: Write after Read")
113 }
114 length := len(b)
115 for len(b) > 0 {
116 if len(s.buf) == 0 && len(b) >= cap(s.buf) {
117
118
119 remainder := len(b) % s.rate
120 kimd(s.function, &s.a, b[:len(b)-remainder])
121 if remainder != 0 {
122 s.copyIntoBuf(b[len(b)-remainder:])
123 }
124 return length, nil
125 }
126
127 if len(s.buf) == cap(s.buf) {
128
129 kimd(s.function, &s.a, s.buf)
130 s.buf = s.buf[:0]
131 }
132
133
134 n := len(b)
135 if len(b) > cap(s.buf)-len(s.buf) {
136 n = cap(s.buf) - len(s.buf)
137 }
138 s.copyIntoBuf(b[:n])
139 b = b[n:]
140 }
141 return length, nil
142 }
143
144
145 func (s *asmState) Read(out []byte) (n int, err error) {
146
147
148 if s.function != shake_128 && s.function != shake_256 {
149 panic("sha3: can only call Read for SHAKE functions")
150 }
151
152 n = len(out)
153
154
155 if s.state == spongeAbsorbing {
156 s.state = spongeSqueezing
157
158
159 if len(out)%s.rate == 0 {
160 klmd(s.function, &s.a, out, s.buf)
161 s.buf = s.buf[:0]
162 return
163 }
164
165
166 max := cap(s.buf)
167 if max > len(out) {
168 max = (len(out)/s.rate)*s.rate + s.rate
169 }
170 klmd(s.function, &s.a, s.buf[:max], s.buf)
171 s.buf = s.buf[:max]
172 }
173
174 for len(out) > 0 {
175
176 if len(s.buf) != 0 {
177 c := copy(out, s.buf)
178 out = out[c:]
179 s.buf = s.buf[c:]
180 continue
181 }
182
183
184 if len(out)%s.rate == 0 {
185 klmd(s.function|nopad, &s.a, out, nil)
186 return
187 }
188
189
190 s.resetBuf()
191 if cap(s.buf) > len(out) {
192 s.buf = s.buf[:(len(out)/s.rate)*s.rate+s.rate]
193 }
194 klmd(s.function|nopad, &s.a, s.buf, nil)
195 }
196 return
197 }
198
199
200
201 func (s *asmState) Sum(b []byte) []byte {
202 if s.state != spongeAbsorbing {
203 panic("sha3: Sum after Read")
204 }
205
206
207 a := s.a
208
209
210
211 switch s.function {
212 case sha3_224, sha3_256, sha3_384, sha3_512:
213 klmd(s.function, &a, nil, s.buf)
214 return append(b, a[:s.outputLen]...)
215 case shake_128, shake_256:
216 d := make([]byte, s.outputLen, 64)
217 klmd(s.function, &a, d, s.buf)
218 return append(b, d[:s.outputLen]...)
219 default:
220 panic("sha3: unknown function")
221 }
222 }
223
224
225 func (s *asmState) Reset() {
226 for i := range s.a {
227 s.a[i] = 0
228 }
229 s.resetBuf()
230 s.state = spongeAbsorbing
231 }
232
233
234 func (s *asmState) Size() int {
235 return s.outputLen
236 }
237
238
239
240
241
242 func (s *asmState) BlockSize() int {
243 return s.rate
244 }
245
246
247 func (s *asmState) Clone() ShakeHash {
248 return s.clone()
249 }
250
251
252
253 func new224() hash.Hash {
254 if cpu.S390X.HasSHA3 {
255 return newAsmState(sha3_224)
256 }
257 return new224Generic()
258 }
259
260
261
262 func new256() hash.Hash {
263 if cpu.S390X.HasSHA3 {
264 return newAsmState(sha3_256)
265 }
266 return new256Generic()
267 }
268
269
270
271 func new384() hash.Hash {
272 if cpu.S390X.HasSHA3 {
273 return newAsmState(sha3_384)
274 }
275 return new384Generic()
276 }
277
278
279
280 func new512() hash.Hash {
281 if cpu.S390X.HasSHA3 {
282 return newAsmState(sha3_512)
283 }
284 return new512Generic()
285 }
286
287
288
289 func newShake128() ShakeHash {
290 if cpu.S390X.HasSHA3 {
291 return newAsmState(shake_128)
292 }
293 return newShake128Generic()
294 }
295
296
297
298 func newShake256() ShakeHash {
299 if cpu.S390X.HasSHA3 {
300 return newAsmState(shake_256)
301 }
302 return newShake256Generic()
303 }
304
View as plain text