...
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 n = len(out)
147
148
149 if s.state == spongeAbsorbing {
150 s.state = spongeSqueezing
151
152
153 if len(out)%s.rate == 0 {
154 klmd(s.function, &s.a, out, s.buf)
155 s.buf = s.buf[:0]
156 return
157 }
158
159
160 max := cap(s.buf)
161 if max > len(out) {
162 max = (len(out)/s.rate)*s.rate + s.rate
163 }
164 klmd(s.function, &s.a, s.buf[:max], s.buf)
165 s.buf = s.buf[:max]
166 }
167
168 for len(out) > 0 {
169
170 if len(s.buf) != 0 {
171 c := copy(out, s.buf)
172 out = out[c:]
173 s.buf = s.buf[c:]
174 continue
175 }
176
177
178 if len(out)%s.rate == 0 {
179 klmd(s.function|nopad, &s.a, out, nil)
180 return
181 }
182
183
184 s.resetBuf()
185 if cap(s.buf) > len(out) {
186 s.buf = s.buf[:(len(out)/s.rate)*s.rate+s.rate]
187 }
188 klmd(s.function|nopad, &s.a, s.buf, nil)
189 }
190 return
191 }
192
193
194
195 func (s *asmState) Sum(b []byte) []byte {
196 if s.state != spongeAbsorbing {
197 panic("sha3: Sum after Read")
198 }
199
200
201 a := s.a
202
203
204
205 klmd(s.function, &a, nil, s.buf)
206 return append(b, a[:s.outputLen]...)
207 }
208
209
210 func (s *asmState) Reset() {
211 for i := range s.a {
212 s.a[i] = 0
213 }
214 s.resetBuf()
215 s.state = spongeAbsorbing
216 }
217
218
219 func (s *asmState) Size() int {
220 return s.outputLen
221 }
222
223
224
225
226
227 func (s *asmState) BlockSize() int {
228 return s.rate
229 }
230
231
232 func (s *asmState) Clone() ShakeHash {
233 return s.clone()
234 }
235
236
237
238 func new224Asm() hash.Hash {
239 if cpu.S390X.HasSHA3 {
240 return newAsmState(sha3_224)
241 }
242 return nil
243 }
244
245
246
247 func new256Asm() hash.Hash {
248 if cpu.S390X.HasSHA3 {
249 return newAsmState(sha3_256)
250 }
251 return nil
252 }
253
254
255
256 func new384Asm() hash.Hash {
257 if cpu.S390X.HasSHA3 {
258 return newAsmState(sha3_384)
259 }
260 return nil
261 }
262
263
264
265 func new512Asm() hash.Hash {
266 if cpu.S390X.HasSHA3 {
267 return newAsmState(sha3_512)
268 }
269 return nil
270 }
271
272
273
274 func newShake128Asm() ShakeHash {
275 if cpu.S390X.HasSHA3 {
276 return newAsmState(shake_128)
277 }
278 return nil
279 }
280
281
282
283 func newShake256Asm() ShakeHash {
284 if cpu.S390X.HasSHA3 {
285 return newAsmState(shake_256)
286 }
287 return nil
288 }
289
View as plain text