diff --git a/accounts/accounts.go b/accounts/accounts.go index 7bd911577a..e95a0f515a 100644 --- a/accounts/accounts.go +++ b/accounts/accounts.go @@ -24,8 +24,8 @@ import ( "github.com/ethereum/go-ethereum" "github.com/ethereum/go-ethereum/common" "github.com/ethereum/go-ethereum/core/types" + "github.com/ethereum/go-ethereum/crypto" "github.com/ethereum/go-ethereum/event" - "golang.org/x/crypto/sha3" ) // Account represents an Ethereum account located at a specific location defined @@ -196,7 +196,7 @@ func TextHash(data []byte) []byte { // This gives context to the signed message and prevents signing of transactions. func TextAndHash(data []byte) ([]byte, string) { msg := fmt.Sprintf("\x19Ethereum Signed Message:\n%d%s", len(data), data) - hasher := sha3.NewLegacyKeccak256() + hasher := crypto.NewLegacyKeccak256() hasher.Write([]byte(msg)) return hasher.Sum(nil), msg } diff --git a/cmd/evm/internal/t8ntool/execution.go b/cmd/evm/internal/t8ntool/execution.go index 865a5944a7..313a3a9114 100644 --- a/cmd/evm/internal/t8ntool/execution.go +++ b/cmd/evm/internal/t8ntool/execution.go @@ -32,6 +32,7 @@ import ( "github.com/ethereum/go-ethereum/core/tracing" "github.com/ethereum/go-ethereum/core/types" "github.com/ethereum/go-ethereum/core/vm" + "github.com/ethereum/go-ethereum/crypto" "github.com/ethereum/go-ethereum/ethdb" "github.com/ethereum/go-ethereum/log" "github.com/ethereum/go-ethereum/params" @@ -39,7 +40,6 @@ import ( "github.com/ethereum/go-ethereum/trie" "github.com/ethereum/go-ethereum/triedb" "github.com/holiman/uint256" - "golang.org/x/crypto/sha3" ) type Prestate struct { @@ -403,7 +403,7 @@ func MakePreState(db ethdb.Database, accounts types.GenesisAlloc) *state.StateDB } func rlpHash(x interface{}) (h common.Hash) { - hw := sha3.NewLegacyKeccak256() + hw := crypto.NewLegacyKeccak256() rlp.Encode(hw, x) hw.Sum(h[:0]) return h diff --git a/consensus/clique/clique.go b/consensus/clique/clique.go index 5128a9d9f4..a83589e5e5 100644 --- a/consensus/clique/clique.go +++ b/consensus/clique/clique.go @@ -42,7 +42,6 @@ import ( "github.com/ethereum/go-ethereum/params" "github.com/ethereum/go-ethereum/rlp" "github.com/ethereum/go-ethereum/trie" - "golang.org/x/crypto/sha3" ) const ( @@ -643,7 +642,7 @@ func (c *Clique) Close() error { // SealHash returns the hash of a block prior to it being sealed. func SealHash(header *types.Header) (hash common.Hash) { - hasher := sha3.NewLegacyKeccak256() + hasher := crypto.NewLegacyKeccak256() encodeSigHeader(hasher, header) hasher.(crypto.KeccakState).Read(hash[:]) return hash diff --git a/consensus/ethash/consensus.go b/consensus/ethash/consensus.go index 9211197687..9f5c845a12 100644 --- a/consensus/ethash/consensus.go +++ b/consensus/ethash/consensus.go @@ -31,11 +31,11 @@ import ( "github.com/ethereum/go-ethereum/core/tracing" "github.com/ethereum/go-ethereum/core/types" "github.com/ethereum/go-ethereum/core/vm" + "github.com/ethereum/go-ethereum/crypto" "github.com/ethereum/go-ethereum/params" "github.com/ethereum/go-ethereum/rlp" "github.com/ethereum/go-ethereum/trie" "github.com/holiman/uint256" - "golang.org/x/crypto/sha3" ) // Ethash proof-of-work protocol constants. @@ -528,7 +528,7 @@ func (ethash *Ethash) FinalizeAndAssemble(chain consensus.ChainHeaderReader, hea // SealHash returns the hash of a block prior to it being sealed. func (ethash *Ethash) SealHash(header *types.Header) (hash common.Hash) { - hasher := sha3.NewLegacyKeccak256() + hasher := crypto.NewLegacyKeccak256() enc := []interface{}{ header.ParentHash, diff --git a/core/rawdb/accessors_chain_test.go b/core/rawdb/accessors_chain_test.go index 819788b4da..ed7f093824 100644 --- a/core/rawdb/accessors_chain_test.go +++ b/core/rawdb/accessors_chain_test.go @@ -31,7 +31,6 @@ import ( "github.com/ethereum/go-ethereum/crypto" "github.com/ethereum/go-ethereum/params" "github.com/ethereum/go-ethereum/rlp" - "golang.org/x/crypto/sha3" ) // Tests block header storage and retrieval operations. @@ -53,7 +52,7 @@ func TestHeaderStorage(t *testing.T) { if entry := ReadHeaderRLP(db, header.Hash(), header.Number.Uint64()); entry == nil { t.Fatalf("Stored header RLP not found") } else { - hasher := sha3.NewLegacyKeccak256() + hasher := crypto.NewLegacyKeccak256() hasher.Write(entry) if hash := common.BytesToHash(hasher.Sum(nil)); hash != header.Hash() { @@ -74,7 +73,7 @@ func TestBodyStorage(t *testing.T) { // Create a test body to move around the database and make sure it's really new body := &types.Body{Uncles: []*types.Header{{Extra: []byte("test header")}}} - hasher := sha3.NewLegacyKeccak256() + hasher := crypto.NewLegacyKeccak256() rlp.Encode(hasher, body) hash := common.BytesToHash(hasher.Sum(nil)) @@ -91,7 +90,7 @@ func TestBodyStorage(t *testing.T) { if entry := ReadBodyRLP(db, hash, 0); entry == nil { t.Fatalf("Stored body RLP not found") } else { - hasher := sha3.NewLegacyKeccak256() + hasher := crypto.NewLegacyKeccak256() hasher.Write(entry) if calc := common.BytesToHash(hasher.Sum(nil)); calc != hash { diff --git a/core/rlp_test.go b/core/rlp_test.go index 69efa82551..eab646e360 100644 --- a/core/rlp_test.go +++ b/core/rlp_test.go @@ -27,7 +27,6 @@ import ( "github.com/ethereum/go-ethereum/crypto" "github.com/ethereum/go-ethereum/params" "github.com/ethereum/go-ethereum/rlp" - "golang.org/x/crypto/sha3" ) func getBlock(transactions int, uncles int, dataSize int) *types.Block { @@ -147,7 +146,7 @@ func BenchmarkHashing(b *testing.B) { blockRlp, _ = rlp.EncodeToBytes(block) } var got common.Hash - var hasher = sha3.NewLegacyKeccak256() + var hasher = crypto.NewLegacyKeccak256() b.Run("iteratorhashing", func(b *testing.B) { for b.Loop() { var hash common.Hash diff --git a/core/state/snapshot/generate_test.go b/core/state/snapshot/generate_test.go index 63d6e930f9..ab5848aa49 100644 --- a/core/state/snapshot/generate_test.go +++ b/core/state/snapshot/generate_test.go @@ -25,6 +25,7 @@ import ( "github.com/ethereum/go-ethereum/common" "github.com/ethereum/go-ethereum/core/rawdb" "github.com/ethereum/go-ethereum/core/types" + "github.com/ethereum/go-ethereum/crypto" "github.com/ethereum/go-ethereum/ethdb" "github.com/ethereum/go-ethereum/log" "github.com/ethereum/go-ethereum/rlp" @@ -34,11 +35,10 @@ import ( "github.com/ethereum/go-ethereum/triedb/hashdb" "github.com/ethereum/go-ethereum/triedb/pathdb" "github.com/holiman/uint256" - "golang.org/x/crypto/sha3" ) func hashData(input []byte) common.Hash { - var hasher = sha3.NewLegacyKeccak256() + var hasher = crypto.NewLegacyKeccak256() var hash common.Hash hasher.Reset() hasher.Write(input) diff --git a/core/state_processor_test.go b/core/state_processor_test.go index 64001e2857..e9e9151877 100644 --- a/core/state_processor_test.go +++ b/core/state_processor_test.go @@ -34,7 +34,6 @@ import ( "github.com/ethereum/go-ethereum/params" "github.com/ethereum/go-ethereum/trie" "github.com/holiman/uint256" - "golang.org/x/crypto/sha3" ) func u64(val uint64) *uint64 { return &val } @@ -399,7 +398,7 @@ func GenerateBadBlock(parent *types.Block, engine consensus.Engine, txs types.Tr var receipts []*types.Receipt // The post-state result doesn't need to be correct (this is a bad block), but we do need something there // Preferably something unique. So let's use a combo of blocknum + txhash - hasher := sha3.NewLegacyKeccak256() + hasher := crypto.NewLegacyKeccak256() hasher.Write(header.Number.Bytes()) var cumulativeGas uint64 var nBlobs int diff --git a/crypto/keccak.go b/crypto/keccak.go index 0ad79a63c1..1b14eee903 100644 --- a/crypto/keccak.go +++ b/crypto/keccak.go @@ -22,17 +22,16 @@ import ( "sync" "github.com/ethereum/go-ethereum/common" - "golang.org/x/crypto/sha3" ) // NewKeccakState creates a new KeccakState func NewKeccakState() KeccakState { - return sha3.NewLegacyKeccak256().(KeccakState) + return NewLegacyKeccak256().(KeccakState) } var hasherPool = sync.Pool{ New: func() any { - return sha3.NewLegacyKeccak256().(KeccakState) + return NewLegacyKeccak256().(KeccakState) }, } diff --git a/crypto/keccak_state.go b/crypto/keccak_state.go new file mode 100644 index 0000000000..0868c2c238 --- /dev/null +++ b/crypto/keccak_state.go @@ -0,0 +1,9 @@ +//go:build !ziren && !wasm + +package crypto + +import "golang.org/x/crypto/sha3" + +func NewLegacyKeccak256() KeccakState { + return sha3.NewLegacyKeccak256().(KeccakState) +} diff --git a/crypto/keccak_state_wasm.go b/crypto/keccak_state_wasm.go new file mode 100644 index 0000000000..78a7813b12 --- /dev/null +++ b/crypto/keccak_state_wasm.go @@ -0,0 +1,55 @@ +//go:build !ziren && wasm + +package crypto + +import ( + "sync" + + "golang.org/x/crypto/sha3" +) + +func NewLegacyKeccak256() KeccakState { + return &simpleHashBuffer{} +} + +type simpleHashBuffer struct { + buffer []byte +} + +func (s *simpleHashBuffer) Write(p []byte) (n int, err error) { + s.buffer = append(s.buffer, p...) + return len(p), nil +} + +func (s *simpleHashBuffer) Sum(b []byte) []byte { + currentBufferHash := make([]byte, 32) + s.Read(currentBufferHash) + return append(b, currentBufferHash...) +} + +func (s *simpleHashBuffer) Reset() { + s.buffer = nil // Simply forget previous data. +} + +func (s *simpleHashBuffer) Size() int { + return 32 // Keccak256 produces 32-byte hashes +} + +func (s *simpleHashBuffer) BlockSize() int { + return (1600 - 512) / 8 // Keccak256 rate in bytes: sponge size 1600 bits - capacity 512 bits. Copied from sha3. +} + +var realHasherPool = sync.Pool{ + New: func() any { + return sha3.NewLegacyKeccak256().(KeccakState) + }, +} + +func (s *simpleHashBuffer) Read(bytes []byte) (int, error) { + d := realHasherPool.Get().(KeccakState) + defer realHasherPool.Put(d) + + d.Reset() + d.Write(s.buffer) + return d.Read(bytes) +} diff --git a/eth/protocols/snap/sync_test.go b/eth/protocols/snap/sync_test.go index 713b358ff8..79d43323ce 100644 --- a/eth/protocols/snap/sync_test.go +++ b/eth/protocols/snap/sync_test.go @@ -41,7 +41,6 @@ import ( "github.com/ethereum/go-ethereum/triedb" "github.com/ethereum/go-ethereum/triedb/pathdb" "github.com/holiman/uint256" - "golang.org/x/crypto/sha3" ) func TestHashing(t *testing.T) { @@ -55,7 +54,7 @@ func TestHashing(t *testing.T) { } var want, got string var old = func() { - hasher := sha3.NewLegacyKeccak256() + hasher := crypto.NewLegacyKeccak256() for i := 0; i < len(bytecodes); i++ { hasher.Reset() hasher.Write(bytecodes[i]) @@ -88,7 +87,7 @@ func BenchmarkHashing(b *testing.B) { bytecodes[i] = buf } var old = func() { - hasher := sha3.NewLegacyKeccak256() + hasher := crypto.NewLegacyKeccak256() for i := 0; i < len(bytecodes); i++ { hasher.Reset() hasher.Write(bytecodes[i]) diff --git a/internal/blocktest/test_hash.go b/internal/blocktest/test_hash.go index b3e7098e2b..e0b3853fda 100644 --- a/internal/blocktest/test_hash.go +++ b/internal/blocktest/test_hash.go @@ -27,7 +27,7 @@ import ( "hash" "github.com/ethereum/go-ethereum/common" - "golang.org/x/crypto/sha3" + "github.com/ethereum/go-ethereum/crypto" ) // testHasher is the helper tool for transaction/receipt list hashing. @@ -39,7 +39,7 @@ type testHasher struct { // NewHasher returns a new testHasher instance. func NewHasher() *testHasher { - return &testHasher{hasher: sha3.NewLegacyKeccak256()} + return &testHasher{hasher: crypto.NewLegacyKeccak256()} } // Reset resets the hash state. diff --git a/p2p/dnsdisc/tree.go b/p2p/dnsdisc/tree.go index a8295ac9eb..aad82ad11b 100644 --- a/p2p/dnsdisc/tree.go +++ b/p2p/dnsdisc/tree.go @@ -31,7 +31,6 @@ import ( "github.com/ethereum/go-ethereum/p2p/enode" "github.com/ethereum/go-ethereum/p2p/enr" "github.com/ethereum/go-ethereum/rlp" - "golang.org/x/crypto/sha3" ) // Tree is a merkle tree of node records. @@ -262,7 +261,7 @@ const ( ) func subdomain(e entry) string { - h := sha3.NewLegacyKeccak256() + h := crypto.NewLegacyKeccak256() io.WriteString(h, e.String()) return b32format.EncodeToString(h.Sum(nil)[:16]) } @@ -272,7 +271,7 @@ func (e *rootEntry) String() string { } func (e *rootEntry) sigHash() []byte { - h := sha3.NewLegacyKeccak256() + h := crypto.NewLegacyKeccak256() fmt.Fprintf(h, rootPrefix+" e=%s l=%s seq=%d", e.eroot, e.lroot, e.seq) return h.Sum(nil) } diff --git a/p2p/enode/idscheme.go b/p2p/enode/idscheme.go index db7841c047..e43c9d9051 100644 --- a/p2p/enode/idscheme.go +++ b/p2p/enode/idscheme.go @@ -25,7 +25,6 @@ import ( "github.com/ethereum/go-ethereum/crypto" "github.com/ethereum/go-ethereum/p2p/enr" "github.com/ethereum/go-ethereum/rlp" - "golang.org/x/crypto/sha3" ) // ValidSchemes is a List of known secure identity schemes. @@ -49,7 +48,7 @@ func SignV4(r *enr.Record, privkey *ecdsa.PrivateKey) error { cpy.Set(enr.ID("v4")) cpy.Set(Secp256k1(privkey.PublicKey)) - h := sha3.NewLegacyKeccak256() + h := crypto.NewLegacyKeccak256() rlp.Encode(h, cpy.AppendElements(nil)) sig, err := crypto.Sign(h.Sum(nil), privkey) if err != nil { @@ -70,7 +69,7 @@ func (V4ID) Verify(r *enr.Record, sig []byte) error { return errors.New("invalid public key") } - h := sha3.NewLegacyKeccak256() + h := crypto.NewLegacyKeccak256() rlp.Encode(h, r.AppendElements(nil)) if !crypto.VerifySignature(entry, h.Sum(nil), sig) { return enr.ErrInvalidSig diff --git a/p2p/rlpx/rlpx.go b/p2p/rlpx/rlpx.go index c074534d4d..cdb32537aa 100644 --- a/p2p/rlpx/rlpx.go +++ b/p2p/rlpx/rlpx.go @@ -38,7 +38,6 @@ import ( "github.com/ethereum/go-ethereum/crypto/ecies" "github.com/ethereum/go-ethereum/rlp" "github.com/golang/snappy" - "golang.org/x/crypto/sha3" ) // Conn is an RLPx network connection. It wraps a low-level network connection. The @@ -486,10 +485,10 @@ func (h *handshakeState) secrets(auth, authResp []byte) (Secrets, error) { } // setup sha3 instances for the MACs - mac1 := sha3.NewLegacyKeccak256() + mac1 := crypto.NewLegacyKeccak256() mac1.Write(xor(s.MAC, h.respNonce)) mac1.Write(auth) - mac2 := sha3.NewLegacyKeccak256() + mac2 := crypto.NewLegacyKeccak256() mac2.Write(xor(s.MAC, h.initNonce)) mac2.Write(authResp) if h.initiator { diff --git a/tests/state_test_util.go b/tests/state_test_util.go index cc02b9feea..49646a38e6 100644 --- a/tests/state_test_util.go +++ b/tests/state_test_util.go @@ -46,7 +46,6 @@ import ( "github.com/ethereum/go-ethereum/triedb/hashdb" "github.com/ethereum/go-ethereum/triedb/pathdb" "github.com/holiman/uint256" - "golang.org/x/crypto/sha3" ) // StateTest checks transaction processing without block context. @@ -488,7 +487,7 @@ func (tx *stTransaction) toMessage(ps stPostState, baseFee *big.Int) (*core.Mess } func rlpHash(x interface{}) (h common.Hash) { - hw := sha3.NewLegacyKeccak256() + hw := crypto.NewLegacyKeccak256() rlp.Encode(hw, x) hw.Sum(h[:0]) return h diff --git a/trie/trie_test.go b/trie/trie_test.go index b8b8edb33e..fc68ca7f72 100644 --- a/trie/trie_test.go +++ b/trie/trie_test.go @@ -40,7 +40,6 @@ import ( "github.com/ethereum/go-ethereum/rlp" "github.com/ethereum/go-ethereum/trie/trienode" "github.com/holiman/uint256" - "golang.org/x/crypto/sha3" ) func init() { @@ -968,7 +967,7 @@ func TestCommitSequenceStackTrie(t *testing.T) { prng := rand.New(rand.NewSource(int64(count))) // This spongeDb is used to check the sequence of disk-db-writes s := &spongeDb{ - sponge: sha3.NewLegacyKeccak256(), + sponge: crypto.NewLegacyKeccak256(), id: "a", values: make(map[string]string), } @@ -977,7 +976,7 @@ func TestCommitSequenceStackTrie(t *testing.T) { // Another sponge is used for the stacktrie commits stackTrieSponge := &spongeDb{ - sponge: sha3.NewLegacyKeccak256(), + sponge: crypto.NewLegacyKeccak256(), id: "b", values: make(map[string]string), } @@ -1040,7 +1039,7 @@ func TestCommitSequenceStackTrie(t *testing.T) { // not fit into 32 bytes, rlp-encoded. However, it's still the correct thing to do. func TestCommitSequenceSmallRoot(t *testing.T) { s := &spongeDb{ - sponge: sha3.NewLegacyKeccak256(), + sponge: crypto.NewLegacyKeccak256(), id: "a", values: make(map[string]string), } @@ -1049,7 +1048,7 @@ func TestCommitSequenceSmallRoot(t *testing.T) { // Another sponge is used for the stacktrie commits stackTrieSponge := &spongeDb{ - sponge: sha3.NewLegacyKeccak256(), + sponge: crypto.NewLegacyKeccak256(), id: "b", values: make(map[string]string), }