@@ -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 | |||
} |
@@ -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 } |
@@ -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) | |||
} |
@@ -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 | |||
} |
@@ -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) { | |||
@@ -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} | |||
} | |||
@@ -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 | |||
} |
@@ -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 | |||
@@ -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] | |||
@@ -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} } |
@@ -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) { | |||