openvm_keccak256_transpiler/
lib.rs
1use openvm_instructions::LocalOpcode;
2use openvm_instructions_derive::LocalOpcode;
3use openvm_keccak256_guest::{KECCAK256_FUNCT3, KECCAK256_FUNCT7, OPCODE};
4use openvm_stark_backend::p3_field::PrimeField32;
5use openvm_transpiler::{util::from_r_type, TranspilerExtension, TranspilerOutput};
6use rrs_lib::instruction_formats::RType;
7use strum::{EnumCount, EnumIter, FromRepr};
8
9#[derive(
10 Copy, Clone, Debug, PartialEq, Eq, PartialOrd, Ord, EnumCount, EnumIter, FromRepr, LocalOpcode,
11)]
12#[opcode_offset = 0x310]
13#[repr(usize)]
14pub enum Rv32KeccakOpcode {
15 KECCAK256,
16}
17
18#[derive(Default)]
19pub struct Keccak256TranspilerExtension;
20
21impl<F: PrimeField32> TranspilerExtension<F> for Keccak256TranspilerExtension {
22 fn process_custom(&self, instruction_stream: &[u32]) -> Option<TranspilerOutput<F>> {
23 if instruction_stream.is_empty() {
24 return None;
25 }
26 let instruction_u32 = instruction_stream[0];
27 let opcode = (instruction_u32 & 0x7f) as u8;
28 let funct3 = ((instruction_u32 >> 12) & 0b111) as u8;
29
30 if (opcode, funct3) != (OPCODE, KECCAK256_FUNCT3) {
31 return None;
32 }
33 let dec_insn = RType::new(instruction_u32);
34 if dec_insn.funct7 != KECCAK256_FUNCT7 as u32 {
35 return None;
36 }
37 let instruction = from_r_type(
38 Rv32KeccakOpcode::KECCAK256.global_opcode().as_usize(),
39 2,
40 &dec_insn,
41 true,
42 );
43 Some(TranspilerOutput::one_to_one(instruction))
44 }
45}