diff --git a/sha3/hashes.go b/sha3/hashes.go index 2b51cf4e..35e745c2 100644 --- a/sha3/hashes.go +++ b/sha3/hashes.go @@ -32,6 +32,12 @@ func New384() hash.Hash { return &state{rate: 104, outputLen: 48, dsbyte: 0x06} // and 256 bits against collision attacks. func New512() hash.Hash { 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() diff --git a/sha3/sha3_test.go b/sha3/sha3_test.go index 2c8719b4..b925a1c6 100644 --- a/sha3/sha3_test.go +++ b/sha3/sha3_test.go @@ -36,15 +36,16 @@ func newHashShake256() hash.Hash { } // testDigests contains functions returning hash.Hash instances -// with output-length equal to the KAT length for both SHA-3 and -// SHAKE instances. +// 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, - "SHAKE128": newHashShake128, - "SHAKE256": newHashShake256, + "SHA3-224": New224, + "SHA3-256": New256, + "SHA3-384": New384, + "SHA3-512": New512, + "Keccak-256": NewLegacyKeccak256, + "SHAKE128": newHashShake128, + "SHAKE256": newHashShake256, } // testShakes contains functions that return ShakeHash instances for @@ -124,6 +125,31 @@ 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) {