1 // Copyright 2014 The Go Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style
3 // license that can be found in the LICENSE file.
4 5 package sha3
6 7 // This implementation is only used for NewLegacyKeccak256 and
8 // NewLegacyKeccak512, which are not implemented by crypto/sha3.
9 // All other functions in this package are wrappers around crypto/sha3.
10 11 import (
12 "crypto/subtle"
13 "encoding/binary"
14 "errors"
15 "hash"
16 "unsafe"
17 18 "golang.org/x/sys/cpu"
19 )
20 21 const (
22 dsbyteKeccak = 0b00000001
23 24 // rateK[c] is the rate in bytes for Keccak[c] where c is the capacity in
25 // bits. Given the sponge size is 1600 bits, the rate is 1600 - c bits.
26 rateK256 = (1600 - 256) / 8
27 rateK512 = (1600 - 512) / 8
28 rateK1024 = (1600 - 1024) / 8
29 )
30 31 // NewLegacyKeccak256 creates a new Keccak-256 hash.
32 //
33 // Only use this function if you require compatibility with an existing cryptosystem
34 // that uses non-standard padding. All other users should use New256 instead.
35 func NewLegacyKeccak256() hash.Hash {
36 return &state{rate: rateK512, outputLen: 32, dsbyte: dsbyteKeccak}
37 }
38 39 // NewLegacyKeccak512 creates a new Keccak-512 hash.
40 //
41 // Only use this function if you require compatibility with an existing cryptosystem
42 // that uses non-standard padding. All other users should use New512 instead.
43 func NewLegacyKeccak512() hash.Hash {
44 return &state{rate: rateK1024, outputLen: 64, dsbyte: dsbyteKeccak}
45 }
46 47 // spongeDirection indicates the direction bytes are flowing through the sponge.
48 type spongeDirection int
49 50 const (
51 // spongeAbsorbing indicates that the sponge is absorbing input.
52 spongeAbsorbing spongeDirection = iota
53 // spongeSqueezing indicates that the sponge is being squeezed.
54 spongeSqueezing
55 )
56 57 type state struct {
58 a [1600 / 8]byte // main state of the hash
59 60 // a[n:rate] is the buffer. If absorbing, it's the remaining space to XOR
61 // into before running the permutation. If squeezing, it's the remaining
62 // output to produce before running the permutation.
63 n, rate int
64 65 // dsbyte contains the "domain separation" bits and the first bit of
66 // the padding. Sections 6.1 and 6.2 of [1] separate the outputs of the
67 // SHA-3 and SHAKE functions by appending bitstrings to the message.
68 // Using a little-endian bit-ordering convention, these are "01" for SHA-3
69 // and "1111" for SHAKE, or 00000010b and 00001111b, respectively. Then the
70 // padding rule from section 5.1 is applied to pad the message to a multiple
71 // of the rate, which involves adding a "1" bit, zero or more "0" bits, and
72 // a final "1" bit. We merge the first "1" bit from the padding into dsbyte,
73 // giving 00000110b (0x06) and 00011111b (0x1f).
74 // [1] http://csrc.nist.gov/publications/drafts/fips-202/fips_202_draft.pdf
75 // "Draft FIPS 202: SHA-3 Standard: Permutation-Based Hash and
76 // Extendable-Output Functions (May 2014)"
77 dsbyte byte
78 79 outputLen int // the default output size in bytes
80 state spongeDirection // whether the sponge is absorbing or squeezing
81 }
82 83 // BlockSize returns the rate of sponge underlying this hash function.
84 func (d *state) BlockSize() int { return d.rate }
85 86 // Size returns the output size of the hash function in bytes.
87 func (d *state) Size() int { return d.outputLen }
88 89 // Reset clears the internal state by zeroing the sponge state and
90 // the buffer indexes, and setting Sponge.state to absorbing.
91 func (d *state) Reset() {
92 // Zero the permutation's state.
93 for i := range d.a {
94 d.a[i] = 0
95 }
96 d.state = spongeAbsorbing
97 d.n = 0
98 }
99 100 func (d *state) clone() *state {
101 ret := *d
102 return &ret
103 }
104 105 // permute applies the KeccakF-1600 permutation.
106 func (d *state) permute() {
107 var a *[25]uint64
108 if cpu.IsBigEndian {
109 a = new([25]uint64)
110 for i := range a {
111 a[i] = binary.LittleEndian.Uint64(d.a[i*8:])
112 }
113 } else {
114 a = (*[25]uint64)(unsafe.Pointer(&d.a))
115 }
116 117 keccakF1600(a)
118 d.n = 0
119 120 if cpu.IsBigEndian {
121 for i := range a {
122 binary.LittleEndian.PutUint64(d.a[i*8:], a[i])
123 }
124 }
125 }
126 127 // pads appends the domain separation bits in dsbyte, applies
128 // the multi-bitrate 10..1 padding rule, and permutes the state.
129 func (d *state) padAndPermute() {
130 // Pad with this instance's domain-separator bits. We know that there's
131 // at least one byte of space in the sponge because, if it were full,
132 // permute would have been called to empty it. dsbyte also contains the
133 // first one bit for the padding. See the comment in the state struct.
134 d.a[d.n] ^= d.dsbyte
135 // This adds the final one bit for the padding. Because of the way that
136 // bits are numbered from the LSB upwards, the final bit is the MSB of
137 // the last byte.
138 d.a[d.rate-1] ^= 0x80
139 // Apply the permutation
140 d.permute()
141 d.state = spongeSqueezing
142 }
143 144 // Write absorbs more data into the hash's state. It panics if any
145 // output has already been read.
146 func (d *state) Write(p []byte) (n int, err error) {
147 if d.state != spongeAbsorbing {
148 panic("sha3: Write after Read")
149 }
150 151 n = len(p)
152 153 for len(p) > 0 {
154 x := subtle.XORBytes(d.a[d.n:d.rate], d.a[d.n:d.rate], p)
155 d.n += x
156 p = p[x:]
157 158 // If the sponge is full, apply the permutation.
159 if d.n == d.rate {
160 d.permute()
161 }
162 }
163 164 return
165 }
166 167 // Read squeezes an arbitrary number of bytes from the sponge.
168 func (d *state) Read(out []byte) (n int, err error) {
169 // If we're still absorbing, pad and apply the permutation.
170 if d.state == spongeAbsorbing {
171 d.padAndPermute()
172 }
173 174 n = len(out)
175 176 // Now, do the squeezing.
177 for len(out) > 0 {
178 // Apply the permutation if we've squeezed the sponge dry.
179 if d.n == d.rate {
180 d.permute()
181 }
182 183 x := copy(out, d.a[d.n:d.rate])
184 d.n += x
185 out = out[x:]
186 }
187 188 return
189 }
190 191 // Sum applies padding to the hash state and then squeezes out the desired
192 // number of output bytes. It panics if any output has already been read.
193 func (d *state) Sum(in []byte) []byte {
194 if d.state != spongeAbsorbing {
195 panic("sha3: Sum after Read")
196 }
197 198 // Make a copy of the original hash so that caller can keep writing
199 // and summing.
200 dup := d.clone()
201 hash := make([]byte, dup.outputLen, 64) // explicit cap to allow stack allocation
202 dup.Read(hash)
203 return append(in, hash...)
204 }
205 206 const (
207 magicKeccak = "sha\x0b"
208 // magic || rate || main state || n || sponge direction
209 marshaledSize = len(magicKeccak) + 1 + 200 + 1 + 1
210 )
211 212 func (d *state) MarshalBinary() ([]byte, error) {
213 return d.AppendBinary(make([]byte, 0, marshaledSize))
214 }
215 216 func (d *state) AppendBinary(b []byte) ([]byte, error) {
217 switch d.dsbyte {
218 case dsbyteKeccak:
219 b = append(b, magicKeccak...)
220 default:
221 panic("unknown dsbyte")
222 }
223 // rate is at most 168, and n is at most rate.
224 b = append(b, byte(d.rate))
225 b = append(b, d.a[:]...)
226 b = append(b, byte(d.n), byte(d.state))
227 return b, nil
228 }
229 230 func (d *state) UnmarshalBinary(b []byte) error {
231 if len(b) != marshaledSize {
232 return errors.New("sha3: invalid hash state")
233 }
234 235 magic := string(b[:len(magicKeccak)])
236 b = b[len(magicKeccak):]
237 switch {
238 case magic == magicKeccak && d.dsbyte == dsbyteKeccak:
239 default:
240 return errors.New("sha3: invalid hash state identifier")
241 }
242 243 rate := int(b[0])
244 b = b[1:]
245 if rate != d.rate {
246 return errors.New("sha3: invalid hash state function")
247 }
248 249 copy(d.a[:], b)
250 b = b[len(d.a):]
251 252 n, state := int(b[0]), spongeDirection(b[1])
253 if n > d.rate {
254 return errors.New("sha3: invalid hash state")
255 }
256 d.n = n
257 if state != spongeAbsorbing && state != spongeSqueezing {
258 return errors.New("sha3: invalid hash state")
259 }
260 d.state = state
261 262 return nil
263 }
264