-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathsha3.go
239 lines (202 loc) · 5.89 KB
/
sha3.go
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
// Copyright 2024 The Go Authors. All rights reserved.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.
// Package sha3 implements the SHA-3 hash algorithms and the SHAKE extendable
// output functions defined in FIPS 202.
package sha3
import (
"crypto"
"crypto/internal/fips140/sha3"
"hash"
_ "unsafe"
)
func init() {
crypto.RegisterHash(crypto.SHA3_224, func() hash.Hash { return New224() })
crypto.RegisterHash(crypto.SHA3_256, func() hash.Hash { return New256() })
crypto.RegisterHash(crypto.SHA3_384, func() hash.Hash { return New384() })
crypto.RegisterHash(crypto.SHA3_512, func() hash.Hash { return New512() })
}
// Sum224 returns the SHA3-224 hash of data.
func Sum224(data []byte) [28]byte {
var out [28]byte
h := sha3.New224()
h.Write(data)
h.Sum(out[:0])
return out
}
// Sum256 returns the SHA3-256 hash of data.
func Sum256(data []byte) [32]byte {
var out [32]byte
h := sha3.New256()
h.Write(data)
h.Sum(out[:0])
return out
}
// Sum384 returns the SHA3-384 hash of data.
func Sum384(data []byte) [48]byte {
var out [48]byte
h := sha3.New384()
h.Write(data)
h.Sum(out[:0])
return out
}
// Sum512 returns the SHA3-512 hash of data.
func Sum512(data []byte) [64]byte {
var out [64]byte
h := sha3.New512()
h.Write(data)
h.Sum(out[:0])
return out
}
// SumSHAKE128 applies the SHAKE128 extendable output function to data and
// returns an output of the given length in bytes.
func SumSHAKE128(data []byte, length int) []byte {
// Outline the allocation for up to 256 bits of output to the caller's stack.
out := make([]byte, 32)
return sumSHAKE128(out, data, length)
}
func sumSHAKE128(out, data []byte, length int) []byte {
if len(out) < length {
out = make([]byte, length)
} else {
out = out[:length]
}
h := sha3.NewShake128()
h.Write(data)
h.Read(out)
return out
}
// SumSHAKE256 applies the SHAKE256 extendable output function to data and
// returns an output of the given length in bytes.
func SumSHAKE256(data []byte, length int) []byte {
// Outline the allocation for up to 512 bits of output to the caller's stack.
out := make([]byte, 64)
return sumSHAKE256(out, data, length)
}
func sumSHAKE256(out, data []byte, length int) []byte {
if len(out) < length {
out = make([]byte, length)
} else {
out = out[:length]
}
h := sha3.NewShake256()
h.Write(data)
h.Read(out)
return out
}
// SHA3 is an instance of a SHA-3 hash. It implements [hash.Hash].
type SHA3 struct {
s sha3.Digest
}
//go:linkname fips140hash_sha3Unwrap crypto/internal/fips140hash.sha3Unwrap
func fips140hash_sha3Unwrap(sha3 *SHA3) *sha3.Digest {
return &sha3.s
}
// New224 creates a new SHA3-224 hash.
func New224() *SHA3 {
return &SHA3{*sha3.New224()}
}
// New256 creates a new SHA3-256 hash.
func New256() *SHA3 {
return &SHA3{*sha3.New256()}
}
// New384 creates a new SHA3-384 hash.
func New384() *SHA3 {
return &SHA3{*sha3.New384()}
}
// New512 creates a new SHA3-512 hash.
func New512() *SHA3 {
return &SHA3{*sha3.New512()}
}
// Write absorbs more data into the hash's state.
func (s *SHA3) Write(p []byte) (n int, err error) {
return s.s.Write(p)
}
// Sum appends the current hash to b and returns the resulting slice.
func (s *SHA3) Sum(b []byte) []byte {
return s.s.Sum(b)
}
// Reset resets the hash to its initial state.
func (s *SHA3) Reset() {
s.s.Reset()
}
// Size returns the number of bytes Sum will produce.
func (s *SHA3) Size() int {
return s.s.Size()
}
// BlockSize returns the hash's rate.
func (s *SHA3) BlockSize() int {
return s.s.BlockSize()
}
// MarshalBinary implements [encoding.BinaryMarshaler].
func (s *SHA3) MarshalBinary() ([]byte, error) {
return s.s.MarshalBinary()
}
// AppendBinary implements [encoding.BinaryAppender].
func (s *SHA3) AppendBinary(p []byte) ([]byte, error) {
return s.s.AppendBinary(p)
}
// UnmarshalBinary implements [encoding.BinaryUnmarshaler].
func (s *SHA3) UnmarshalBinary(data []byte) error {
return s.s.UnmarshalBinary(data)
}
// SHAKE is an instance of a SHAKE extendable output function.
type SHAKE struct {
s sha3.SHAKE
}
// NewSHAKE128 creates a new SHAKE128 XOF.
func NewSHAKE128() *SHAKE {
return &SHAKE{*sha3.NewShake128()}
}
// NewSHAKE256 creates a new SHAKE256 XOF.
func NewSHAKE256() *SHAKE {
return &SHAKE{*sha3.NewShake256()}
}
// NewCSHAKE128 creates a new cSHAKE128 XOF.
//
// N is used to define functions based on cSHAKE, it can be empty when plain
// cSHAKE is desired. S is a customization byte string used for domain
// separation. When N and S are both empty, this is equivalent to NewSHAKE128.
func NewCSHAKE128(N, S []byte) *SHAKE {
return &SHAKE{*sha3.NewCShake128(N, S)}
}
// NewCSHAKE256 creates a new cSHAKE256 XOF.
//
// N is used to define functions based on cSHAKE, it can be empty when plain
// cSHAKE is desired. S is a customization byte string used for domain
// separation. When N and S are both empty, this is equivalent to NewSHAKE256.
func NewCSHAKE256(N, S []byte) *SHAKE {
return &SHAKE{*sha3.NewCShake256(N, S)}
}
// Write absorbs more data into the XOF's state.
//
// It panics if any output has already been read.
func (s *SHAKE) Write(p []byte) (n int, err error) {
return s.s.Write(p)
}
// Read squeezes more output from the XOF.
//
// Any call to Write after a call to Read will panic.
func (s *SHAKE) Read(p []byte) (n int, err error) {
return s.s.Read(p)
}
// Reset resets the XOF to its initial state.
func (s *SHAKE) Reset() {
s.s.Reset()
}
// BlockSize returns the rate of the XOF.
func (s *SHAKE) BlockSize() int {
return s.s.BlockSize()
}
// MarshalBinary implements [encoding.BinaryMarshaler].
func (s *SHAKE) MarshalBinary() ([]byte, error) {
return s.s.MarshalBinary()
}
// AppendBinary implements [encoding.BinaryAppender].
func (s *SHAKE) AppendBinary(p []byte) ([]byte, error) {
return s.s.AppendBinary(p)
}
// UnmarshalBinary implements [encoding.BinaryUnmarshaler].
func (s *SHAKE) UnmarshalBinary(data []byte) error {
return s.s.UnmarshalBinary(data)
}