sha3.gno
6.61 Kb ยท 239 lines
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 keccak256 was ported from x/crypto/sha3
6// the original source can be found here:
7// https://cs.opensource.google/go/x/crypto/+/master:sha3/sha3.go
8package keccak256
9
10import (
11 "crypto/subtle"
12 "encoding/binary"
13 "errors"
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 without unsafe.
75func (d *state) permute() {
76 var a [25]uint64
77
78 // Always load in little-endian order
79 for i := range a {
80 a[i] = binary.LittleEndian.Uint64(d.a[i*8:])
81 }
82
83 keccakF1600(&a)
84 d.n = 0
85
86 // Always store in little-endian order
87 for i := range a {
88 binary.LittleEndian.PutUint64(d.a[i*8:], a[i])
89 }
90}
91
92// pads appends the domain separation bits in dsbyte, applies
93// the multi-bitrate 10..1 padding rule, and permutes the state.
94func (d *state) padAndPermute() {
95 // Pad with this instance's domain-separator bits. We know that there's
96 // at least one byte of space in the sponge because, if it were full,
97 // permute would have been called to empty it. dsbyte also contains the
98 // first one bit for the padding. See the comment in the state struct.
99 d.a[d.n] ^= d.dsbyte
100 // This adds the final one bit for the padding. Because of the way that
101 // bits are numbered from the LSB upwards, the final bit is the MSB of
102 // the last byte.
103 d.a[d.rate-1] ^= 0x80
104 // Apply the permutation
105 d.permute()
106 d.state = spongeSqueezing
107}
108
109// Write absorbs more data into the hash's state. It panics if any
110// output has already been read.
111func (d *state) Write(p []byte) (n int, err error) {
112 if d.state != spongeAbsorbing {
113 panic("sha3: Write after Read")
114 }
115
116 n = len(p)
117 for len(p) > 0 {
118 x := subtle.XORBytesUnsafe(d.a[d.n:d.rate], d.a[d.n:d.rate], p)
119 d.n += x
120 p = p[x:]
121
122 // If the sponge is full, apply the permutation.
123 if d.n == d.rate {
124 d.permute()
125 }
126 }
127
128 return
129}
130
131// Read squeezes an arbitrary number of bytes from the sponge.
132func (d *state) Read(out []byte) (n int, err error) {
133 // If we're still absorbing, pad and apply the permutation.
134 if d.state == spongeAbsorbing {
135 d.padAndPermute()
136 }
137
138 n = len(out)
139
140 // Now, do the squeezing.
141 for len(out) > 0 {
142 // Apply the permutation if we've squeezed the sponge dry.
143 if d.n == d.rate {
144 d.permute()
145 }
146
147 x := copy(out, d.a[d.n:d.rate])
148 d.n += x
149 out = out[x:]
150 }
151
152 return
153}
154
155// Sum applies padding to the hash state and then squeezes out the desired
156// number of output bytes. It panics if any output has already been read.
157func (d *state) Sum(in []byte) []byte {
158 if d.state != spongeAbsorbing {
159 panic("sha3: Sum after Read")
160 }
161
162 // Make a copy of the original hash so that caller can keep writing
163 // and summing.
164 dup := d.clone()
165 hash := make([]byte, dup.outputLen, 64) // explicit cap to allow stack allocation
166 dup.Read(hash)
167 return append(in, hash...)
168}
169
170const (
171 magicSHA3 = "sha\x08"
172 magicShake = "sha\x09"
173 magicCShake = "sha\x0a"
174 magicKeccak = "sha\x0b"
175 // magic || rate || main state || n || sponge direction
176 marshaledSize = len(magicSHA3) + 1 + 200 + 1 + 1
177)
178
179func (d *state) MarshalBinary() ([]byte, error) {
180 return d.AppendBinary(make([]byte, 0, marshaledSize))
181}
182
183func (d *state) AppendBinary(b []byte) ([]byte, error) {
184 switch d.dsbyte {
185 case dsbyteSHA3:
186 b = append(b, magicSHA3...)
187 case dsbyteShake:
188 b = append(b, magicShake...)
189 case dsbyteCShake:
190 b = append(b, magicCShake...)
191 case dsbyteKeccak:
192 b = append(b, magicKeccak...)
193 default:
194 panic("unknown dsbyte")
195 }
196 // rate is at most 168, and n is at most rate.
197 b = append(b, byte(d.rate))
198 b = append(b, d.a[:]...)
199 b = append(b, byte(d.n), byte(d.state))
200 return b, nil
201}
202
203func (d *state) UnmarshalBinary(b []byte) error {
204 if len(b) != marshaledSize {
205 return errors.New("sha3: invalid hash state")
206 }
207
208 magic := string(b[:len(magicSHA3)])
209 b = b[len(magicSHA3):]
210 switch {
211 case magic == magicSHA3 && d.dsbyte == dsbyteSHA3:
212 case magic == magicShake && d.dsbyte == dsbyteShake:
213 case magic == magicCShake && d.dsbyte == dsbyteCShake:
214 case magic == magicKeccak && d.dsbyte == dsbyteKeccak:
215 default:
216 return errors.New("sha3: invalid hash state identifier")
217 }
218
219 rate := int(b[0])
220 b = b[1:]
221 if rate != d.rate {
222 return errors.New("sha3: invalid hash state function")
223 }
224
225 copy(d.a[:], b)
226 b = b[len(d.a):]
227
228 n, state := int(b[0]), spongeDirection(b[1])
229 if n > d.rate {
230 return errors.New("sha3: invalid hash state")
231 }
232 d.n = n
233 if state != spongeAbsorbing && state != spongeSqueezing {
234 return errors.New("sha3: invalid hash state")
235 }
236 d.state = state
237
238 return nil
239}