main
Raw Download raw file
  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}