openvm_sha256_transpiler/
lib.rs

1use openvm_instructions::{riscv::RV32_MEMORY_AS, LocalOpcode};
2use openvm_instructions_derive::LocalOpcode;
3use openvm_sha256_guest::{OPCODE, SHA256_FUNCT3, SHA256_FUNCT7};
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 = 0x320]
13#[repr(usize)]
14pub enum Rv32Sha256Opcode {
15    SHA256,
16}
17
18#[derive(Default)]
19pub struct Sha256TranspilerExtension;
20
21impl<F: PrimeField32> TranspilerExtension<F> for Sha256TranspilerExtension {
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, SHA256_FUNCT3) {
31            return None;
32        }
33        let dec_insn = RType::new(instruction_u32);
34
35        if dec_insn.funct7 != SHA256_FUNCT7 as u32 {
36            return None;
37        }
38        let instruction = from_r_type(
39            Rv32Sha256Opcode::SHA256.global_opcode().as_usize(),
40            RV32_MEMORY_AS as usize,
41            &dec_insn,
42            true,
43        );
44        Some(TranspilerOutput::one_to_one(instruction))
45    }
46}