main
Raw Download raw file
  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}