Skip to content
Merged
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 @@ -434,8 +434,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 @@ -459,9 +457,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 @@ -500,9 +496,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
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
6 changes: 1 addition & 5 deletions core/vm/evm.go
Original file line number Diff line number Diff line change
Expand Up @@ -133,9 +133,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 @@ -152,7 +149,6 @@ func NewEVM(blockCtx BlockContext, statedb StateDB, chainConfig *params.ChainCon
chainConfig: chainConfig,
chainRules: chainConfig.Rules(blockCtx.BlockNumber, blockCtx.Random != nil, blockCtx.Time, blockCtx.ArbOSVersion),
jumpDests: newMapJumpDests(),
hasher: crypto.NewKeccakState(),
}
evm.ProcessingHook = DefaultTxProcessor{evm: evm}
evm.precompiles = activePrecompiledContracts(evm.chainRules)
Expand Down Expand Up @@ -703,7 +699,7 @@ 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, usedMultiGas multigas.MultiGas, err error) {
inithash := crypto.HashData(evm.hasher, code)
inithash := crypto.Keccak256Hash(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 @@ -25,6 +25,7 @@ import (
"github.com/ethereum/go-ethereum/core/state"
"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 @@ -235,15 +236,12 @@ func opSAR(pc *uint64, evm *EVM, scope *ScopeContext) ([]byte, error) {
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[:])
hasherBuf := crypto.Keccak256Hash(data)

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

Expand Down
8 changes: 0 additions & 8 deletions crypto/crypto.go
Original file line number Diff line number Diff line change
Expand Up @@ -67,14 +67,6 @@ type KeccakState interface {
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
}

// CreateAddress creates an ethereum address given the bytes and the nonce
func CreateAddress(b common.Address, nonce uint64) common.Address {
data, _ := rlp.EncodeToBytes([]interface{}{b, 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[:])
}
}
21 changes: 10 additions & 11 deletions crypto/keccak.go
Original file line number Diff line number Diff line change
Expand Up @@ -36,28 +36,27 @@ var hasherPool = sync.Pool{
},
}

// Keccak256 calculates and returns the Keccak256 hash of the input data.
func Keccak256(data ...[]byte) []byte {
b := make([]byte, 32)
// keccak256 is a helper that hashes the input data using the provided KeccakState and writes the result to out.
func keccak256(out []byte, data ...[]byte) {
d := hasherPool.Get().(KeccakState)
d.Reset()
for _, b := range data {
d.Write(b)
}
d.Read(b)
d.Read(out)
hasherPool.Put(d)
}

// Keccak256 calculates and returns the Keccak256 hash of the input data.
func Keccak256(data ...[]byte) []byte {
b := make([]byte, 32)
keccak256(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) {
d := hasherPool.Get().(KeccakState)
d.Reset()
for _, b := range data {
d.Write(b)
}
d.Read(h[:])
hasherPool.Put(d)
keccak256(h[:], data...)
return h
}
25 changes: 5 additions & 20 deletions eth/protocols/snap/sync.go
Original file line number Diff line number Diff line change
Expand Up @@ -2672,15 +2672,10 @@ func (s *Syncer) onByteCodes(peer SyncPeer, id uint64, bytecodes [][]byte) error

// Cross reference the requested bytecodes with the response to find gaps
// that the serving node is missing
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 @@ -2920,16 +2915,12 @@ func (s *Syncer) OnTrieNodes(peer SyncPeer, id uint64, trienodes [][]byte) error
// Cross reference the requested trienodes with the response to find gaps
// that the serving node is missing
var (
hasher = crypto.NewKeccakState()
hash = make([]byte, 32)
nodes = make([][]byte, len(req.hashes))
fills uint64
nodes = make([][]byte, len(req.hashes))
fills uint64
)
for i, j := 0, 0; i < len(trienodes); i++ {
// Find the next hash that we've been served, leaving misses with nils
hasher.Reset()
hasher.Write(trienodes[i])
hasher.Read(hash)
hash := crypto.Keccak256(trienodes[i])

for j < len(req.hashes) && !bytes.Equal(hash, req.hashes[j][:]) {
j++
Expand Down Expand Up @@ -3026,16 +3017,10 @@ func (s *Syncer) onHealByteCodes(peer SyncPeer, id uint64, bytecodes [][]byte) e

// Cross reference the requested bytecodes with the response to find gaps
// that the serving node is missing
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
Loading
Loading