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
  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
 11import (
 12	"crypto/subtle"
 13	"encoding/binary"
 14	"errors"
 15	"hash"
 16	"unsafe"
 17
 18	"golang.org/x/sys/cpu"
 19)
 20
 21const (
 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.
 35func 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.
 43func 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.
 48type spongeDirection int
 49
 50const (
 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
 57type 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.
 84func (d *state) BlockSize() int { return d.rate }
 85
 86// Size returns the output size of the hash function in bytes.
 87func (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.
 91func (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
100func (d *state) clone() *state {
101	ret := *d
102	return &ret
103}
104
105// permute applies the KeccakF-1600 permutation.
106func (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.
129func (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.
146func (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.
168func (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.
193func (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
206const (
207	magicKeccak = "sha\x0b"
208	// magic || rate || main state || n || sponge direction
209	marshaledSize = len(magicKeccak) + 1 + 200 + 1 + 1
210)
211
212func (d *state) MarshalBinary() ([]byte, error) {
213	return d.AppendBinary(make([]byte, 0, marshaledSize))
214}
215
216func (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
230func (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}