// Copyright 2014 The Go Authors. All rights reserved.// Use of this source code is governed by a BSD-style// license that can be found in the LICENSE file.
// Package sha3 implements the SHA-3 fixed-output-length hash functions and// the SHAKE variable-output-length functions defined by [FIPS 202], as well as// the cSHAKE extendable-output-length functions defined by [SP 800-185].//// [FIPS 202]: https://doi.org/10.6028/NIST.FIPS.202// [SP 800-185]: https://doi.org/10.6028/NIST.SP.800-185
package sha3import ()// spongeDirection indicates the direction bytes are flowing through the sponge.type spongeDirection intconst (// spongeAbsorbing indicates that the sponge is absorbing input. spongeAbsorbing spongeDirection = iota// spongeSqueezing indicates that the sponge is being squeezed. spongeSqueezing)typeDigeststruct { a [1600 / 8]byte// main state of the hash// a[n:rate] is the buffer. If absorbing, it's the remaining space to XOR // into before running the permutation. If squeezing, it's the remaining // output to produce before running the permutation. n, rate int// dsbyte contains the "domain separation" bits and the first bit of // the padding. Sections 6.1 and 6.2 of [1] separate the outputs of the // SHA-3 and SHAKE functions by appending bitstrings to the message. // Using a little-endian bit-ordering convention, these are "01" for SHA-3 // and "1111" for SHAKE, or 00000010b and 00001111b, respectively. Then the // padding rule from section 5.1 is applied to pad the message to a multiple // of the rate, which involves adding a "1" bit, zero or more "0" bits, and // a final "1" bit. We merge the first "1" bit from the padding into dsbyte, // giving 00000110b (0x06) and 00011111b (0x1f). // [1] http://csrc.nist.gov/publications/drafts/fips-202/fips_202_draft.pdf // "Draft FIPS 202: SHA-3 Standard: Permutation-Based Hash and // Extendable-Output Functions (May 2014)" dsbyte byte outputLen int// the default output size in bytes state spongeDirection// whether the sponge is absorbing or squeezing}// BlockSize returns the rate of sponge underlying this hash function.func ( *Digest) () int { return .rate }// Size returns the output size of the hash function in bytes.func ( *Digest) () int { return .outputLen }// Reset resets the Digest to its initial state.func ( *Digest) () {// Zero the permutation's state.for := range .a { .a[] = 0 } .state = spongeAbsorbing .n = 0}func ( *Digest) () *Digest { := *return &}// permute applies the KeccakF-1600 permutation.func ( *Digest) () {keccakF1600(&.a) .n = 0}// padAndPermute appends the domain separation bits in dsbyte, applies// the multi-bitrate 10..1 padding rule, and permutes the state.func ( *Digest) () {// Pad with this instance's domain-separator bits. We know that there's // at least one byte of space in the sponge because, if it were full, // permute would have been called to empty it. dsbyte also contains the // first one bit for the padding. See the comment in the state struct. .a[.n] ^= .dsbyte// This adds the final one bit for the padding. Because of the way that // bits are numbered from the LSB upwards, the final bit is the MSB of // the last byte. .a[.rate-1] ^= 0x80// Apply the permutation .permute() .state = spongeSqueezing}// Write absorbs more data into the hash's state.func ( *Digest) ( []byte) ( int, error) { return .write() }func ( *Digest) ( []byte) ( int, error) {if .state != spongeAbsorbing {panic("sha3: Write after Read") } = len()forlen() > 0 { := subtle.XORBytes(.a[.n:.rate], .a[.n:.rate], ) .n += = [:]// If the sponge is full, apply the permutation.if .n == .rate { .permute() } }return}// read squeezes an arbitrary number of bytes from the sponge.func ( *Digest) ( []byte) ( int, error) {// If we're still absorbing, pad and apply the permutation.if .state == spongeAbsorbing { .padAndPermute() } = len()// Now, do the squeezing.forlen() > 0 {// Apply the permutation if we've squeezed the sponge dry.if .n == .rate { .permute() } := copy(, .a[.n:.rate]) .n += = [:] }return}// Sum appends the current hash to b and returns the resulting slice.// It does not change the underlying hash state.func ( *Digest) ( []byte) []byte {fips140.RecordApproved()return .sum()}func ( *Digest) ( []byte) []byte {if .state != spongeAbsorbing {panic("sha3: Sum after Read") }// Make a copy of the original hash so that caller can keep writing // and summing. := .Clone() := make([]byte, .outputLen, 64) // explicit cap to allow stack allocation .read()returnappend(, ...)}const ( magicSHA3 = "sha\x08" magicShake = "sha\x09" magicCShake = "sha\x0a" magicKeccak = "sha\x0b"// magic || rate || main state || n || sponge direction marshaledSize = len(magicSHA3) + 1 + 200 + 1 + 1)func ( *Digest) () ([]byte, error) {return .AppendBinary(make([]byte, 0, marshaledSize))}func ( *Digest) ( []byte) ([]byte, error) {switch .dsbyte {casedsbyteSHA3: = append(, magicSHA3...)casedsbyteShake: = append(, magicShake...)casedsbyteCShake: = append(, magicCShake...)casedsbyteKeccak: = append(, magicKeccak...)default:panic("unknown dsbyte") }// rate is at most 168, and n is at most rate. = append(, byte(.rate)) = append(, .a[:]...) = append(, byte(.n), byte(.state))return , nil}func ( *Digest) ( []byte) error {iflen() != marshaledSize {returnerrors.New("sha3: invalid hash state") } := string([:len(magicSHA3)]) = [len(magicSHA3):]switch {case == magicSHA3 && .dsbyte == dsbyteSHA3:case == magicShake && .dsbyte == dsbyteShake:case == magicCShake && .dsbyte == dsbyteCShake:case == magicKeccak && .dsbyte == dsbyteKeccak:default:returnerrors.New("sha3: invalid hash state identifier") } := int([0]) = [1:]if != .rate {returnerrors.New("sha3: invalid hash state function") }copy(.a[:], ) = [len(.a):] , := int([0]), spongeDirection([1])if > .rate {returnerrors.New("sha3: invalid hash state") } .n = if != spongeAbsorbing && != spongeSqueezing {returnerrors.New("sha3: invalid hash state") } .state = returnnil}
The pages are generated with Goldsv0.7.3-preview. (GOOS=linux GOARCH=amd64)
Golds is a Go 101 project developed by Tapir Liu.
PR and bug reports are welcome and can be submitted to the issue list.
Please follow @zigo_101 (reachable from the left QR code) to get the latest news of Golds.