diff --git a/hash/sha3/hashes.go b/hash/sha3/hashes.go deleted file mode 100644 index 4fb38c0..0000000 --- a/hash/sha3/hashes.go +++ /dev/null @@ -1,91 +0,0 @@ -// 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 file provides functions for creating instances of the SHA-3 -// and SHAKE hash functions, as well as utility functions for hashing -// bytes. - -import ( - "hash" -) - -// New224 creates a new SHA3-224 hash. -// Its generic security strength is 224 bits against preimage attacks, -// and 112 bits against collision attacks. -func New224() hash.Hash { - if h := new224Asm(); h != nil { - return h - } - return &state{rate: 144, outputLen: 28, dsbyte: 0x06} -} - -// New256 creates a new SHA3-256 hash. -// Its generic security strength is 256 bits against preimage attacks, -// and 128 bits against collision attacks. -func New256() hash.Hash { - if h := new256Asm(); h != nil { - return h - } - return &state{rate: 136, outputLen: 32, dsbyte: 0x06} -} - -// New384 creates a new SHA3-384 hash. -// Its generic security strength is 384 bits against preimage attacks, -// and 192 bits against collision attacks. -func New384() hash.Hash { - if h := new384Asm(); h != nil { - return h - } - return &state{rate: 104, outputLen: 48, dsbyte: 0x06} -} - -// New512 creates a new SHA3-512 hash. -// Its generic security strength is 512 bits against preimage attacks, -// and 256 bits against collision attacks. -func New512() hash.Hash { - if h := new512Asm(); h != nil { - return h - } - return &state{rate: 72, outputLen: 64, dsbyte: 0x06} -} - -// 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 NewLegacyKeccak256() hash.Hash { return &state{rate: 136, outputLen: 32, dsbyte: 0x01} } - -// Sum224 returns the SHA3-224 digest of the data. -func Sum224(data []byte) (digest [28]byte) { - h := New224() - h.Write(data) - h.Sum(digest[:0]) - return -} - -// Sum256 returns the SHA3-256 digest of the data. -func Sum256(data []byte) (digest [32]byte) { - h := New256() - h.Write(data) - h.Sum(digest[:0]) - return -} - -// Sum384 returns the SHA3-384 digest of the data. -func Sum384(data []byte) (digest [48]byte) { - h := New384() - h.Write(data) - h.Sum(digest[:0]) - return -} - -// Sum512 returns the SHA3-512 digest of the data. -func Sum512(data []byte) (digest [64]byte) { - h := New512() - h.Write(data) - h.Sum(digest[:0]) - return -} diff --git a/hash/sha3/hashes_generic.go b/hash/sha3/hashes_generic.go deleted file mode 100644 index c4ff3f6..0000000 --- a/hash/sha3/hashes_generic.go +++ /dev/null @@ -1,27 +0,0 @@ -// Copyright 2017 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. - -//+build gccgo appengine !s390x - -package sha3 - -import ( - "hash" -) - -// new224Asm returns an assembly implementation of SHA3-224 if available, -// otherwise it returns nil. -func new224Asm() hash.Hash { return nil } - -// new256Asm returns an assembly implementation of SHA3-256 if available, -// otherwise it returns nil. -func new256Asm() hash.Hash { return nil } - -// new384Asm returns an assembly implementation of SHA3-384 if available, -// otherwise it returns nil. -func new384Asm() hash.Hash { return nil } - -// new512Asm returns an assembly implementation of SHA3-512 if available, -// otherwise it returns nil. -func new512Asm() hash.Hash { return nil } diff --git a/hash/sha3/register.go b/hash/sha3/register.go deleted file mode 100644 index 3cf6a22..0000000 --- a/hash/sha3/register.go +++ /dev/null @@ -1,18 +0,0 @@ -// 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. - -// +build go1.4 - -package sha3 - -import ( - "crypto" -) - -func init() { - crypto.RegisterHash(crypto.SHA3_224, New224) - crypto.RegisterHash(crypto.SHA3_256, New256) - crypto.RegisterHash(crypto.SHA3_384, New384) - crypto.RegisterHash(crypto.SHA3_512, New512) -} diff --git a/hash/sha3/sha3.go b/hash/sha3/sha3.go index b12a35c..f120ff4 100644 --- a/hash/sha3/sha3.go +++ b/hash/sha3/sha3.go @@ -4,6 +4,8 @@ package sha3 +import "hash" + // spongeDirection indicates the direction bytes are flowing through the sponge. type spongeDirection int @@ -38,8 +40,9 @@ type state struct { // [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 - storage [maxRate]byte + dsbyte byte + + storage storageBuf // Specific to SHA-3 and SHAKE. outputLen int // the default output size in bytes @@ -60,15 +63,15 @@ func (d *state) Reset() { d.a[i] = 0 } d.state = spongeAbsorbing - d.buf = d.storage[:0] + d.buf = d.storage.asBytes()[:0] } func (d *state) clone() *state { ret := *d if ret.state == spongeAbsorbing { - ret.buf = ret.storage[:len(ret.buf)] + ret.buf = ret.storage.asBytes()[:len(ret.buf)] } else { - ret.buf = ret.storage[d.rate-cap(d.buf) : d.rate] + ret.buf = ret.storage.asBytes()[d.rate-cap(d.buf) : d.rate] } return &ret @@ -82,13 +85,13 @@ func (d *state) permute() { // If we're absorbing, we need to xor the input into the state // before applying the permutation. xorIn(d, d.buf) - d.buf = d.storage[:0] + d.buf = d.storage.asBytes()[:0] keccakF1600(&d.a) case spongeSqueezing: // If we're squeezing, we need to apply the permutatin before // copying more output. keccakF1600(&d.a) - d.buf = d.storage[:d.rate] + d.buf = d.storage.asBytes()[:d.rate] copyOut(d, d.buf) } } @@ -97,7 +100,7 @@ func (d *state) permute() { // the multi-bitrate 10..1 padding rule, and permutes the state. func (d *state) padAndPermute(dsbyte byte) { if d.buf == nil { - d.buf = d.storage[:0] + d.buf = d.storage.asBytes()[:0] } // Pad with this instance's domain-separator bits. We know that there's // at least one byte of space in d.buf because, if it were full, @@ -105,7 +108,7 @@ func (d *state) padAndPermute(dsbyte byte) { // first one bit for the padding. See the comment in the state struct. d.buf = append(d.buf, dsbyte) zerosStart := len(d.buf) - d.buf = d.storage[:d.rate] + d.buf = d.storage.asBytes()[:d.rate] for i := zerosStart; i < d.rate; i++ { d.buf[i] = 0 } @@ -116,7 +119,7 @@ func (d *state) padAndPermute(dsbyte byte) { // Apply the permutation d.permute() d.state = spongeSqueezing - d.buf = d.storage[:d.rate] + d.buf = d.storage.asBytes()[:d.rate] copyOut(d, d.buf) } @@ -127,7 +130,7 @@ func (d *state) Write(p []byte) (written int, err error) { panic("sha3: write to sponge after read") } if d.buf == nil { - d.buf = d.storage[:0] + d.buf = d.storage.asBytes()[:0] } written = len(p) @@ -190,3 +193,63 @@ func (d *state) Sum(in []byte) []byte { dup.Read(hash) return append(in, hash...) } + +// New224 creates a new SHA3-224 hash. +// Its generic security strength is 224 bits against preimage attacks, +// and 112 bits against collision attacks. +func New224() hash.Hash { + return &state{rate: 144, outputLen: 28, dsbyte: 0x06} +} + +// New256 creates a new SHA3-256 hash. +// Its generic security strength is 256 bits against preimage attacks, +// and 128 bits against collision attacks. +func New256() hash.Hash { + return &state{rate: 136, outputLen: 32, dsbyte: 0x06} +} + +// New384 creates a new SHA3-384 hash. +// Its generic security strength is 384 bits against preimage attacks, +// and 192 bits against collision attacks. +func New384() hash.Hash { + return &state{rate: 104, outputLen: 48, dsbyte: 0x06} +} + +// New512 creates a new SHA3-512 hash. +// Its generic security strength is 512 bits against preimage attacks, +// and 256 bits against collision attacks. +func New512() hash.Hash { + return &state{rate: 72, outputLen: 64, dsbyte: 0x06} +} + +// Sum224 returns the SHA3-224 digest of the data. +func Sum224(data []byte) (digest [28]byte) { + h := New224() + h.Write(data) + h.Sum(digest[:0]) + return +} + +// Sum256 returns the SHA3-256 digest of the data. +func Sum256(data []byte) (digest [32]byte) { + h := New256() + h.Write(data) + h.Sum(digest[:0]) + return +} + +// Sum384 returns the SHA3-384 digest of the data. +func Sum384(data []byte) (digest [48]byte) { + h := New384() + h.Write(data) + h.Sum(digest[:0]) + return +} + +// Sum512 returns the SHA3-512 digest of the data. +func Sum512(data []byte) (digest [64]byte) { + h := New512() + h.Write(data) + h.Sum(digest[:0]) + return +} diff --git a/hash/sha3/sha3_test.go b/hash/sha3/sha3_test.go index d38876c..8426f5c 100644 --- a/hash/sha3/sha3_test.go +++ b/hash/sha3/sha3_test.go @@ -31,11 +31,10 @@ const ( // with output-length equal to the KAT length for SHA-3, Keccak // and SHAKE instances. var testDigests = map[string]func() hash.Hash{ - "SHA3-224": New224, - "SHA3-256": New256, - "SHA3-384": New384, - "SHA3-512": New512, - "Keccak-256": NewLegacyKeccak256, + "SHA3-224": New224, + "SHA3-256": New256, + "SHA3-384": New384, + "SHA3-512": New512, } // testShakes contains functions that return sha3.ShakeHash instances for @@ -156,31 +155,6 @@ func TestKeccakKats(t *testing.T) { }) } -// TestKeccak does a basic test of the non-standardized Keccak hash functions. -func TestKeccak(t *testing.T) { - tests := []struct { - fn func() hash.Hash - data []byte - want string - }{ - { - NewLegacyKeccak256, - []byte("abc"), - "4e03657aea45a94fc7d47ba826c8d667c0d1e6e33a64a036ec44f58fa12d6c45", - }, - } - - for _, u := range tests { - h := u.fn() - h.Write(u.data) - got := h.Sum(nil) - want := decodeHex(u.want) - if !bytes.Equal(got, want) { - t.Errorf("unexpected hash for size %d: got '%x' want '%s'", h.Size()*8, got, u.want) - } - } -} - // TestUnalignedWrite tests that writing data in an arbitrary pattern with // small input buffers. func TestUnalignedWrite(t *testing.T) { diff --git a/hash/sha3/shake.go b/hash/sha3/shake.go index a39e5d5..ef5fbc7 100644 --- a/hash/sha3/shake.go +++ b/hash/sha3/shake.go @@ -116,9 +116,6 @@ func (c *state) Clone() ShakeHash { // Its generic security strength is 128 bits against all attacks if at // least 32 bytes of its output are used. func NewShake128() ShakeHash { - if h := newShake128Asm(); h != nil { - return h - } return &state{rate: rate128, dsbyte: dsbyteShake} } @@ -126,9 +123,6 @@ func NewShake128() ShakeHash { // Its generic security strength is 256 bits against all attacks if // at least 64 bytes of its output are used. func NewShake256() ShakeHash { - if h := newShake256Asm(); h != nil { - return h - } return &state{rate: rate256, dsbyte: dsbyteShake} } diff --git a/hash/sha3/shake_generic.go b/hash/sha3/shake_generic.go deleted file mode 100644 index 73d0c90..0000000 --- a/hash/sha3/shake_generic.go +++ /dev/null @@ -1,19 +0,0 @@ -// Copyright 2017 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. - -//+build gccgo appengine !s390x - -package sha3 - -// newShake128Asm returns an assembly implementation of SHAKE-128 if available, -// otherwise it returns nil. -func newShake128Asm() ShakeHash { - return nil -} - -// newShake256Asm returns an assembly implementation of SHAKE-256 if available, -// otherwise it returns nil. -func newShake256Asm() ShakeHash { - return nil -} diff --git a/hash/sha3/xor.go b/hash/sha3/xor.go index 46a0d63..079b650 100644 --- a/hash/sha3/xor.go +++ b/hash/sha3/xor.go @@ -6,6 +6,13 @@ package sha3 +// A storageBuf is an aligned array of maxRate bytes. +type storageBuf [maxRate]byte + +func (b *storageBuf) asBytes() *[maxRate]byte { + return (*[maxRate]byte)(b) +} + var ( xorIn = xorInGeneric copyOut = copyOutGeneric diff --git a/hash/sha3/xor_unaligned.go b/hash/sha3/xor_unaligned.go index 929a486..a3d0686 100644 --- a/hash/sha3/xor_unaligned.go +++ b/hash/sha3/xor_unaligned.go @@ -9,9 +9,16 @@ package sha3 import "unsafe" +// A storageBuf is an aligned array of maxRate bytes. +type storageBuf [maxRate / 8]uint64 + +func (b *storageBuf) asBytes() *[maxRate]byte { + return (*[maxRate]byte)(unsafe.Pointer(b)) +} + func xorInUnaligned(d *state, buf []byte) { - bw := (*[maxRate / 8]uint64)(unsafe.Pointer(&buf[0])) n := len(buf) + bw := (*[maxRate / 8]uint64)(unsafe.Pointer(&buf[0]))[: n/8 : n/8] if n >= 72 { d.a[0] ^= bw[0] d.a[1] ^= bw[1] diff --git a/hash/shake/sha3.go b/hash/shake/sha3.go index 74a9e75..a8526ee 100644 --- a/hash/shake/sha3.go +++ b/hash/shake/sha3.go @@ -4,8 +4,6 @@ package shake -import "hash" - // spongeDirection indicates the direction bytes are flowing through the sponge. type spongeDirection int @@ -193,7 +191,3 @@ func (d *state) Sum(in []byte) []byte { dup.Read(hash) return append(in, 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 NewLegacyKeccak256() hash.Hash { return &state{rate: 136, outputLen: 32, dsbyte: 0x01} } diff --git a/hash/shake/sha3_test.go b/hash/shake/sha3_test.go index 19539fe..1457c83 100644 --- a/hash/shake/sha3_test.go +++ b/hash/shake/sha3_test.go @@ -112,31 +112,6 @@ func TestKeccakKats(t *testing.T) { } } -// TestKeccak does a basic test of the non-standardized Keccak hash functions. -func TestKeccak(t *testing.T) { - tests := []struct { - fn func() hash.Hash - data []byte - want string - }{ - { - NewLegacyKeccak256, - []byte("abc"), - "4e03657aea45a94fc7d47ba826c8d667c0d1e6e33a64a036ec44f58fa12d6c45", - }, - } - - for _, u := range tests { - h := u.fn() - h.Write(u.data) - got := h.Sum(nil) - want := decodeHex(u.want) - if !bytes.Equal(got, want) { - t.Errorf("unexpected hash for size %d: got '%x' want '%s'", h.Size()*8, got, u.want) - } - } -} - // TestUnalignedWrite tests that writing data in an arbitrary pattern with // small input buffers. func TestUnalignedWrite(t *testing.T) {