Skip to content

Commit a799864

Browse files
committed
core/vm, crypto: add crypto package for hashing
1 parent aa37bd0 commit a799864

File tree

4 files changed

+157
-13
lines changed

4 files changed

+157
-13
lines changed

core/vm/evm.go

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -26,6 +26,7 @@ import (
2626
"github.com/ethereum/go-ethereum/core/tracing"
2727
"github.com/ethereum/go-ethereum/core/types"
2828
"github.com/ethereum/go-ethereum/crypto"
29+
"github.com/ethereum/go-ethereum/crypto/platcrypto"
2930
"github.com/ethereum/go-ethereum/log"
3031
"github.com/ethereum/go-ethereum/params"
3132
"github.com/holiman/uint256"
@@ -144,7 +145,7 @@ func NewEVM(blockCtx BlockContext, statedb StateDB, chainConfig *params.ChainCon
144145
chainConfig: chainConfig,
145146
chainRules: chainConfig.Rules(blockCtx.BlockNumber, blockCtx.Random != nil, blockCtx.Time),
146147
jumpDests: newMapJumpDests(),
147-
hasher: crypto.NewKeccakState(),
148+
hasher: platcrypto.NewKeccakState(),
148149
}
149150
evm.precompiles = activePrecompiledContracts(evm.chainRules)
150151

crypto/platcrypto/keccak.go

Lines changed: 42 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,42 @@
1+
// Copyright 2025 The go-ethereum Authors
2+
// This file is part of the go-ethereum library.
3+
//
4+
// The go-ethereum library is free software: you can redistribute it and/or modify
5+
// it under the terms of the GNU Lesser General Public License as published by
6+
// the Free Software Foundation, either version 3 of the License, or
7+
// (at your option) any later version.
8+
//
9+
// The go-ethereum library is distributed in the hope that it will be useful,
10+
// but WITHOUT ANY WARRANTY; without even the implied warranty of
11+
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12+
// GNU Lesser General Public License for more details.
13+
//
14+
// You should have received a copy of the GNU Lesser General Public License
15+
// along with the go-ethereum library. If not, see <http://www.gnu.org/licenses/>.
16+
17+
//go:build !ziren
18+
19+
package platcrypto
20+
21+
import (
22+
"github.com/ethereum/go-ethereum/common"
23+
"github.com/ethereum/go-ethereum/crypto"
24+
)
25+
26+
// Keccak256 calculates and returns the Keccak256 hash using the standard implementation.
27+
// This is used for geth, evm, and other regular programs.
28+
func Keccak256(data ...[]byte) []byte {
29+
return crypto.Keccak256(data...)
30+
}
31+
32+
// Keccak256Hash calculates and returns the Keccak256 hash as a Hash using the standard implementation.
33+
// This is used for geth, evm, and other regular programs.
34+
func Keccak256Hash(data ...[]byte) common.Hash {
35+
return crypto.Keccak256Hash(data...)
36+
}
37+
38+
// NewKeccakState returns a new keccak state hasher using the standard implementation.
39+
// This is used for geth, evm, and other regular programs.
40+
func NewKeccakState() crypto.KeccakState {
41+
return crypto.NewKeccakState()
42+
}

crypto/platcrypto/keccak_ziren.go

Lines changed: 101 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,101 @@
1+
// Copyright 2025 The go-ethereum Authors
2+
// This file is part of the go-ethereum library.
3+
//
4+
// The go-ethereum library is free software: you can redistribute it and/or modify
5+
// it under the terms of the GNU Lesser General Public License as published by
6+
// the Free Software Foundation, either version 3 of the License, or
7+
// (at your option) any later version.
8+
//
9+
// The go-ethereum library is distributed in the hope that it will be useful,
10+
// but WITHOUT ANY WARRANTY; without even the implied warranty of
11+
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12+
// GNU Lesser General Public License for more details.
13+
//
14+
// You should have received a copy of the GNU Lesser General Public License
15+
// along with the go-ethereum library. If not, see <http://www.gnu.org/licenses/>.
16+
17+
//go:build ziren
18+
19+
package platcrypto
20+
21+
import (
22+
"errors"
23+
24+
"github.com/ethereum/go-ethereum/common"
25+
"github.com/ethereum/go-ethereum/crypto"
26+
zkruntime "github.com/zkMIPS/zkMIPS/crates/go-runtime/zkm_runtime"
27+
)
28+
29+
// zirenKeccak implements keccak256 using the ziren platform precompile
30+
func zirenKeccak(data []byte) []byte {
31+
return zkruntime.Keccak(data)
32+
}
33+
34+
// zirenKeccakState wraps the ziren platform keccak precompile to implement crypto.KeccakState interface
35+
type zirenKeccakState struct {
36+
data []byte
37+
}
38+
39+
func (k *zirenKeccakState) Reset() {
40+
k.data = k.data[:0]
41+
}
42+
43+
func (k *zirenKeccakState) Clone() crypto.KeccakState {
44+
clone := &zirenKeccakState{
45+
data: make([]byte, len(k.data)),
46+
}
47+
copy(clone.data, k.data)
48+
return clone
49+
}
50+
51+
func (k *zirenKeccakState) Write(data []byte) (int, error) {
52+
k.data = append(k.data, data...)
53+
return len(data), nil
54+
}
55+
56+
func (k *zirenKeccakState) Read(hash []byte) (int, error) {
57+
if len(hash) < 32 {
58+
return 0, errors.New("hash slice too short")
59+
}
60+
61+
result := zirenKeccak(k.data)
62+
copy(hash[:32], result)
63+
return 32, nil
64+
}
65+
66+
func (k *zirenKeccakState) Sum(data []byte) []byte {
67+
hash := make([]byte, 32)
68+
k.Read(hash)
69+
return append(data, hash...)
70+
}
71+
72+
func (k *zirenKeccakState) Size() int {
73+
return 32
74+
}
75+
76+
func (k *zirenKeccakState) BlockSize() int {
77+
return 136 // keccak256 block size
78+
}
79+
80+
// Keccak256 calculates and returns the Keccak256 hash using the ziren platform precompile.
81+
func Keccak256(data ...[]byte) []byte {
82+
hasher := &zirenKeccakState{}
83+
for _, b := range data {
84+
hasher.Write(b)
85+
}
86+
hash := make([]byte, 32)
87+
hasher.Read(hash)
88+
return hash
89+
}
90+
91+
// Keccak256Hash calculates and returns the Keccak256 hash as a Hash using the ziren platform precompile.
92+
func Keccak256Hash(data ...[]byte) (h common.Hash) {
93+
hash := Keccak256(data...)
94+
copy(h[:], hash)
95+
return h
96+
}
97+
98+
// NewKeccakState returns a new keccak state hasher using the ziren platform precompile.
99+
func NewKeccakState() crypto.KeccakState {
100+
return &zirenKeccakState{}
101+
}

trie/secure_trie.go

Lines changed: 12 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -19,7 +19,7 @@ package trie
1919
import (
2020
"github.com/ethereum/go-ethereum/common"
2121
"github.com/ethereum/go-ethereum/core/types"
22-
"github.com/ethereum/go-ethereum/crypto"
22+
"github.com/ethereum/go-ethereum/crypto/platcrypto"
2323
"github.com/ethereum/go-ethereum/rlp"
2424
"github.com/ethereum/go-ethereum/trie/trienode"
2525
"github.com/ethereum/go-ethereum/triedb/database"
@@ -102,14 +102,14 @@ func NewStateTrie(id *ID, db database.NodeDatabase) (*StateTrie, error) {
102102
// This function will omit any encountered error but just
103103
// print out an error message.
104104
func (t *StateTrie) MustGet(key []byte) []byte {
105-
return t.trie.MustGet(crypto.Keccak256(key))
105+
return t.trie.MustGet(platcrypto.Keccak256(key))
106106
}
107107

108108
// GetAccount attempts to retrieve an account with provided account address.
109109
// If the specified account is not in the trie, nil will be returned.
110110
// If a trie node is not found in the database, a MissingNodeError is returned.
111111
func (t *StateTrie) GetAccount(address common.Address) (*types.StateAccount, error) {
112-
res, err := t.trie.Get(crypto.Keccak256(address.Bytes()))
112+
res, err := t.trie.Get(platcrypto.Keccak256(address.Bytes()))
113113
if res == nil || err != nil {
114114
return nil, err
115115
}
@@ -136,7 +136,7 @@ func (t *StateTrie) GetAccountByHash(addrHash common.Hash) (*types.StateAccount,
136136
func (t *StateTrie) PrefetchAccount(addresses []common.Address) error {
137137
var keys [][]byte
138138
for _, addr := range addresses {
139-
keys = append(keys, crypto.Keccak256(addr.Bytes()))
139+
keys = append(keys, platcrypto.Keccak256(addr.Bytes()))
140140
}
141141
return t.trie.Prefetch(keys)
142142
}
@@ -146,7 +146,7 @@ func (t *StateTrie) PrefetchAccount(addresses []common.Address) error {
146146
// If the specified storage slot is not in the trie, nil will be returned.
147147
// If a trie node is not found in the database, a MissingNodeError is returned.
148148
func (t *StateTrie) GetStorage(_ common.Address, key []byte) ([]byte, error) {
149-
enc, err := t.trie.Get(crypto.Keccak256(key))
149+
enc, err := t.trie.Get(platcrypto.Keccak256(key))
150150
if err != nil || len(enc) == 0 {
151151
return nil, err
152152
}
@@ -159,7 +159,7 @@ func (t *StateTrie) GetStorage(_ common.Address, key []byte) ([]byte, error) {
159159
func (t *StateTrie) PrefetchStorage(_ common.Address, keys [][]byte) error {
160160
var keylist [][]byte
161161
for _, key := range keys {
162-
keylist = append(keylist, crypto.Keccak256(key))
162+
keylist = append(keylist, platcrypto.Keccak256(key))
163163
}
164164
return t.trie.Prefetch(keylist)
165165
}
@@ -182,7 +182,7 @@ func (t *StateTrie) GetNode(path []byte) ([]byte, int, error) {
182182
// This function will omit any encountered error but just print out an
183183
// error message.
184184
func (t *StateTrie) MustUpdate(key, value []byte) {
185-
hk := crypto.Keccak256(key)
185+
hk := platcrypto.Keccak256(key)
186186
t.trie.MustUpdate(hk, value)
187187
if t.preimages != nil {
188188
t.secKeyCache[common.Hash(hk)] = common.CopyBytes(key)
@@ -198,7 +198,7 @@ func (t *StateTrie) MustUpdate(key, value []byte) {
198198
//
199199
// If a node is not found in the database, a MissingNodeError is returned.
200200
func (t *StateTrie) UpdateStorage(_ common.Address, key, value []byte) error {
201-
hk := crypto.Keccak256(key)
201+
hk := platcrypto.Keccak256(key)
202202
v, _ := rlp.EncodeToBytes(value)
203203
err := t.trie.Update(hk, v)
204204
if err != nil {
@@ -212,7 +212,7 @@ func (t *StateTrie) UpdateStorage(_ common.Address, key, value []byte) error {
212212

213213
// UpdateAccount will abstract the write of an account to the secure trie.
214214
func (t *StateTrie) UpdateAccount(address common.Address, acc *types.StateAccount, _ int) error {
215-
hk := crypto.Keccak256(address.Bytes())
215+
hk := platcrypto.Keccak256(address.Bytes())
216216
data, err := rlp.EncodeToBytes(acc)
217217
if err != nil {
218218
return err
@@ -233,7 +233,7 @@ func (t *StateTrie) UpdateContractCode(_ common.Address, _ common.Hash, _ []byte
233233
// MustDelete removes any existing value for key from the trie. This function
234234
// will omit any encountered error but just print out an error message.
235235
func (t *StateTrie) MustDelete(key []byte) {
236-
hk := crypto.Keccak256(key)
236+
hk := platcrypto.Keccak256(key)
237237
if t.preimages != nil {
238238
delete(t.secKeyCache, common.Hash(hk))
239239
}
@@ -244,7 +244,7 @@ func (t *StateTrie) MustDelete(key []byte) {
244244
// If the specified trie node is not in the trie, nothing will be changed.
245245
// If a node is not found in the database, a MissingNodeError is returned.
246246
func (t *StateTrie) DeleteStorage(_ common.Address, key []byte) error {
247-
hk := crypto.Keccak256(key)
247+
hk := platcrypto.Keccak256(key)
248248
if t.preimages != nil {
249249
delete(t.secKeyCache, common.Hash(hk))
250250
}
@@ -253,7 +253,7 @@ func (t *StateTrie) DeleteStorage(_ common.Address, key []byte) error {
253253

254254
// DeleteAccount abstracts an account deletion from the trie.
255255
func (t *StateTrie) DeleteAccount(address common.Address) error {
256-
hk := crypto.Keccak256(address.Bytes())
256+
hk := platcrypto.Keccak256(address.Bytes())
257257
if t.preimages != nil {
258258
delete(t.secKeyCache, common.Hash(hk))
259259
}

0 commit comments

Comments
 (0)