github.com/cloudflare/circl@v1.5.0/internal/sha3/shake.go (about) 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 }