Source File
legacy_hash.go
Belonging Package
golang.org/x/crypto/sha3
// 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// This implementation is only used for NewLegacyKeccak256 and// NewLegacyKeccak512, which are not implemented by crypto/sha3.// All other functions in this package are wrappers around crypto/sha3.import ()const (dsbyteKeccak = 0b00000001// rateK[c] is the rate in bytes for Keccak[c] where c is the capacity in// bits. Given the sponge size is 1600 bits, the rate is 1600 - c bits.rateK256 = (1600 - 256) / 8rateK512 = (1600 - 512) / 8rateK1024 = (1600 - 1024) / 8)// NewLegacyKeccak256 creates a new Keccak-256 hash.//// Only use this function if you require compatibility with an existing cryptosystem// that uses non-standard padding. All other users should use New256 instead.func () hash.Hash {return &state{rate: rateK512, outputLen: 32, dsbyte: dsbyteKeccak}}// NewLegacyKeccak512 creates a new Keccak-512 hash.//// Only use this function if you require compatibility with an existing cryptosystem// that uses non-standard padding. All other users should use New512 instead.func () hash.Hash {return &state{rate: rateK1024, outputLen: 64, dsbyte: dsbyteKeccak}}// 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)type state struct {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 byteoutputLen int // the default output size in bytesstate spongeDirection // whether the sponge is absorbing or squeezing}// BlockSize returns the rate of sponge underlying this hash function.func ( *state) () int { return .rate }// Size returns the output size of the hash function in bytes.func ( *state) () int { return .outputLen }// Reset clears the internal state by zeroing the sponge state and// the buffer indexes, and setting Sponge.state to absorbing.func ( *state) () {// Zero the permutation's state.for := range .a {.a[] = 0}.state = spongeAbsorbing.n = 0}func ( *state) () *state {:= *return &}// permute applies the KeccakF-1600 permutation.func ( *state) () {var *[25]uint64if cpu.IsBigEndian {= new([25]uint64)for := range {[] = binary.LittleEndian.Uint64(.a[*8:])}} else {= (*[25]uint64)(unsafe.Pointer(&.a))}keccakF1600().n = 0if cpu.IsBigEndian {for := range {binary.LittleEndian.PutUint64(.a[*8:], [])}}}// pads appends the domain separation bits in dsbyte, applies// the multi-bitrate 10..1 padding rule, and permutes the state.func ( *state) () {// 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. It panics if any// output has already been read.func ( *state) ( []byte) ( int, error) {if .state != spongeAbsorbing {panic("sha3: Write after Read")}= len()for len() > 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 ( *state) ( []byte) ( int, error) {// If we're still absorbing, pad and apply the permutation.if .state == spongeAbsorbing {.padAndPermute()}= len()// Now, do the squeezing.for len() > 0 {// Apply the permutation if we've squeezed the sponge dry.if .n == .rate {.permute()}:= copy(, .a[.n:.rate]).n +== [:]}return}// Sum applies padding to the hash state and then squeezes out the desired// number of output bytes. It panics if any output has already been read.func ( *state) ( []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()return append(, ...)}const (magicKeccak = "sha\x0b"// magic || rate || main state || n || sponge directionmarshaledSize = len(magicKeccak) + 1 + 200 + 1 + 1)func ( *state) () ([]byte, error) {return .AppendBinary(make([]byte, 0, marshaledSize))}func ( *state) ( []byte) ([]byte, error) {switch .dsbyte {case dsbyteKeccak:= 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 ( *state) ( []byte) error {if len() != marshaledSize {return errors.New("sha3: invalid hash state")}:= string([:len(magicKeccak)])= [len(magicKeccak):]switch {case == magicKeccak && .dsbyte == dsbyteKeccak:default:return errors.New("sha3: invalid hash state identifier")}:= int([0])= [1:]if != .rate {return errors.New("sha3: invalid hash state function")}copy(.a[:], )= [len(.a):], := int([0]), spongeDirection([1])if > .rate {return errors.New("sha3: invalid hash state")}.n =if != spongeAbsorbing && != spongeSqueezing {return errors.New("sha3: invalid hash state")}.state =return nil}
![]() |
The pages are generated with Golds v0.8.2. (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. |