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 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 18 import (
19 "io"
20 )
21 22 // ShakeHash defines the interface to hash functions that
23 // support arbitrary-length output.
24 type 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
42 const (
43 dsbyteShake = 0x1f
44 rate128 = 168
45 rate256 = 136
46 )
47 48 // Clone returns copy of SHAKE context within its current state.
49 func (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.
56 func 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.
64 func 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.
74 func 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.
82 func 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.
90 func 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.
97 func 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.
104 func 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.
111 func TurboShakeSum256(hash, data []byte, D byte) {
112 h := NewTurboShake256(D)
113 _, _ = h.Write(data)
114 _, _ = h.Read(hash)
115 }
116 117 func (d *State) SwitchDS(D byte) {
118 d.dsbyte = D
119 }
120