Skip to content

Commit 8b97607

Browse files
FiloSottilegopherbot
authored andcommitted
crypto/sha3: new package
Implement the SHA-3 hash algorithms and the SHAKE extendable output functions defined in FIPS 202. This is a wrapper for crypto/internal/fips/sha3 which in turn was ported from x/crypto/sha3 in CL 616717 as part of #65269. Fixes #69982 Change-Id: I64ce7f362c1a773f7f5b05f7e0acb4110e52a329 Reviewed-on: https://go-review.googlesource.com/c/go/+/629176 Reviewed-by: Russ Cox <[email protected]> Auto-Submit: Filippo Valsorda <[email protected]> LUCI-TryBot-Result: Go LUCI <[email protected]> Reviewed-by: Dmitri Shuralyov <[email protected]>
1 parent 8cecfad commit 8b97607

File tree

6 files changed

+349
-253
lines changed

6 files changed

+349
-253
lines changed

api/next/69982.txt

+31
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,31 @@
1+
pkg crypto/sha3, func New224() *SHA3 #69982
2+
pkg crypto/sha3, func New256() *SHA3 #69982
3+
pkg crypto/sha3, func New384() *SHA3 #69982
4+
pkg crypto/sha3, func New512() *SHA3 #69982
5+
pkg crypto/sha3, func NewCSHAKE128([]uint8, []uint8) *SHAKE #69982
6+
pkg crypto/sha3, func NewCSHAKE256([]uint8, []uint8) *SHAKE #69982
7+
pkg crypto/sha3, func NewSHAKE128() *SHAKE #69982
8+
pkg crypto/sha3, func NewSHAKE256() *SHAKE #69982
9+
pkg crypto/sha3, func Sum224([]uint8) [28]uint8 #69982
10+
pkg crypto/sha3, func Sum256([]uint8) [32]uint8 #69982
11+
pkg crypto/sha3, func Sum384([]uint8) [48]uint8 #69982
12+
pkg crypto/sha3, func Sum512([]uint8) [64]uint8 #69982
13+
pkg crypto/sha3, func SumSHAKE128([]uint8, int) []uint8 #69982
14+
pkg crypto/sha3, func SumSHAKE256([]uint8, int) []uint8 #69982
15+
pkg crypto/sha3, method (*SHA3) AppendBinary([]uint8) ([]uint8, error) #69982
16+
pkg crypto/sha3, method (*SHA3) BlockSize() int #69982
17+
pkg crypto/sha3, method (*SHA3) MarshalBinary() ([]uint8, error) #69982
18+
pkg crypto/sha3, method (*SHA3) Reset() #69982
19+
pkg crypto/sha3, method (*SHA3) Size() int #69982
20+
pkg crypto/sha3, method (*SHA3) Sum([]uint8) []uint8 #69982
21+
pkg crypto/sha3, method (*SHA3) UnmarshalBinary([]uint8) error #69982
22+
pkg crypto/sha3, method (*SHA3) Write([]uint8) (int, error) #69982
23+
pkg crypto/sha3, method (*SHAKE) AppendBinary([]uint8) ([]uint8, error) #69982
24+
pkg crypto/sha3, method (*SHAKE) BlockSize() int #69982
25+
pkg crypto/sha3, method (*SHAKE) MarshalBinary() ([]uint8, error) #69982
26+
pkg crypto/sha3, method (*SHAKE) Read([]uint8) (int, error) #69982
27+
pkg crypto/sha3, method (*SHAKE) Reset() #69982
28+
pkg crypto/sha3, method (*SHAKE) UnmarshalBinary([]uint8) error #69982
29+
pkg crypto/sha3, method (*SHAKE) Write([]uint8) (int, error) #69982
30+
pkg crypto/sha3, type SHA3 struct #69982
31+
pkg crypto/sha3, type SHAKE struct #69982

doc/next/6-stdlib/5-sha3.md

+6
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,6 @@
1+
### New sha3 package
2+
3+
The new [crypto/sha3] package implements the SHA-3 hash function, and SHAKE and
4+
cSHAKE extendable-output functions.
5+
6+
It was imported from `golang.org/x/crypto/sha3`.
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
<!-- This is a new package; covered in 6-stdlib/5-sha3.md. -->

src/crypto/sha3/sha3.go

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

0 commit comments

Comments
 (0)