openvm_keccak256_guest/
lib.rs
1#![no_std]
2
3#[cfg(target_os = "zkvm")]
4use core::mem::MaybeUninit;
5
6pub const OPCODE: u8 = 0x0b;
8pub const KECCAK256_FUNCT3: u8 = 0b100;
9pub const KECCAK256_FUNCT7: u8 = 0;
10
11#[inline(always)]
13pub fn keccak256(input: &[u8]) -> [u8; 32] {
14 #[cfg(not(target_os = "zkvm"))]
15 {
16 let mut output = [0u8; 32];
17 set_keccak256(input, &mut output);
18 output
19 }
20 #[cfg(target_os = "zkvm")]
21 {
22 let mut output = MaybeUninit::<[u8; 32]>::uninit();
23 native_keccak256(input.as_ptr(), input.len(), output.as_mut_ptr() as *mut u8);
24 unsafe { output.assume_init() }
25 }
26}
27
28#[cfg(target_os = "zkvm")]
41#[inline(always)]
42#[no_mangle]
43extern "C" fn native_keccak256(bytes: *const u8, len: usize, output: *mut u8) {
44 openvm_platform::custom_insn_r!(
45 opcode = OPCODE,
46 funct3 = KECCAK256_FUNCT3,
47 funct7 = KECCAK256_FUNCT7,
48 rd = In output,
49 rs1 = In bytes,
50 rs2 = In len
51 );
52}
53
54pub fn set_keccak256(input: &[u8], output: &mut [u8; 32]) {
56 #[cfg(not(target_os = "zkvm"))]
57 {
58 use tiny_keccak::Hasher;
59 let mut hasher = tiny_keccak::Keccak::v256();
60 hasher.update(input);
61 hasher.finalize(output);
62 }
63 #[cfg(target_os = "zkvm")]
64 native_keccak256(input.as_ptr(), input.len(), output.as_mut_ptr() as *mut u8);
65}