Sitelet https://github.com/r55-eth/r55/commit/b3492d54bdf84f4802a49451d5c0f46f51122db7
Skip to content

Commit b3492d5

Browse files
authored
Feat: keccak256 (#5)
1 parent 587a485 commit b3492d5

5 files changed

Lines changed: 62 additions & 8 deletions

File tree

‎eth-riscv-runtime/Cargo.toml‎

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -9,5 +9,3 @@ riscv-rt = "0.12.2"
99

1010
alloy-core = { version = "0.7.4", default-features = false }
1111
alloy-sol-types = { version = "0.7.4", default-features = false }
12-
13-
tiny-keccak = { version = "2.0.2", features = ["keccak"] }

‎eth-riscv-runtime/src/lib.rs‎

Lines changed: 30 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,7 @@ use core::arch::asm;
66
use core::panic::PanicInfo;
77
use core::slice;
88
pub use riscv_rt::entry;
9-
use alloy_core::primitives::Address;
9+
use alloy_core::primitives::{Address, B256};
1010

1111
mod alloc;
1212
pub mod types;
@@ -73,6 +73,35 @@ pub fn revert() -> ! {
7373
unreachable!()
7474
}
7575

76+
pub fn keccak256(offset: u64, size: u64) -> B256 {
77+
let first: u64;
78+
let second: u64;
79+
let third: u64;
80+
let fourth: u64;
81+
82+
unsafe {
83+
asm!(
84+
"ecall",
85+
in("a0") offset,
86+
in("a1") size,
87+
lateout("a0") first,
88+
lateout("a1") second,
89+
lateout("a2") third,
90+
lateout("a3") fourth,
91+
in("t0") u32::from(Syscall::Keccak256)
92+
);
93+
}
94+
95+
let mut bytes = [0u8; 32];
96+
97+
bytes[0..8].copy_from_slice(&first.to_be_bytes());
98+
bytes[8..16].copy_from_slice(&second.to_be_bytes());
99+
bytes[16..24].copy_from_slice(&third.to_be_bytes());
100+
bytes[24..32].copy_from_slice(&fourth.to_be_bytes());
101+
102+
B256::from_slice(&bytes)
103+
}
104+
76105
pub fn msg_sender() -> Address {
77106
let first: u64;
78107
let second: u64;

‎eth-riscv-runtime/src/types.rs‎

Lines changed: 4 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,6 @@ use core::default::Default;
44
use crate::*;
55

66
use alloy_core::primitives::Address;
7-
use tiny_keccak::{Hasher, Keccak};
87

98
extern crate alloc;
109
use alloc::vec::Vec;
@@ -26,10 +25,10 @@ impl<K: ToBytes, V: Into<u64> + From<u64>> Mapping<K, V> {
2625
concatenated.extend_from_slice(&key_bytes);
2726
concatenated.extend_from_slice(&id_bytes);
2827

29-
let mut output = [0u8; 32];
30-
let mut hasher = Keccak::v256();
31-
hasher.update(&concatenated);
32-
hasher.finalize(&mut output);
28+
// Call the keccak256 syscall with the concatenated bytes
29+
let offset = concatenated.as_ptr() as u64;
30+
let size = concatenated.len() as u64;
31+
let output = keccak256(offset, size);
3332

3433
let mut bytes = [0u8; 8];
3534
bytes.copy_from_slice(&output[..8]);

‎eth-riscv-syscalls/src/lib.rs‎

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -50,11 +50,14 @@ macro_rules! syscalls {
5050
// t0: 2, opcode for sstore, a0: storage key, a1: storage value, returns nothing
5151
// t0: 3, opcode for call, args: TODO
5252
// t0: 4, opcode for revert, doesn't return
53+
// t0: 5, opcode for caller, returns an address
54+
// t0: 0x20, opcode for keccak256, a0: offset, a1: size, returns keccak256 hash
5355
syscalls!(
5456
(0, Return, "return"),
5557
(1, SLoad, "sload"),
5658
(2, SStore, "sstore"),
5759
(3, Call, "call"),
5860
(4, Revert, "revert"),
5961
(5, Caller, "caller"),
62+
(0x20, Keccak256, "keccak256"),
6063
);

‎r55/src/exec.rs‎

Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,4 @@
1+
use alloy_core::primitives::Keccak256;
12
use eth_riscv_interpreter::setup_from_elf;
23
use revm::{
34
handler::register::EvmHandler,
@@ -256,6 +257,30 @@ fn execute_riscv(
256257
let third_u64 = u64::from_be_bytes(padded_bytes);
257258
emu.cpu.xregs.write(12, third_u64);
258259
}
260+
0x20 => {
261+
// Syscall::Keccak256
262+
let offset: u64 = emu.cpu.xregs.read(10);
263+
let size: u64 = emu.cpu.xregs.read(11);
264+
265+
let data_bytes = if size != 0 {
266+
emu.cpu
267+
.bus
268+
.get_dram_slice(offset..(offset + size))
269+
.unwrap()
270+
} else {
271+
&mut []
272+
};
273+
274+
let mut hasher = Keccak256::new();
275+
hasher.update(data_bytes);
276+
let hash: [u8; 32] = hasher.finalize().into();
277+
278+
// Write the hash to the emulator's registers
279+
emu.cpu.xregs.write(10, u64::from_le_bytes(hash[0..8].try_into().unwrap()));
280+
emu.cpu.xregs.write(11, u64::from_le_bytes(hash[8..16].try_into().unwrap()));
281+
emu.cpu.xregs.write(12, u64::from_le_bytes(hash[16..24].try_into().unwrap()));
282+
emu.cpu.xregs.write(13, u64::from_le_bytes(hash[24..32].try_into().unwrap()));
283+
}
259284
_ => {
260285
println!("Unhandled syscall: {:?}", t0);
261286
return return_revert(interpreter);

0 commit comments

Comments
 (0)