Skip to content
12 changes: 2 additions & 10 deletions cmd/devp2p/internal/ethtest/snap.go
Original file line number Diff line number Diff line change
Expand Up @@ -900,16 +900,12 @@ func (s *Suite) snapGetByteCodes(t *utesting.T, tc *byteCodesTest) error {
// that the serving node is missing
var (
bytecodes = res.Codes
hasher = crypto.NewKeccakState()
hash = make([]byte, 32)
codes = make([][]byte, len(req.Hashes))
)

for i, j := 0, 0; i < len(bytecodes); i++ {
// Find the next hash that we've been served, leaving misses with nils
hasher.Reset()
hasher.Write(bytecodes[i])
hasher.Read(hash)
hash := crypto.Keccak256(bytecodes[i])

for j < len(req.Hashes) && !bytes.Equal(hash, req.Hashes[j][:]) {
j++
Expand Down Expand Up @@ -959,16 +955,12 @@ func (s *Suite) snapGetTrieNodes(t *utesting.T, tc *trieNodesTest) error {

// Cross reference the requested trienodes with the response to find gaps
// that the serving node is missing
hasher := crypto.NewKeccakState()
hash := make([]byte, 32)
trienodes := res.Nodes
if got, want := len(trienodes), len(tc.expHashes); got != want {
return fmt.Errorf("wrong trienode count, got %d, want %d", got, want)
}
for i, trienode := range trienodes {
hasher.Reset()
hasher.Write(trienode)
hasher.Read(hash)
hash := crypto.Keccak256(trienode[:])
if got, want := hash, tc.expHashes[i]; !bytes.Equal(got, want[:]) {
t.Logf(" hash %d wrong, got %#x, want %#x\n", i, got, want)
err = fmt.Errorf("hash %d wrong, got %#x, want %#x", i, got, want)
Expand Down
6 changes: 1 addition & 5 deletions cmd/geth/dbcmd.go
Original file line number Diff line number Diff line change
Expand Up @@ -354,8 +354,6 @@ func checkStateContent(ctx *cli.Context) error {
defer db.Close()
var (
it = rawdb.NewKeyLengthIterator(db.NewIterator(prefix, start), 32)
hasher = crypto.NewKeccakState()
got = make([]byte, 32)
errs int
count int
startTime = time.Now()
Expand All @@ -365,9 +363,7 @@ func checkStateContent(ctx *cli.Context) error {
count++
k := it.Key()
v := it.Value()
hasher.Reset()
hasher.Write(v)
hasher.Read(got)
got := crypto.Keccak256(v)
if !bytes.Equal(k, got) {
errs++
fmt.Printf("Error at %#x\n", k)
Expand Down
10 changes: 2 additions & 8 deletions cmd/geth/snapshot.go
Original file line number Diff line number Diff line change
Expand Up @@ -430,8 +430,6 @@ func traverseRawState(ctx *cli.Context) error {
codes int
lastReport time.Time
start = time.Now()
hasher = crypto.NewKeccakState()
got = make([]byte, 32)
)
accIter, err := t.NodeIterator(nil)
if err != nil {
Expand All @@ -455,9 +453,7 @@ func traverseRawState(ctx *cli.Context) error {
log.Error("Missing trie node(account)", "hash", node)
return errors.New("missing account")
}
hasher.Reset()
hasher.Write(blob)
hasher.Read(got)
got := crypto.Keccak256(blob)
if !bytes.Equal(got, node.Bytes()) {
log.Error("Invalid trie node(account)", "hash", node.Hex(), "value", blob)
return errors.New("invalid account node")
Expand Down Expand Up @@ -496,9 +492,7 @@ func traverseRawState(ctx *cli.Context) error {
log.Error("Missing trie node(storage)", "hash", node)
return errors.New("missing storage")
}
hasher.Reset()
hasher.Write(blob)
hasher.Read(got)
got := crypto.Keccak256(blob)
if !bytes.Equal(got, node.Bytes()) {
log.Error("Invalid trie node(storage)", "hash", node.Hex(), "value", blob)
return errors.New("invalid storage node")
Expand Down
5 changes: 2 additions & 3 deletions cmd/workload/historytestgen.go
Original file line number Diff line number Diff line change
Expand Up @@ -132,9 +132,8 @@ func generateHistoryTests(clictx *cli.Context) error {
}

func calcReceiptsHash(rcpt []*types.Receipt) common.Hash {
h := crypto.NewKeccakState()
rlp.Encode(h, rcpt)
return common.Hash(h.Sum(nil))
encoded, _ := rlp.EncodeToBytes(rcpt)
return crypto.Keccak256Hash(encoded)
}

func writeJSON(fileName string, value any) {
Expand Down
9 changes: 3 additions & 6 deletions consensus/clique/clique.go
Original file line number Diff line number Diff line change
Expand Up @@ -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 (
Expand Down Expand Up @@ -641,11 +640,9 @@ 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()
encodeSigHeader(hasher, header)
hasher.(crypto.KeccakState).Read(hash[:])
return hash
func SealHash(header *types.Header) common.Hash {
encoded := CliqueRLP(header)
return crypto.Keccak256Hash(encoded)
}

// CliqueRLP returns the rlp bytes which needs to be signed for the proof-of-authority
Expand Down
18 changes: 3 additions & 15 deletions core/stateless/database.go
Original file line number Diff line number Diff line change
Expand Up @@ -34,33 +34,21 @@ import (
//
// Acceleration structures built would need to explicitly validate the witness.
func (w *Witness) MakeHashDB() ethdb.Database {
var (
memdb = rawdb.NewMemoryDatabase()
hasher = crypto.NewKeccakState()
hash = make([]byte, 32)
)
var memdb = rawdb.NewMemoryDatabase()
// Inject all the "block hashes" (i.e. headers) into the ephemeral database
for _, header := range w.Headers {
rawdb.WriteHeader(memdb, header)
}
// Inject all the bytecodes into the ephemeral database
for code := range w.Codes {
blob := []byte(code)

hasher.Reset()
hasher.Write(blob)
hasher.Read(hash)

hash := crypto.Keccak256(blob)
rawdb.WriteCode(memdb, common.BytesToHash(hash), blob)
}
// Inject all the MPT trie nodes into the ephemeral database
for node := range w.State {
blob := []byte(node)

hasher.Reset()
hasher.Write(blob)
hasher.Read(hash)

hash := crypto.Keccak256(blob)
rawdb.WriteLegacyTrieNode(memdb, common.BytesToHash(hash), blob)
}
return memdb
Expand Down
7 changes: 2 additions & 5 deletions core/types/bloom9.go
Original file line number Diff line number Diff line change
Expand Up @@ -141,11 +141,8 @@ func Bloom9(data []byte) []byte {

// bloomValues returns the bytes (index-value pairs) to set for the given data
func bloomValues(data []byte, hashbuf *[6]byte) (uint, byte, uint, byte, uint, byte) {
sha := hasherPool.Get().(crypto.KeccakState)
sha.Reset()
sha.Write(data)
sha.Read(hashbuf[:])
hasherPool.Put(sha)
hash := crypto.Keccak256(data)
copy(hashbuf[:], hash[:6])
// The actual bits to flip
v1 := byte(1 << (hashbuf[1] & 0x7))
v2 := byte(1 << (hashbuf[3] & 0x7))
Expand Down
22 changes: 4 additions & 18 deletions core/types/hashing.go
Original file line number Diff line number Diff line change
Expand Up @@ -27,11 +27,6 @@ import (
"github.com/ethereum/go-ethereum/rlp"
)

// hasherPool holds LegacyKeccak256 buffer for rlpHash.
var hasherPool = sync.Pool{
New: func() interface{} { return crypto.NewKeccakState() },
}

// encodeBufferPool holds temporary encoder buffers for DeriveSha and TX encoding.
var encodeBufferPool = sync.Pool{
New: func() interface{} { return new(bytes.Buffer) },
Expand All @@ -55,24 +50,15 @@ func getPooledBuffer(size uint64) ([]byte, *bytes.Buffer, error) {

// rlpHash encodes x and hashes the encoded bytes.
func rlpHash(x interface{}) (h common.Hash) {
sha := hasherPool.Get().(crypto.KeccakState)
defer hasherPool.Put(sha)
sha.Reset()
rlp.Encode(sha, x)
sha.Read(h[:])
return h
encoded, _ := rlp.EncodeToBytes(x)
return crypto.Keccak256Hash(encoded)
}

// prefixedRlpHash writes the prefix into the hasher before rlp-encoding x.
// It's used for typed transactions.
func prefixedRlpHash(prefix byte, x interface{}) (h common.Hash) {
sha := hasherPool.Get().(crypto.KeccakState)
defer hasherPool.Put(sha)
sha.Reset()
sha.Write([]byte{prefix})
rlp.Encode(sha, x)
sha.Read(h[:])
return h
encoded, _ := rlp.EncodeToBytes(x)
return crypto.Keccak256Hash([]byte{prefix}, encoded)
}

// ListHasher defines the interface for computing the hash of a derivable list.
Expand Down
8 changes: 2 additions & 6 deletions core/vm/evm.go
Original file line number Diff line number Diff line change
Expand Up @@ -125,9 +125,6 @@ type EVM struct {
// jumpDests stores results of JUMPDEST analysis.
jumpDests JumpDestCache

hasher crypto.KeccakState // Keccak256 hasher instance shared across opcodes
hasherBuf common.Hash // Keccak256 hasher result array shared across opcodes

readOnly bool // Whether to throw on stateful modifications
returnData []byte // Last CALL's return data for subsequent reuse
}
Expand All @@ -144,7 +141,6 @@ func NewEVM(blockCtx BlockContext, statedb StateDB, chainConfig *params.ChainCon
chainConfig: chainConfig,
chainRules: chainConfig.Rules(blockCtx.BlockNumber, blockCtx.Random != nil, blockCtx.Time),
jumpDests: newMapJumpDests(),
hasher: crypto.NewKeccakState(),
}
evm.precompiles = activePrecompiledContracts(evm.chainRules)

Expand Down Expand Up @@ -618,8 +614,8 @@ func (evm *EVM) Create(caller common.Address, code []byte, gas uint64, value *ui
// The different between Create2 with Create is Create2 uses keccak256(0xff ++ msg.sender ++ salt ++ keccak256(init_code))[12:]
// instead of the usual sender-and-nonce-hash as the address where the contract is initialized at.
func (evm *EVM) Create2(caller common.Address, code []byte, gas uint64, endowment *uint256.Int, salt *uint256.Int) (ret []byte, contractAddr common.Address, leftOverGas uint64, err error) {
inithash := crypto.HashData(evm.hasher, code)
contractAddr = crypto.CreateAddress2(caller, salt.Bytes32(), inithash[:])
inithash := crypto.Keccak256(code)
contractAddr = crypto.CreateAddress2(caller, salt.Bytes32(), inithash)
return evm.create(caller, code, gas, endowment, contractAddr, CREATE2)
}

Expand Down
10 changes: 4 additions & 6 deletions core/vm/instructions.go
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,7 @@ import (
"github.com/ethereum/go-ethereum/common"
"github.com/ethereum/go-ethereum/core/tracing"
"github.com/ethereum/go-ethereum/core/types"
"github.com/ethereum/go-ethereum/crypto"
"github.com/ethereum/go-ethereum/params"
"github.com/holiman/uint256"
)
Expand Down Expand Up @@ -233,14 +234,11 @@ func opKeccak256(pc *uint64, evm *EVM, scope *ScopeContext) ([]byte, error) {
offset, size := scope.Stack.pop(), scope.Stack.peek()
data := scope.Memory.GetPtr(offset.Uint64(), size.Uint64())

evm.hasher.Reset()
evm.hasher.Write(data)
evm.hasher.Read(evm.hasherBuf[:])

hash := crypto.Keccak256Hash(data)
if evm.Config.EnablePreimageRecording {
evm.StateDB.AddPreimage(evm.hasherBuf, data)
evm.StateDB.AddPreimage(hash, data)
}
size.SetBytes(evm.hasherBuf[:])
size.SetBytes(hash[:])
return nil, nil
}

Expand Down
10 changes: 1 addition & 9 deletions crypto/crypto.go
Original file line number Diff line number Diff line change
Expand Up @@ -64,15 +64,7 @@ type EllipticCurve interface {
// because it doesn't copy the internal state, but also modifies the internal state.
type KeccakState interface {
hash.Hash
Read([]byte) (int, error)
}

// HashData hashes the provided data using the KeccakState and returns a 32 byte hash
func HashData(kh KeccakState, data []byte) (h common.Hash) {
kh.Reset()
kh.Write(data)
kh.Read(h[:])
return h
io.Reader
}

// CreateAddress creates an ethereum address given the bytes and the nonce
Expand Down
22 changes: 1 addition & 21 deletions crypto/crypto_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -45,8 +45,7 @@ func TestKeccak256Hash(t *testing.T) {
func TestKeccak256Hasher(t *testing.T) {
msg := []byte("abc")
exp, _ := hex.DecodeString("4e03657aea45a94fc7d47ba826c8d667c0d1e6e33a64a036ec44f58fa12d6c45")
hasher := NewKeccakState()
checkhash(t, "Sha3-256-array", func(in []byte) []byte { h := HashData(hasher, in); return h[:] }, msg, exp)
checkhash(t, "Sha3-256-array", func(in []byte) []byte { h := Keccak256Hash(in); return h[:] }, msg, exp)
}

func TestToECDSAErrors(t *testing.T) {
Expand Down Expand Up @@ -314,22 +313,3 @@ func BenchmarkKeccak256Hash(b *testing.B) {
Keccak256Hash(input[:])
}
}

// goos: darwin
// goarch: arm64
// pkg: github.com/ethereum/go-ethereum/crypto
// cpu: Apple M1 Pro
// BenchmarkHashData
// BenchmarkHashData-8 793386 1278 ns/op 32 B/op 1 allocs/op
func BenchmarkHashData(b *testing.B) {
var (
input [512]byte
buffer = NewKeccakState()
)
rand.Read(input[:])

b.ReportAllocs()
for b.Loop() {
HashData(buffer, input[:])
}
}
20 changes: 9 additions & 11 deletions crypto/keccak.go
Original file line number Diff line number Diff line change
Expand Up @@ -32,32 +32,30 @@ func NewKeccakState() KeccakState {

var hasherPool = sync.Pool{
New: func() any {
return sha3.NewLegacyKeccak256().(KeccakState)
return NewKeccakState()
},
}

// Keccak256 calculates and returns the Keccak256 hash of the input data.
func Keccak256(data ...[]byte) []byte {
b := make([]byte, 32)
d := hasherPool.Get().(KeccakState)
d.Reset()
for _, b := range data {
d.Write(b)
}
d.Read(b)
hasherPool.Put(d)
hashInto(b, data...)
return b
}

// Keccak256Hash calculates and returns the Keccak256 hash of the input data,
// converting it to an internal Hash data structure.
func Keccak256Hash(data ...[]byte) (h common.Hash) {
hashInto(h[:], data...)
return h
}

func hashInto(out []byte, data ...[]byte) {
d := hasherPool.Get().(KeccakState)
defer hasherPool.Put(d)
d.Reset()
for _, b := range data {
d.Write(b)
}
d.Read(h[:])
hasherPool.Put(d)
return h
d.Read(out)
}
Loading