diff --git a/crypto/crypto.go b/crypto/crypto.go
index dd262b4add..8cc4994fe7 100644
--- a/crypto/crypto.go
+++ b/crypto/crypto.go
@@ -28,12 +28,10 @@ import (
"io"
"math/big"
"os"
- "sync"
"github.com/XinFinOrg/XDPoSChain/common"
"github.com/XinFinOrg/XDPoSChain/common/math"
"github.com/XinFinOrg/XDPoSChain/rlp"
- "golang.org/x/crypto/sha3"
)
// SignatureLength indicates the byte length required to carry a signature with recovery id.
@@ -69,17 +67,6 @@ type KeccakState interface {
Read([]byte) (int, error)
}
-// NewKeccakState creates a new KeccakState
-func NewKeccakState() KeccakState {
- return sha3.NewLegacyKeccak256().(KeccakState)
-}
-
-var hasherPool = sync.Pool{
- New: func() any {
- return sha3.NewLegacyKeccak256().(KeccakState)
- },
-}
-
// 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()
@@ -88,41 +75,6 @@ func HashData(kh KeccakState, data []byte) (h common.Hash) {
return h
}
-// 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)
- 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)
- return h
-}
-
-// Keccak512 calculates and returns the Keccak512 hash of the input data.
-func Keccak512(data ...[]byte) []byte {
- d := sha3.NewLegacyKeccak512()
- for _, b := range data {
- d.Write(b)
- }
- return d.Sum(nil)
-}
-
// 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})
diff --git a/crypto/keccak.go b/crypto/keccak.go
new file mode 100644
index 0000000000..d2c8802474
--- /dev/null
+++ b/crypto/keccak.go
@@ -0,0 +1,63 @@
+// Copyright 2025 The go-ethereum Authors
+// This file is part of the go-ethereum library.
+//
+// The go-ethereum library is free software: you can redistribute it and/or modify
+// it under the terms of the GNU Lesser General Public License as published by
+// the Free Software Foundation, either version 3 of the License, or
+// (at your option) any later version.
+//
+// The go-ethereum library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU Lesser General Public License for more details.
+//
+// You should have received a copy of the GNU Lesser General Public License
+// along with the go-ethereum library. If not, see .
+
+//go:build !ziren
+
+package crypto
+
+import (
+ "sync"
+
+ "github.com/XinFinOrg/XDPoSChain/common"
+ "golang.org/x/crypto/sha3"
+)
+
+// NewKeccakState creates a new KeccakState
+func NewKeccakState() KeccakState {
+ return sha3.NewLegacyKeccak256().(KeccakState)
+}
+
+var hasherPool = sync.Pool{
+ New: func() any {
+ return sha3.NewLegacyKeccak256().(KeccakState)
+ },
+}
+
+// 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 _, chunk := range data {
+ d.Write(chunk)
+ }
+ d.Read(b)
+ hasherPool.Put(d)
+ 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 _, chunk := range data {
+ d.Write(chunk)
+ }
+ d.Read(h[:])
+ hasherPool.Put(d)
+ return h
+}
diff --git a/crypto/keccak_ziren.go b/crypto/keccak_ziren.go
new file mode 100644
index 0000000000..75df68a80d
--- /dev/null
+++ b/crypto/keccak_ziren.go
@@ -0,0 +1,122 @@
+// Copyright 2025 The go-ethereum Authors
+// This file is part of the go-ethereum library.
+//
+// The go-ethereum library is free software: you can redistribute it and/or modify
+// it under the terms of the GNU Lesser General Public License as published by
+// the Free Software Foundation, either version 3 of the License, or
+// (at your option) any later version.
+//
+// The go-ethereum library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU Lesser General Public License for more details.
+//
+// You should have received a copy of the GNU Lesser General Public License
+// along with the go-ethereum library. If not, see .
+
+//go:build ziren
+
+package crypto
+
+import (
+ "github.com/ProjectZKM/Ziren/crates/go-runtime/zkvm_runtime"
+ "github.com/XinFinOrg/XDPoSChain/common"
+)
+
+// zirenKeccakState implements the KeccakState interface using the Ziren zkvm_runtime.
+// It accumulates data written to it and uses the zkvm's Keccak256 system call for hashing.
+type zirenKeccakState struct {
+ buf []byte // accumulated data
+ result []byte // cached result
+ dirty bool // whether new data has been written since last hash
+}
+
+func newZirenKeccakState() KeccakState {
+ return &zirenKeccakState{
+ buf: make([]byte, 0, 512), // pre-allocate reasonable capacity
+ }
+}
+
+func (s *zirenKeccakState) Write(p []byte) (n int, err error) {
+ s.buf = append(s.buf, p...)
+ s.dirty = true
+ return len(p), nil
+}
+
+func (s *zirenKeccakState) Sum(b []byte) []byte {
+ s.computeHashIfNeeded()
+ return append(b, s.result...)
+}
+
+func (s *zirenKeccakState) Reset() {
+ s.buf = s.buf[:0]
+ s.result = nil
+ s.dirty = false
+}
+
+func (s *zirenKeccakState) Size() int {
+ return 32
+}
+
+func (s *zirenKeccakState) BlockSize() int {
+ return 136 // Keccak256 rate
+}
+
+func (s *zirenKeccakState) Read(p []byte) (n int, err error) {
+ s.computeHashIfNeeded()
+
+ if len(p) == 0 {
+ return 0, nil
+ }
+
+ // After computeHashIfNeeded(), s.result is always a 32-byte slice
+ n = copy(p, s.result)
+ return n, nil
+}
+
+func (s *zirenKeccakState) computeHashIfNeeded() {
+ if s.dirty || s.result == nil {
+ // Use the zkvm_runtime Keccak256 which uses SyscallKeccakSponge
+ hashArray := zkvm_runtime.Keccak256(s.buf)
+ s.result = hashArray[:]
+ s.dirty = false
+ }
+}
+
+// NewKeccakState creates a new KeccakState
+// This uses a Ziren-optimized implementation that leverages the zkvm_runtime.Keccak256 system call.
+func NewKeccakState() KeccakState {
+ return newZirenKeccakState()
+}
+
+// Keccak256 calculates and returns the Keccak256 hash using the Ziren zkvm_runtime implementation.
+func Keccak256(data ...[]byte) []byte {
+ // For multiple data chunks, concatenate them
+ if len(data) == 0 {
+ result := zkvm_runtime.Keccak256(nil)
+ return result[:]
+ }
+ if len(data) == 1 {
+ result := zkvm_runtime.Keccak256(data[0])
+ return result[:]
+ }
+
+ // Concatenate multiple data chunks
+ var totalLen int
+ for _, d := range data {
+ totalLen += len(d)
+ }
+
+ combined := make([]byte, 0, totalLen)
+ for _, d := range data {
+ combined = append(combined, d...)
+ }
+
+ result := zkvm_runtime.Keccak256(combined)
+ return result[:]
+}
+
+// Keccak256Hash calculates and returns the Keccak256 hash as a Hash using the Ziren zkvm_runtime implementation.
+func Keccak256Hash(data ...[]byte) common.Hash {
+ return common.BytesToHash(Keccak256(data...))
+}
diff --git a/go.mod b/go.mod
index bf94fe273a..044819a52b 100644
--- a/go.mod
+++ b/go.mod
@@ -64,6 +64,7 @@ require (
)
require (
+ github.com/ProjectZKM/Ziren/crates/go-runtime/zkvm_runtime v0.0.0-20260124092617-829590d2c921 // indirect
github.com/StackExchange/wmi v1.2.1 // indirect
github.com/bits-and-blooms/bitset v1.5.0 // indirect
github.com/cespare/xxhash/v2 v2.3.0 // indirect
diff --git a/go.sum b/go.sum
index 4fa67ba64e..e1a98c8ea7 100644
--- a/go.sum
+++ b/go.sum
@@ -1,5 +1,7 @@
github.com/Microsoft/go-winio v0.6.2 h1:F2VQgta7ecxGYO8k3ZZz3RS8fVIXVxONVUPlNERoyfY=
github.com/Microsoft/go-winio v0.6.2/go.mod h1:yd8OoFMLzJbo9gZq8j5qaps8bJ9aShtEA8Ipt1oGCvU=
+github.com/ProjectZKM/Ziren/crates/go-runtime/zkvm_runtime v0.0.0-20260124092617-829590d2c921 h1:NxRnjiL8BBFLCnsDv18a20vb1d34TUiiZtdJGqpj3xs=
+github.com/ProjectZKM/Ziren/crates/go-runtime/zkvm_runtime v0.0.0-20260124092617-829590d2c921/go.mod h1:ioLG6R+5bUSO1oeGSDxOV3FADARuMoytZCSX6MEMQkI=
github.com/StackExchange/wmi v1.2.1 h1:VIkavFPXSjcnS+O8yTq7NI32k0R5Aj+v39y29VYDOSA=
github.com/StackExchange/wmi v1.2.1/go.mod h1:rcmrprowKIVzvc+NUiLncP2uuArMWLCbu9SBzvHz7e8=
github.com/VictoriaMetrics/fastcache v1.12.2 h1:N0y9ASrJ0F6h0QaC3o6uJb3NIZ9VKLjCM7NQbSmF7WI=