Skip to content

Commit cbf86b4

Browse files
committed
use my keccak PR
1 parent c14034a commit cbf86b4

File tree

1 file changed

+20
-211
lines changed

1 file changed

+20
-211
lines changed

cmd/keeper/crypto_ziren/crypto.go

Lines changed: 20 additions & 211 deletions
Original file line numberDiff line numberDiff line change
@@ -14,85 +14,17 @@
1414
// You should have received a copy of the GNU Lesser General Public License
1515
// along with the go-ethereum library. If not, see <http://www.gnu.org/licenses/>.
1616

17+
//go:build ziren
18+
// +build ziren
19+
1720
package crypto
1821

1922
import (
20-
"errors"
21-
"syscall"
22-
"unsafe"
23-
23+
"github.com/ProjectZKM/Ziren/crates/go-runtime/zkvm_runtime"
2424
"github.com/ethereum/go-ethereum/common"
2525
originalcrypto "github.com/ethereum/go-ethereum/crypto"
2626
)
2727

28-
// Ziren zkVM system call numbers
29-
const (
30-
// SYS_KECCAK_SPONGE is the system call number for keccak sponge compression in Ziren zkVM
31-
// This performs the keccak-f[1600] permutation on a 1600-bit (200-byte) state
32-
SYS_KECCAK_SPONGE = 0x010109
33-
)
34-
35-
// Keccak256 constants
36-
const (
37-
keccakRate = 136 // 1088 bits = 136 bytes for keccak256
38-
keccakCapacity = 64 // 512 bits = 64 bytes
39-
keccakStateSize = 200 // 1600 bits = 200 bytes
40-
)
41-
42-
// zirenKeccakSponge calls the Ziren zkVM keccak sponge compression function
43-
// This performs the keccak-f[1600] permutation on the 200-byte state
44-
func zirenKeccakSponge(state *[keccakStateSize]byte) error {
45-
_, _, errno := syscall.Syscall(
46-
SYS_KECCAK_SPONGE,
47-
uintptr(unsafe.Pointer(state)), // State pointer (input/output)
48-
0, 0, // Unused parameters
49-
)
50-
51-
if errno != 0 {
52-
return errors.New("keccak sponge syscall failed")
53-
}
54-
55-
return nil
56-
}
57-
58-
// zirenKeccak256 implements full keccak256 using the Ziren sponge syscall
59-
func zirenKeccak256(data []byte) []byte {
60-
// Initialize state to zeros
61-
var state [keccakStateSize]byte
62-
63-
// Pad input according to keccak256 specification
64-
// Padding: append 0x01, then zero or more 0x00 bytes, then 0x80
65-
padded := make([]byte, len(data))
66-
copy(padded, data)
67-
padded = append(padded, 0x01) // Domain separator for keccak256
68-
69-
// Pad to multiple of rate (136 bytes for keccak256)
70-
for len(padded)%keccakRate != (keccakRate - 1) {
71-
padded = append(padded, 0x00)
72-
}
73-
padded = append(padded, 0x80) // Final padding bit
74-
75-
// Absorb phase: process input in chunks of rate size
76-
for i := 0; i < len(padded); i += keccakRate {
77-
// XOR current chunk with state
78-
for j := 0; j < keccakRate && i+j < len(padded); j++ {
79-
state[j] ^= padded[i+j]
80-
}
81-
82-
// Apply keccak-f[1600] permutation via syscall
83-
if err := zirenKeccakSponge(&state); err != nil {
84-
// Fallback to standard implementation on error
85-
return originalcrypto.Keccak256(data)
86-
}
87-
}
88-
89-
// Squeeze phase: extract 32 bytes (256 bits) for keccak256
90-
result := make([]byte, 32)
91-
copy(result, state[:32])
92-
93-
return result
94-
}
95-
9628
// Re-export everything from original crypto package except the parts we're overriding
9729
var (
9830
S256 = originalcrypto.S256
@@ -116,166 +48,43 @@ type (
11648
KeccakState = originalcrypto.KeccakState
11749
)
11850

119-
// zirenKeccakState implements crypto.KeccakState using the Ziren sponge precompile
120-
type zirenKeccakState struct {
121-
state [keccakStateSize]byte // 200-byte keccak state
122-
absorbed int // Number of bytes absorbed into current block
123-
buffer [keccakRate]byte // Rate-sized buffer for current block
124-
finalized bool // Whether absorption is complete
125-
}
126-
127-
func (k *zirenKeccakState) Reset() {
128-
for i := range k.state {
129-
k.state[i] = 0
130-
}
131-
for i := range k.buffer {
132-
k.buffer[i] = 0
133-
}
134-
k.absorbed = 0
135-
k.finalized = false
136-
}
137-
138-
func (k *zirenKeccakState) Clone() KeccakState {
139-
clone := &zirenKeccakState{
140-
absorbed: k.absorbed,
141-
finalized: k.finalized,
142-
}
143-
copy(clone.state[:], k.state[:])
144-
copy(clone.buffer[:], k.buffer[:])
145-
return clone
146-
}
147-
148-
func (k *zirenKeccakState) Write(data []byte) (int, error) {
149-
if k.finalized {
150-
panic("write to finalized keccak state")
151-
}
152-
153-
written := 0
154-
for len(data) > 0 {
155-
// Fill current block
156-
canWrite := keccakRate - k.absorbed
157-
if canWrite > len(data) {
158-
canWrite = len(data)
159-
}
160-
161-
copy(k.buffer[k.absorbed:], data[:canWrite])
162-
k.absorbed += canWrite
163-
data = data[canWrite:]
164-
written += canWrite
165-
166-
// If block is full, absorb it
167-
if k.absorbed == keccakRate {
168-
k.absorbBlock()
169-
}
170-
}
171-
172-
return written, nil
173-
}
174-
175-
// absorbBlock XORs the current buffer into state and applies the sponge permutation
176-
func (k *zirenKeccakState) absorbBlock() {
177-
// XOR buffer into state
178-
for i := 0; i < keccakRate; i++ {
179-
k.state[i] ^= k.buffer[i]
180-
}
181-
182-
// Apply keccak-f[1600] permutation via Ziren syscall
183-
if err := zirenKeccakSponge(&k.state); err != nil {
184-
// On error, fallback to standard Go implementation
185-
// This shouldn't happen in production but provides safety
186-
fallbackState := originalcrypto.NewKeccakState()
187-
fallbackState.Reset()
188-
fallbackState.Write(k.buffer[:k.absorbed])
189-
fallbackState.Read(k.state[:32])
190-
}
191-
192-
// Reset buffer
193-
k.absorbed = 0
194-
for i := range k.buffer {
195-
k.buffer[i] = 0
196-
}
197-
}
198-
199-
func (k *zirenKeccakState) Read(hash []byte) (int, error) {
200-
if len(hash) < 32 {
201-
return 0, errors.New("hash slice too short")
202-
}
203-
204-
if !k.finalized {
205-
k.finalize()
206-
}
207-
208-
copy(hash[:32], k.state[:32])
209-
return 32, nil
210-
}
211-
212-
// finalize completes the absorption phase with padding
213-
func (k *zirenKeccakState) finalize() {
214-
// Add keccak256 padding: 0x01, then zeros, then 0x80
215-
k.buffer[k.absorbed] = 0x01
216-
k.absorbed++
217-
218-
// Pad with zeros until we have room for final bit
219-
for k.absorbed < keccakRate-1 {
220-
k.buffer[k.absorbed] = 0x00
221-
k.absorbed++
222-
}
223-
224-
// Add final padding bit
225-
k.buffer[keccakRate-1] = 0x80
226-
k.absorbed = keccakRate
227-
228-
// Absorb final block
229-
k.absorbBlock()
230-
k.finalized = true
231-
}
232-
233-
func (k *zirenKeccakState) Sum(data []byte) []byte {
234-
hash := make([]byte, 32)
235-
k.Read(hash)
236-
return append(data, hash...)
237-
}
238-
239-
func (k *zirenKeccakState) Size() int {
240-
return 32
241-
}
242-
243-
func (k *zirenKeccakState) BlockSize() int {
244-
return 136 // keccak256 block size
245-
}
246-
247-
// Keccak256 calculates and returns the Keccak256 hash using the ziren platform precompile.
51+
// Keccak256 calculates and returns the Keccak256 hash using the Ziren zkvm_runtime implementation.
24852
func Keccak256(data ...[]byte) []byte {
24953
// For multiple data chunks, concatenate them
25054
if len(data) == 0 {
251-
return zirenKeccak256(nil)
55+
result := zkvm_runtime.Keccak256(nil)
56+
return result[:]
25257
}
25358
if len(data) == 1 {
254-
return zirenKeccak256(data[0])
59+
result := zkvm_runtime.Keccak256(data[0])
60+
return result[:]
25561
}
256-
62+
25763
// Concatenate multiple data chunks
25864
var totalLen int
25965
for _, d := range data {
26066
totalLen += len(d)
26167
}
262-
68+
26369
combined := make([]byte, 0, totalLen)
26470
for _, d := range data {
26571
combined = append(combined, d...)
26672
}
267-
268-
return zirenKeccak256(combined)
73+
74+
result := zkvm_runtime.Keccak256(combined)
75+
return result[:]
26976
}
27077

271-
// Keccak256Hash calculates and returns the Keccak256 hash as a Hash using the ziren platform precompile.
78+
// Keccak256Hash calculates and returns the Keccak256 hash as a Hash using the Ziren zkvm_runtime implementation.
27279
func Keccak256Hash(data ...[]byte) (h common.Hash) {
27380
hash := Keccak256(data...)
27481
copy(h[:], hash)
27582
return h
27683
}
27784

278-
// NewKeccakState returns a new keccak state hasher using the ziren platform precompile.
85+
// NewKeccakState returns a new keccak state hasher.
86+
// For now, we fallback to the original implementation for the stateful interface.
87+
// TODO: Implement a stateful wrapper around zkvm_runtime.Keccak256 if needed.
27988
func NewKeccakState() KeccakState {
280-
return &zirenKeccakState{}
281-
}
89+
return originalcrypto.NewKeccakState()
90+
}

0 commit comments

Comments
 (0)