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