openvm_keccak256_circuit/keccakf_op/
mod.rs1mod air;
2pub mod columns;
3mod execution;
4#[cfg(test)]
5pub mod tests;
6pub mod trace;
8
9use std::mem::MaybeUninit;
10
11pub use air::*;
12pub use columns::*;
13pub use trace::*;
14
15use crate::{KECCAK_WIDTH_BYTES, KECCAK_WIDTH_U64S};
16
17pub const NUM_OP_ROWS_PER_INS: usize = 1;
18
19#[derive(derive_new::new, Clone, Copy)]
20pub struct KeccakfExecutor {
21 pub offset: usize,
22 pub pointer_max_bits: usize,
23}
24
25#[cfg(target_endian = "little")]
26fn copy_bytes_to_u64(src: &[u8; KECCAK_WIDTH_BYTES]) -> [u64; KECCAK_WIDTH_U64S] {
27 let mut dst = MaybeUninit::<[u64; KECCAK_WIDTH_U64S]>::uninit();
30
31 unsafe {
32 std::ptr::copy_nonoverlapping(
35 src.as_ptr(), dst.as_mut_ptr() as *mut u8, KECCAK_WIDTH_BYTES, );
39 dst.assume_init()
42 }
43}
44
45#[cfg(not(target_endian = "little"))]
46fn copy_bytes_to_u64(src: &[u8; KECCAK_WIDTH_BYTES]) -> [u64; KECCAK_WIDTH_U64S] {
47 let mut dst = [0u64; KECCAK_WIDTH_U64S];
48 for (u64_word, chunk) in dst.iter_mut().zip(src.chunks_exact(8)) {
49 *u64_word = u64::from_le_bytes(chunk.try_into().unwrap());
50 }
51 dst
52}
53
54#[cfg(target_endian = "little")]
55fn transmute_u64_to_bytes(src: [u64; KECCAK_WIDTH_U64S]) -> [u8; KECCAK_WIDTH_BYTES] {
56 unsafe { std::mem::transmute::<[u64; KECCAK_WIDTH_U64S], [u8; KECCAK_WIDTH_BYTES]>(src) }
60}
61
62#[cfg(not(target_endian = "little"))]
63fn transmute_u64_to_bytes(src: [u64; KECCAK_WIDTH_U64S]) -> [u8; KECCAK_WIDTH_BYTES] {
64 let mut dst = [0u8; KECCAK_WIDTH_BYTES];
65 for (chunk, u64_word) in dst.chunks_exact_mut(8).zip(src.iter()) {
66 chunk.copy_from_slice(&u64_word.to_le_bytes());
67 }
68 dst
69}
70
71fn keccakf_postimage_bytes(
72 preimage_buffer_bytes: &[u8; KECCAK_WIDTH_BYTES],
73) -> [u8; KECCAK_WIDTH_BYTES] {
74 let mut state = copy_bytes_to_u64(preimage_buffer_bytes);
75 tiny_keccak::keccakf(&mut state);
76 transmute_u64_to_bytes(state)
77}