]> Cypherpunks repositories - gostls13.git/commitdiff
crypto/sha3: new package
authorFilippo Valsorda <filippo@golang.org>
Mon, 18 Nov 2024 15:58:49 +0000 (16:58 +0100)
committerGopher Robot <gobot@golang.org>
Fri, 22 Nov 2024 01:58:53 +0000 (01:58 +0000)
Implement the SHA-3 hash algorithms and the SHAKE extendable output
functions defined in FIPS 202.

This is a wrapper for crypto/internal/fips/sha3 which in turn was ported
from x/crypto/sha3 in CL 616717 as part of #65269.

Fixes #69982

Change-Id: I64ce7f362c1a773f7f5b05f7e0acb4110e52a329
Reviewed-on: https://go-review.googlesource.com/c/go/+/629176
Reviewed-by: Russ Cox <rsc@golang.org>
Auto-Submit: Filippo Valsorda <filippo@golang.org>
LUCI-TryBot-Result: Go LUCI <golang-scoped@luci-project-accounts.iam.gserviceaccount.com>
Reviewed-by: Dmitri Shuralyov <dmitshur@google.com>
api/next/69982.txt [new file with mode: 0644]
doc/next/6-stdlib/5-sha3.md [new file with mode: 0644]
doc/next/6-stdlib/99-minor/crypto/sha3/69982.md [new file with mode: 0644]
src/crypto/sha3/sha3.go [new file with mode: 0644]
src/crypto/sha3/sha3_test.go [moved from src/crypto/internal/fips140test/sha3_test.go with 62% similarity]
src/go/build/deps_test.go

diff --git a/api/next/69982.txt b/api/next/69982.txt
new file mode 100644 (file)
index 0000000..24f5954
--- /dev/null
@@ -0,0 +1,31 @@
+pkg crypto/sha3, func New224() *SHA3 #69982
+pkg crypto/sha3, func New256() *SHA3 #69982
+pkg crypto/sha3, func New384() *SHA3 #69982
+pkg crypto/sha3, func New512() *SHA3 #69982
+pkg crypto/sha3, func NewCSHAKE128([]uint8, []uint8) *SHAKE #69982
+pkg crypto/sha3, func NewCSHAKE256([]uint8, []uint8) *SHAKE #69982
+pkg crypto/sha3, func NewSHAKE128() *SHAKE #69982
+pkg crypto/sha3, func NewSHAKE256() *SHAKE #69982
+pkg crypto/sha3, func Sum224([]uint8) [28]uint8 #69982
+pkg crypto/sha3, func Sum256([]uint8) [32]uint8 #69982
+pkg crypto/sha3, func Sum384([]uint8) [48]uint8 #69982
+pkg crypto/sha3, func Sum512([]uint8) [64]uint8 #69982
+pkg crypto/sha3, func SumSHAKE128([]uint8, int) []uint8 #69982
+pkg crypto/sha3, func SumSHAKE256([]uint8, int) []uint8 #69982
+pkg crypto/sha3, method (*SHA3) AppendBinary([]uint8) ([]uint8, error) #69982
+pkg crypto/sha3, method (*SHA3) BlockSize() int #69982
+pkg crypto/sha3, method (*SHA3) MarshalBinary() ([]uint8, error) #69982
+pkg crypto/sha3, method (*SHA3) Reset() #69982
+pkg crypto/sha3, method (*SHA3) Size() int #69982
+pkg crypto/sha3, method (*SHA3) Sum([]uint8) []uint8 #69982
+pkg crypto/sha3, method (*SHA3) UnmarshalBinary([]uint8) error #69982
+pkg crypto/sha3, method (*SHA3) Write([]uint8) (int, error) #69982
+pkg crypto/sha3, method (*SHAKE) AppendBinary([]uint8) ([]uint8, error) #69982
+pkg crypto/sha3, method (*SHAKE) BlockSize() int #69982
+pkg crypto/sha3, method (*SHAKE) MarshalBinary() ([]uint8, error) #69982
+pkg crypto/sha3, method (*SHAKE) Read([]uint8) (int, error) #69982
+pkg crypto/sha3, method (*SHAKE) Reset() #69982
+pkg crypto/sha3, method (*SHAKE) UnmarshalBinary([]uint8) error #69982
+pkg crypto/sha3, method (*SHAKE) Write([]uint8) (int, error) #69982
+pkg crypto/sha3, type SHA3 struct #69982
+pkg crypto/sha3, type SHAKE struct #69982
diff --git a/doc/next/6-stdlib/5-sha3.md b/doc/next/6-stdlib/5-sha3.md
new file mode 100644 (file)
index 0000000..61d5872
--- /dev/null
@@ -0,0 +1,6 @@
+### New sha3 package
+
+The new [crypto/sha3] package implements the SHA-3 hash function, and SHAKE and
+cSHAKE extendable-output functions.
+
+It was imported from `golang.org/x/crypto/sha3`.
diff --git a/doc/next/6-stdlib/99-minor/crypto/sha3/69982.md b/doc/next/6-stdlib/99-minor/crypto/sha3/69982.md
new file mode 100644 (file)
index 0000000..a6975cb
--- /dev/null
@@ -0,0 +1 @@
+<!-- This is a new package; covered in 6-stdlib/5-sha3.md. -->
diff --git a/src/crypto/sha3/sha3.go b/src/crypto/sha3/sha3.go
new file mode 100644 (file)
index 0000000..0f4d7ed
--- /dev/null
@@ -0,0 +1,233 @@
+// Copyright 2024 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 hash algorithms and the SHAKE extendable
+// output functions defined in FIPS 202.
+package sha3
+
+import (
+       "crypto"
+       "crypto/internal/fips140/sha3"
+       "hash"
+)
+
+func init() {
+       crypto.RegisterHash(crypto.SHA3_224, func() hash.Hash { return New224() })
+       crypto.RegisterHash(crypto.SHA3_256, func() hash.Hash { return New256() })
+       crypto.RegisterHash(crypto.SHA3_384, func() hash.Hash { return New384() })
+       crypto.RegisterHash(crypto.SHA3_512, func() hash.Hash { return New512() })
+}
+
+// Sum224 returns the SHA3-224 hash of data.
+func Sum224(data []byte) [28]byte {
+       var out [28]byte
+       h := sha3.New224()
+       h.Write(data)
+       h.Sum(out[:0])
+       return out
+}
+
+// Sum256 returns the SHA3-256 hash of data.
+func Sum256(data []byte) [32]byte {
+       var out [32]byte
+       h := sha3.New256()
+       h.Write(data)
+       h.Sum(out[:0])
+       return out
+}
+
+// Sum384 returns the SHA3-384 hash of data.
+func Sum384(data []byte) [48]byte {
+       var out [48]byte
+       h := sha3.New384()
+       h.Write(data)
+       h.Sum(out[:0])
+       return out
+}
+
+// Sum512 returns the SHA3-512 hash of data.
+func Sum512(data []byte) [64]byte {
+       var out [64]byte
+       h := sha3.New512()
+       h.Write(data)
+       h.Sum(out[:0])
+       return out
+}
+
+// SumSHAKE128 applies the SHAKE128 extendable output function to data and
+// returns an output of the given length in bytes.
+func SumSHAKE128(data []byte, length int) []byte {
+       // Outline the allocation for up to 256 bits of output to the caller's stack.
+       out := make([]byte, 32)
+       return sumSHAKE128(out, data, length)
+}
+
+func sumSHAKE128(out, data []byte, length int) []byte {
+       if len(out) < length {
+               out = make([]byte, length)
+       } else {
+               out = out[:length]
+       }
+       h := sha3.NewShake128()
+       h.Write(data)
+       h.Read(out)
+       return out
+}
+
+// SumSHAKE256 applies the SHAKE256 extendable output function to data and
+// returns an output of the given length in bytes.
+func SumSHAKE256(data []byte, length int) []byte {
+       // Outline the allocation for up to 512 bits of output to the caller's stack.
+       out := make([]byte, 64)
+       return sumSHAKE256(out, data, length)
+}
+
+func sumSHAKE256(out, data []byte, length int) []byte {
+       if len(out) < length {
+               out = make([]byte, length)
+       } else {
+               out = out[:length]
+       }
+       h := sha3.NewShake256()
+       h.Write(data)
+       h.Read(out)
+       return out
+}
+
+// SHA3 is an instance of a SHA-3 hash. It implements [hash.Hash].
+type SHA3 struct {
+       s sha3.Digest
+}
+
+// New224 creates a new SHA3-224 hash.
+func New224() *SHA3 {
+       return &SHA3{*sha3.New224()}
+}
+
+// New256 creates a new SHA3-256 hash.
+func New256() *SHA3 {
+       return &SHA3{*sha3.New256()}
+}
+
+// New384 creates a new SHA3-384 hash.
+func New384() *SHA3 {
+       return &SHA3{*sha3.New384()}
+}
+
+// New512 creates a new SHA3-512 hash.
+func New512() *SHA3 {
+       return &SHA3{*sha3.New512()}
+}
+
+// Write absorbs more data into the hash's state.
+func (s *SHA3) Write(p []byte) (n int, err error) {
+       return s.s.Write(p)
+}
+
+// Sum appends the current hash to b and returns the resulting slice.
+func (s *SHA3) Sum(b []byte) []byte {
+       return s.s.Sum(b)
+}
+
+// Reset resets the hash to its initial state.
+func (s *SHA3) Reset() {
+       s.s.Reset()
+}
+
+// Size returns the number of bytes Sum will produce.
+func (s *SHA3) Size() int {
+       return s.s.Size()
+}
+
+// BlockSize returns the hash's rate.
+func (s *SHA3) BlockSize() int {
+       return s.s.BlockSize()
+}
+
+// MarshalBinary implements [encoding.BinaryMarshaler].
+func (s *SHA3) MarshalBinary() ([]byte, error) {
+       return s.s.MarshalBinary()
+}
+
+// AppendBinary implements [encoding.BinaryAppender].
+func (s *SHA3) AppendBinary(p []byte) ([]byte, error) {
+       return s.s.AppendBinary(p)
+}
+
+// UnmarshalBinary implements [encoding.BinaryUnmarshaler].
+func (s *SHA3) UnmarshalBinary(data []byte) error {
+       return s.s.UnmarshalBinary(data)
+}
+
+// SHAKE is an instance of a SHAKE extendable output function.
+type SHAKE struct {
+       s sha3.SHAKE
+}
+
+// NewSHAKE128 creates a new SHAKE128 XOF.
+func NewSHAKE128() *SHAKE {
+       return &SHAKE{*sha3.NewShake128()}
+}
+
+// NewSHAKE256 creates a new SHAKE256 XOF.
+func NewSHAKE256() *SHAKE {
+       return &SHAKE{*sha3.NewShake256()}
+}
+
+// NewCSHAKE128 creates a new cSHAKE128 XOF.
+//
+// N is used to define functions based on cSHAKE, it can be empty when plain
+// cSHAKE is desired. S is a customization byte string used for domain
+// separation. When N and S are both empty, this is equivalent to NewSHAKE128.
+func NewCSHAKE128(N, S []byte) *SHAKE {
+       return &SHAKE{*sha3.NewCShake128(N, S)}
+}
+
+// NewCSHAKE256 creates a new cSHAKE256 XOF.
+//
+// N is used to define functions based on cSHAKE, it can be empty when plain
+// cSHAKE is desired. S is a customization byte string used for domain
+// separation. When N and S are both empty, this is equivalent to NewSHAKE256.
+func NewCSHAKE256(N, S []byte) *SHAKE {
+       return &SHAKE{*sha3.NewCShake256(N, S)}
+}
+
+// Write absorbs more data into the XOF's state.
+//
+// It panics if any output has already been read.
+func (s *SHAKE) Write(p []byte) (n int, err error) {
+       return s.s.Write(p)
+}
+
+// Read squeezes more output from the XOF.
+//
+// Any call to Write after a call to Read will panic.
+func (s *SHAKE) Read(p []byte) (n int, err error) {
+       return s.s.Read(p)
+}
+
+// Reset resets the XOF to its initial state.
+func (s *SHAKE) Reset() {
+       s.s.Reset()
+}
+
+// BlockSize returns the rate of the XOF.
+func (s *SHAKE) BlockSize() int {
+       return s.s.BlockSize()
+}
+
+// MarshalBinary implements [encoding.BinaryMarshaler].
+func (s *SHAKE) MarshalBinary() ([]byte, error) {
+       return s.s.MarshalBinary()
+}
+
+// AppendBinary implements [encoding.BinaryAppender].
+func (s *SHAKE) AppendBinary(p []byte) ([]byte, error) {
+       return s.s.AppendBinary(p)
+}
+
+// UnmarshalBinary implements [encoding.BinaryUnmarshaler].
+func (s *SHAKE) UnmarshalBinary(data []byte) error {
+       return s.s.UnmarshalBinary(data)
+}
similarity index 62%
rename from src/crypto/internal/fips140test/sha3_test.go
rename to src/crypto/sha3/sha3_test.go
index 2bc2a6df2375e6a73b8ecd352481f2e8a85310bb..f88e51d3e746e27170eeb50fea9774ca1ba3db8a 100644 (file)
@@ -2,82 +2,30 @@
 // Use of this source code is governed by a BSD-style
 // license that can be found in the LICENSE file.
 
-package fipstest_test
-
-// TODO(fips, #69982): move to the crypto/sha3 package once it exists.
+package sha3_test
 
 import (
        "bytes"
        "crypto/internal/cryptotest"
        "crypto/internal/fips140"
-       . "crypto/internal/fips140/sha3"
-       "encoding"
+       . "crypto/sha3"
        "encoding/hex"
-       "fmt"
        "io"
        "math/rand"
        "strings"
        "testing"
 )
 
-// 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
-}
-
-// ShakeSum128 writes an arbitrary-length digest of data into hash.
-func ShakeSum128(hash, data []byte) {
-       h := NewShake128()
-       h.Write(data)
-       h.Read(hash)
-}
-
-// ShakeSum256 writes an arbitrary-length digest of data into hash.
-func ShakeSum256(hash, data []byte) {
-       h := NewShake256()
-       h.Write(data)
-       h.Read(hash)
-}
-
 const testString = "brekeccakkeccak koax koax"
 
 // testDigests contains functions returning hash.Hash instances
 // with output-length equal to the KAT length for SHA-3, Keccak
 // and SHAKE instances.
-var testDigests = map[string]func() *Digest{
-       "SHA3-224":   New224,
-       "SHA3-256":   New256,
-       "SHA3-384":   New384,
-       "SHA3-512":   New512,
-       "Keccak-256": NewLegacyKeccak256,
-       "Keccak-512": NewLegacyKeccak512,
+var testDigests = map[string]func() *SHA3{
+       "SHA3-224": New224,
+       "SHA3-256": New256,
+       "SHA3-384": New384,
+       "SHA3-512": New512,
 }
 
 // testShakes contains functions that return *sha3.SHAKE instances for
@@ -87,11 +35,11 @@ var testShakes = map[string]struct {
        defAlgoName  string
        defCustomStr string
 }{
-       // NewCShake without customization produces same result as SHAKE
-       "SHAKE128":  {NewCShake128, "", ""},
-       "SHAKE256":  {NewCShake256, "", ""},
-       "cSHAKE128": {NewCShake128, "CSHAKE128", "CustomString"},
-       "cSHAKE256": {NewCShake256, "CSHAKE256", "CustomString"},
+       // NewCSHAKE without customization produces same result as SHAKE
+       "SHAKE128":  {NewCSHAKE128, "", ""},
+       "SHAKE256":  {NewCSHAKE256, "", ""},
+       "cSHAKE128": {NewCSHAKE128, "CSHAKE128", "CustomString"},
+       "cSHAKE256": {NewCSHAKE256, "CSHAKE256", "CustomString"},
 }
 
 // decodeHex converts a hex-encoded string into a raw byte string.
@@ -103,72 +51,6 @@ func decodeHex(s string) []byte {
        return b
 }
 
-// TestKeccak does a basic test of the non-standardized Keccak hash functions.
-func TestKeccak(t *testing.T) {
-       cryptotest.TestAllImplementations(t, "sha3", testKeccak)
-}
-
-func testKeccak(t *testing.T) {
-       tests := []struct {
-               fn   func() *Digest
-               data []byte
-               want string
-       }{
-               {
-                       NewLegacyKeccak256,
-                       []byte("abc"),
-                       "4e03657aea45a94fc7d47ba826c8d667c0d1e6e33a64a036ec44f58fa12d6c45",
-               },
-               {
-                       NewLegacyKeccak512,
-                       []byte("abc"),
-                       "18587dc2ea106b9a1563e32b3312421ca164c7f1f07bc922a9c83d77cea3a1e5d0c69910739025372dc14ac9642629379540c17e2a65b19d77aa511a9d00bb96",
-               },
-       }
-
-       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)
-               }
-       }
-}
-
-// TestShakeSum tests that the output of Sum matches the output of Read.
-func TestShakeSum(t *testing.T) {
-       cryptotest.TestAllImplementations(t, "sha3", testShakeSum)
-}
-
-func testShakeSum(t *testing.T) {
-       tests := [...]struct {
-               name        string
-               hash        *SHAKE
-               expectedLen int
-       }{
-               {"SHAKE128", NewShake128(), 32},
-               {"SHAKE256", NewShake256(), 64},
-               {"cSHAKE128", NewCShake128([]byte{'X'}, nil), 32},
-               {"cSHAKE256", NewCShake256([]byte{'X'}, nil), 64},
-       }
-
-       for _, test := range tests {
-               t.Run(test.name, func(t *testing.T) {
-                       s := test.hash.Sum(nil)
-                       if len(s) != test.expectedLen {
-                               t.Errorf("Unexpected digest length: got %d, want %d", len(s), test.expectedLen)
-                       }
-                       r := make([]byte, test.expectedLen)
-                       test.hash.Read(r)
-                       if !bytes.Equal(s, r) {
-                               t.Errorf("Mismatch between Sum and Read:\nSum:  %s\nRead: %s", hex.EncodeToString(s), hex.EncodeToString(r))
-                       }
-               })
-       }
-}
-
 // TestUnalignedWrite tests that writing data in an arbitrary pattern with
 // small input buffers.
 func TestUnalignedWrite(t *testing.T) {
@@ -336,36 +218,6 @@ func testReset(t *testing.T) {
        }
 }
 
-func TestClone(t *testing.T) {
-       cryptotest.TestAllImplementations(t, "sha3", testClone)
-}
-
-func testClone(t *testing.T) {
-       out1 := make([]byte, 16)
-       out2 := make([]byte, 16)
-
-       // Test for sizes smaller and larger than block size.
-       for _, size := range []int{0x1, 0x100} {
-               in := sequentialBytes(size)
-               for _, v := range testShakes {
-                       h1 := v.constructor(nil, []byte{0x01})
-                       h1.Write([]byte{0x01})
-
-                       h2 := h1.Clone()
-
-                       h1.Write(in)
-                       h1.Read(out1)
-
-                       h2.Write(in)
-                       h2.Read(out2)
-
-                       if !bytes.Equal(out1, out2) {
-                               t.Error("\nExpected:\n", hex.EncodeToString(out1), "\ngot:\n", hex.EncodeToString(out2))
-                       }
-               }
-       }
-}
-
 var sinkSHA3 byte
 
 func TestAllocations(t *testing.T) {
@@ -382,14 +234,12 @@ func TestAllocations(t *testing.T) {
                        t.Errorf("expected zero allocations, got %0.1f", allocs)
                }
        })
-       t.Run("NewShake", func(t *testing.T) {
+       t.Run("NewSHAKE", func(t *testing.T) {
                if allocs := testing.AllocsPerRun(10, func() {
-                       h := NewShake128()
+                       h := NewSHAKE128()
                        b := []byte("ABC")
                        h.Write(b)
-                       out := make([]byte, 0, 32)
-                       out = h.Sum(out)
-                       sinkSHA3 ^= out[0]
+                       out := make([]byte, 32)
                        h.Read(out)
                        sinkSHA3 ^= out[0]
                }); allocs > 0 {
@@ -405,6 +255,15 @@ func TestAllocations(t *testing.T) {
                        t.Errorf("expected zero allocations, got %0.1f", allocs)
                }
        })
+       t.Run("SumSHAKE", func(t *testing.T) {
+               if allocs := testing.AllocsPerRun(10, func() {
+                       b := []byte("ABC")
+                       out := SumSHAKE128(b, 10)
+                       sinkSHA3 ^= out[0]
+               }); allocs > 0 {
+                       t.Errorf("expected zero allocations, got %0.1f", allocs)
+               }
+       })
 }
 
 func TestCSHAKEAccumulated(t *testing.T) {
@@ -453,19 +312,19 @@ func TestCSHAKEAccumulated(t *testing.T) {
        //
        cryptotest.TestAllImplementations(t, "sha3", func(t *testing.T) {
                t.Run("cSHAKE128", func(t *testing.T) {
-                       testCSHAKEAccumulated(t, NewCShake128, (1600-256)/8,
+                       testCSHAKEAccumulated(t, NewCSHAKE128, (1600-256)/8,
                                "bb14f8657c6ec5403d0b0e2ef3d3393497e9d3b1a9a9e8e6c81dbaa5fd809252")
                })
                t.Run("cSHAKE256", func(t *testing.T) {
-                       testCSHAKEAccumulated(t, NewCShake256, (1600-512)/8,
+                       testCSHAKEAccumulated(t, NewCSHAKE256, (1600-512)/8,
                                "0baaf9250c6e25f0c14ea5c7f9bfde54c8a922c8276437db28f3895bdf6eeeef")
                })
        })
 }
 
-func testCSHAKEAccumulated(t *testing.T, newCShake func(N, S []byte) *SHAKE, rate int64, exp string) {
-       rnd := newCShake(nil, nil)
-       acc := newCShake(nil, nil)
+func testCSHAKEAccumulated(t *testing.T, newCSHAKE func(N, S []byte) *SHAKE, rate int64, exp string) {
+       rnd := newCSHAKE(nil, nil)
+       acc := newCSHAKE(nil, nil)
        for n := 0; n < 200; n++ {
                N := make([]byte, n)
                rnd.Read(N)
@@ -473,7 +332,7 @@ func testCSHAKEAccumulated(t *testing.T, newCShake func(N, S []byte) *SHAKE, rat
                        S := make([]byte, s)
                        rnd.Read(S)
 
-                       c := newCShake(N, S)
+                       c := newCSHAKE(N, S)
                        io.CopyN(c, rnd, 100 /* < rate */)
                        io.CopyN(acc, c, 200)
 
@@ -486,7 +345,9 @@ func testCSHAKEAccumulated(t *testing.T, newCShake func(N, S []byte) *SHAKE, rat
                        io.CopyN(acc, c, 200)
                }
        }
-       if got := hex.EncodeToString(acc.Sum(nil)[:32]); got != exp {
+       out := make([]byte, 32)
+       acc.Read(out)
+       if got := hex.EncodeToString(out); got != exp {
                t.Errorf("got %s, want %s", got, exp)
        }
 }
@@ -503,10 +364,12 @@ func testCSHAKELargeS(t *testing.T) {
        // See https://go.dev/issue/66232.
        const s = (1<<32)/8 + 1000 // s * 8 > 2^32
        S := make([]byte, s)
-       rnd := NewShake128()
+       rnd := NewSHAKE128()
        rnd.Read(S)
-       c := NewCShake128(nil, S)
+       c := NewCSHAKE128(nil, S)
        io.CopyN(c, rnd, 1000)
+       out := make([]byte, 32)
+       c.Read(out)
 
        // Generated with pycryptodome@3.20.0
        //
@@ -518,7 +381,7 @@ func testCSHAKELargeS(t *testing.T) {
        //    print(c.read(32).hex())
        //
        exp := "2cb9f237767e98f2614b8779cf096a52da9b3a849280bbddec820771ae529cf0"
-       if got := hex.EncodeToString(c.Sum(nil)); got != exp {
+       if got := hex.EncodeToString(out); got != exp {
                t.Errorf("got %s, want %s", got, exp)
        }
 }
@@ -529,17 +392,15 @@ func TestMarshalUnmarshal(t *testing.T) {
                t.Run("SHA3-256", func(t *testing.T) { testMarshalUnmarshal(t, New256()) })
                t.Run("SHA3-384", func(t *testing.T) { testMarshalUnmarshal(t, New384()) })
                t.Run("SHA3-512", func(t *testing.T) { testMarshalUnmarshal(t, New512()) })
-               t.Run("SHAKE128", func(t *testing.T) { testMarshalUnmarshal(t, NewShake128()) })
-               t.Run("SHAKE256", func(t *testing.T) { testMarshalUnmarshal(t, NewShake256()) })
-               t.Run("cSHAKE128", func(t *testing.T) { testMarshalUnmarshal(t, NewCShake128([]byte("N"), []byte("S"))) })
-               t.Run("cSHAKE256", func(t *testing.T) { testMarshalUnmarshal(t, NewCShake256([]byte("N"), []byte("S"))) })
-               t.Run("Keccak-256", func(t *testing.T) { testMarshalUnmarshal(t, NewLegacyKeccak256()) })
-               t.Run("Keccak-512", func(t *testing.T) { testMarshalUnmarshal(t, NewLegacyKeccak512()) })
+               t.Run("SHAKE128", func(t *testing.T) { testMarshalUnmarshalSHAKE(t, NewSHAKE128()) })
+               t.Run("SHAKE256", func(t *testing.T) { testMarshalUnmarshalSHAKE(t, NewSHAKE256()) })
+               t.Run("cSHAKE128", func(t *testing.T) { testMarshalUnmarshalSHAKE(t, NewCSHAKE128([]byte("N"), []byte("S"))) })
+               t.Run("cSHAKE256", func(t *testing.T) { testMarshalUnmarshalSHAKE(t, NewCSHAKE256([]byte("N"), []byte("S"))) })
        })
 }
 
 // TODO(filippo): move this to crypto/internal/cryptotest.
-func testMarshalUnmarshal(t *testing.T, h fips140.Hash) {
+func testMarshalUnmarshal(t *testing.T, h *SHA3) {
        buf := make([]byte, 200)
        rand.Read(buf)
        n := rand.Intn(200)
@@ -547,12 +408,12 @@ func testMarshalUnmarshal(t *testing.T, h fips140.Hash) {
        want := h.Sum(nil)
        h.Reset()
        h.Write(buf[:n])
-       b, err := h.(encoding.BinaryMarshaler).MarshalBinary()
+       b, err := h.MarshalBinary()
        if err != nil {
                t.Errorf("MarshalBinary: %v", err)
        }
        h.Write(bytes.Repeat([]byte{0}, 200))
-       if err := h.(encoding.BinaryUnmarshaler).UnmarshalBinary(b); err != nil {
+       if err := h.UnmarshalBinary(b); err != nil {
                t.Errorf("UnmarshalBinary: %v", err)
        }
        h.Write(buf[n:])
@@ -562,6 +423,32 @@ func testMarshalUnmarshal(t *testing.T, h fips140.Hash) {
        }
 }
 
+// TODO(filippo): move this to crypto/internal/cryptotest.
+func testMarshalUnmarshalSHAKE(t *testing.T, h *SHAKE) {
+       buf := make([]byte, 200)
+       rand.Read(buf)
+       n := rand.Intn(200)
+       h.Write(buf)
+       want := make([]byte, 32)
+       h.Read(want)
+       h.Reset()
+       h.Write(buf[:n])
+       b, err := h.MarshalBinary()
+       if err != nil {
+               t.Errorf("MarshalBinary: %v", err)
+       }
+       h.Write(bytes.Repeat([]byte{0}, 200))
+       if err := h.UnmarshalBinary(b); err != nil {
+               t.Errorf("UnmarshalBinary: %v", err)
+       }
+       h.Write(buf[n:])
+       got := make([]byte, 32)
+       h.Read(got)
+       if !bytes.Equal(got, want) {
+               t.Errorf("got %x, want %x", got, want)
+       }
+}
+
 // benchmarkHash tests the speed to hash num buffers of buflen each.
 func benchmarkHash(b *testing.B, h fips140.Hash, size, num int) {
        b.StopTimer()
@@ -606,69 +493,9 @@ func BenchmarkSha3_384_MTU(b *testing.B) { benchmarkHash(b, New384(), 1350, 1) }
 func BenchmarkSha3_256_MTU(b *testing.B) { benchmarkHash(b, New256(), 1350, 1) }
 func BenchmarkSha3_224_MTU(b *testing.B) { benchmarkHash(b, New224(), 1350, 1) }
 
-func BenchmarkShake128_MTU(b *testing.B)  { benchmarkShake(b, NewShake128(), 1350, 1) }
-func BenchmarkShake256_MTU(b *testing.B)  { benchmarkShake(b, NewShake256(), 1350, 1) }
-func BenchmarkShake256_16x(b *testing.B)  { benchmarkShake(b, NewShake256(), 16, 1024) }
-func BenchmarkShake256_1MiB(b *testing.B) { benchmarkShake(b, NewShake256(), 1024, 1024) }
+func BenchmarkShake128_MTU(b *testing.B)  { benchmarkShake(b, NewSHAKE128(), 1350, 1) }
+func BenchmarkShake256_MTU(b *testing.B)  { benchmarkShake(b, NewSHAKE256(), 1350, 1) }
+func BenchmarkShake256_16x(b *testing.B)  { benchmarkShake(b, NewSHAKE256(), 16, 1024) }
+func BenchmarkShake256_1MiB(b *testing.B) { benchmarkShake(b, NewSHAKE256(), 1024, 1024) }
 
 func BenchmarkSha3_512_1MiB(b *testing.B) { benchmarkHash(b, New512(), 1024, 1024) }
-
-func Example_sum() {
-       buf := []byte("some data to hash")
-       // A hash needs to be 64 bytes long to have 256-bit collision resistance.
-       h := make([]byte, 64)
-       // Compute a 64-byte hash of buf and put it in h.
-       ShakeSum256(h, buf)
-       fmt.Printf("%x\n", h)
-       // Output: 0f65fe41fc353e52c55667bb9e2b27bfcc8476f2c413e9437d272ee3194a4e3146d05ec04a25d16b8f577c19b82d16b1424c3e022e783d2b4da98de3658d363d
-}
-
-func Example_mac() {
-       k := []byte("this is a secret key; you should generate a strong random key that's at least 32 bytes long")
-       buf := []byte("and this is some data to authenticate")
-       // A MAC with 32 bytes of output has 256-bit security strength -- if you use at least a 32-byte-long key.
-       h := make([]byte, 32)
-       d := NewShake256()
-       // Write the key into the hash.
-       d.Write(k)
-       // Now write the data.
-       d.Write(buf)
-       // Read 32 bytes of output from the hash into h.
-       d.Read(h)
-       fmt.Printf("%x\n", h)
-       // Output: 78de2974bd2711d5549ffd32b753ef0f5fa80a0db2556db60f0987eb8a9218ff
-}
-
-func ExampleNewCShake256() {
-       out := make([]byte, 32)
-       msg := []byte("The quick brown fox jumps over the lazy dog")
-
-       // Example 1: Simple cshake
-       c1 := NewCShake256([]byte("NAME"), []byte("Partition1"))
-       c1.Write(msg)
-       c1.Read(out)
-       fmt.Println(hex.EncodeToString(out))
-
-       // Example 2: Different customization string produces different digest
-       c1 = NewCShake256([]byte("NAME"), []byte("Partition2"))
-       c1.Write(msg)
-       c1.Read(out)
-       fmt.Println(hex.EncodeToString(out))
-
-       // Example 3: Longer output length produces longer digest
-       out = make([]byte, 64)
-       c1 = NewCShake256([]byte("NAME"), []byte("Partition1"))
-       c1.Write(msg)
-       c1.Read(out)
-       fmt.Println(hex.EncodeToString(out))
-
-       // Example 4: Next read produces different result
-       c1.Read(out)
-       fmt.Println(hex.EncodeToString(out))
-
-       // Output:
-       //a90a4c6ca9af2156eba43dc8398279e6b60dcd56fb21837afe6c308fd4ceb05b
-       //a8db03e71f3e4da5c4eee9d28333cdd355f51cef3c567e59be5beb4ecdbb28f0
-       //a90a4c6ca9af2156eba43dc8398279e6b60dcd56fb21837afe6c308fd4ceb05b9dd98c6ee866ca7dc5a39d53e960f400bcd5a19c8a2d6ec6459f63696543a0d8
-       //85e73a72228d08b46515553ca3a29d47df3047e5d84b12d6c2c63e579f4fd1105716b7838e92e981863907f434bfd4443c9e56ea09da998d2f9b47db71988109
-}
index 4ff73b08c3ba80af3bc7f52675531e7de61da0ba..d888017a927751065da06693103cb231363aaeb3 100644 (file)
@@ -503,7 +503,8 @@ var depsRules = `
        hash, embed
        < crypto
        < crypto/subtle
-       < crypto/cipher;
+       < crypto/cipher
+       < crypto/sha3;
 
        crypto/cipher,
        crypto/internal/boring/bcache
@@ -519,9 +520,6 @@ var depsRules = `
 
        crypto/hmac < crypto/pbkdf2;
 
-       # Unfortunately, stuck with reflect via encoding/binary.
-       encoding/binary, crypto/boring < golang.org/x/crypto/sha3;
-
        crypto/aes,
        crypto/des,
        crypto/ecdh,
@@ -531,7 +529,7 @@ var depsRules = `
        crypto/sha1,
        crypto/sha256,
        crypto/sha512,
-       golang.org/x/crypto/sha3,
+       crypto/sha3,
        crypto/hkdf
        < CRYPTO;