main
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 file defines the ShakeHash interface, and provides
8// functions for creating SHAKE and cSHAKE instances, as well as utility
9// functions for hashing bytes to arbitrary-length output.
10//
11//
12// SHAKE implementation is based on FIPS PUB 202 [1]
13// cSHAKE implementations is based on NIST SP 800-185 [2]
14//
15// [1] https://nvlpubs.nist.gov/nistpubs/FIPS/NIST.FIPS.202.pdf
16// [2] https://doi.org/10.6028/NIST.SP.800-185
17
18import (
19 "io"
20)
21
22// ShakeHash defines the interface to hash functions that
23// support arbitrary-length output.
24type ShakeHash interface {
25 // Write absorbs more data into the hash's state. It panics if input is
26 // written to it after output has been read from it.
27 io.Writer
28
29 // Read reads more output from the hash; reading affects the hash's
30 // state. (ShakeHash.Read is thus very different from Hash.Sum)
31 // It never returns an error.
32 io.Reader
33
34 // Clone returns a copy of the ShakeHash in its current state.
35 Clone() ShakeHash
36
37 // Reset resets the ShakeHash to its initial state.
38 Reset()
39}
40
41// Consts for configuring initial SHA-3 state
42const (
43 dsbyteShake = 0x1f
44 rate128 = 168
45 rate256 = 136
46)
47
48// Clone returns copy of SHAKE context within its current state.
49func (d *State) Clone() ShakeHash {
50 return d.clone()
51}
52
53// NewShake128 creates a new SHAKE128 variable-output-length ShakeHash.
54// Its generic security strength is 128 bits against all attacks if at
55// least 32 bytes of its output are used.
56func NewShake128() State {
57 return State{rate: rate128, dsbyte: dsbyteShake}
58}
59
60// NewTurboShake128 creates a new TurboSHAKE128 variable-output-length ShakeHash.
61// Its generic security strength is 128 bits against all attacks if at
62// least 32 bytes of its output are used.
63// D is the domain separation byte and must be between 0x01 and 0x7f inclusive.
64func NewTurboShake128(D byte) State {
65 if D == 0 || D > 0x7f {
66 panic("turboshake: D out of range")
67 }
68 return State{rate: rate128, dsbyte: D, turbo: true}
69}
70
71// NewShake256 creates a new SHAKE256 variable-output-length ShakeHash.
72// Its generic security strength is 256 bits against all attacks if
73// at least 64 bytes of its output are used.
74func NewShake256() State {
75 return State{rate: rate256, dsbyte: dsbyteShake}
76}
77
78// NewTurboShake256 creates a new TurboSHAKE256 variable-output-length ShakeHash.
79// Its generic security strength is 256 bits against all attacks if
80// at least 64 bytes of its output are used.
81// D is the domain separation byte and must be between 0x01 and 0x7f inclusive.
82func NewTurboShake256(D byte) State {
83 if D == 0 || D > 0x7f {
84 panic("turboshake: D out of range")
85 }
86 return State{rate: rate256, dsbyte: D, turbo: true}
87}
88
89// ShakeSum128 writes an arbitrary-length digest of data into hash.
90func ShakeSum128(hash, data []byte) {
91 h := NewShake128()
92 _, _ = h.Write(data)
93 _, _ = h.Read(hash)
94}
95
96// ShakeSum256 writes an arbitrary-length digest of data into hash.
97func ShakeSum256(hash, data []byte) {
98 h := NewShake256()
99 _, _ = h.Write(data)
100 _, _ = h.Read(hash)
101}
102
103// TurboShakeSum128 writes an arbitrary-length digest of data into hash.
104func TurboShakeSum128(hash, data []byte, D byte) {
105 h := NewTurboShake128(D)
106 _, _ = h.Write(data)
107 _, _ = h.Read(hash)
108}
109
110// TurboShakeSum256 writes an arbitrary-length digest of data into hash.
111func TurboShakeSum256(hash, data []byte, D byte) {
112 h := NewTurboShake256(D)
113 _, _ = h.Write(data)
114 _, _ = h.Read(hash)
115}
116
117func (d *State) SwitchDS(D byte) {
118 d.dsbyte = D
119}