1
2
3
4
5
6
7 package sha3
8
9 import (
10 "crypto/internal/fips140/subtle"
11 "crypto/internal/fips140deps/cpu"
12 "crypto/internal/impl"
13 )
14
15
16
17
18
19
20
21
22 var useSHA3 = cpu.S390XHasSHA3
23
24 func init() {
25
26 impl.Register("sha3", "CPACF", &useSHA3)
27 }
28
29 func keccakF1600(a *[200]byte) {
30 keccakF1600Generic(a)
31 }
32
33
34
35 type code uint64
36
37 const (
38
39 sha3_224 code = 32
40 sha3_256 code = 33
41 sha3_384 code = 34
42 sha3_512 code = 35
43 shake_128 code = 36
44 shake_256 code = 37
45 nopad = 0x100
46 )
47
48
49
50
51
52
53 func kimd(function code, a *[200]byte, src []byte)
54
55
56
57
58
59
60
61
62
63
64
65 func klmd(function code, a *[200]byte, dst, src []byte)
66
67 func (d *Digest) write(p []byte) (n int, err error) {
68 if d.state != spongeAbsorbing {
69 panic("sha3: Write after Read")
70 }
71 if !useSHA3 {
72 return d.writeGeneric(p)
73 }
74
75 n = len(p)
76
77
78 if d.n > 0 {
79 x := subtle.XORBytes(d.a[d.n:d.rate], d.a[d.n:d.rate], p)
80 d.n += x
81 p = p[x:]
82 }
83
84
85 if d.n == d.rate {
86
87
88
89 kimd(shake_128, &d.a, make([]byte, rateK256))
90 d.n = 0
91 }
92
93
94 if len(p) >= d.rate {
95 wholeBlocks := len(p) / d.rate * d.rate
96 kimd(d.function(), &d.a, p[:wholeBlocks])
97 p = p[wholeBlocks:]
98 }
99
100
101 if len(p) > 0 {
102 d.n += subtle.XORBytes(d.a[d.n:d.rate], d.a[d.n:d.rate], p)
103 }
104
105 return
106 }
107
108 func (d *Digest) sum(b []byte) []byte {
109 if d.state != spongeAbsorbing {
110 panic("sha3: Sum after Read")
111 }
112 if !useSHA3 || d.dsbyte != dsbyteSHA3 && d.dsbyte != dsbyteShake {
113 return d.sumGeneric(b)
114 }
115
116
117 a := d.a
118
119
120
121
122 buf := make([]byte, d.n, rateK256)
123 function := d.function()
124 switch function {
125 case sha3_224, sha3_256, sha3_384, sha3_512:
126 klmd(function, &a, nil, buf)
127 return append(b, a[:d.outputLen]...)
128 case shake_128, shake_256:
129 h := make([]byte, d.outputLen, 64)
130 klmd(function, &a, h, buf)
131 return append(b, h...)
132 default:
133 panic("sha3: unknown function")
134 }
135 }
136
137 func (d *Digest) read(out []byte) (n int, err error) {
138 if !useSHA3 || d.dsbyte != dsbyteShake {
139 return d.readGeneric(out)
140 }
141
142 n = len(out)
143
144 if d.state == spongeAbsorbing {
145 d.state = spongeSqueezing
146
147
148
149
150 buf := make([]byte, d.n, rateK256)
151 klmd(d.function(), &d.a, out, buf)
152 } else {
153
154 if d.n < d.rate {
155 x := copy(out, d.a[d.n:d.rate])
156 d.n += x
157 out = out[x:]
158 }
159 if len(out) == 0 {
160 return
161 }
162
163 klmd(d.function()|nopad, &d.a, out, nil)
164 }
165
166 if len(out)%d.rate == 0 {
167
168
169 d.n = d.rate
170 } else {
171 d.n = len(out) % d.rate
172 }
173
174 return
175 }
176
177 func (d *Digest) function() code {
178 switch d.rate {
179 case rateK256:
180 return shake_128
181 case rateK448:
182 return sha3_224
183 case rateK512:
184 if d.dsbyte == dsbyteSHA3 {
185 return sha3_256
186 } else {
187 return shake_256
188 }
189 case rateK768:
190 return sha3_384
191 case rateK1024:
192 return sha3_512
193 default:
194 panic("invalid rate")
195 }
196 }
197
View as plain text