openvm_sha256_circuit/
extension.rs

1use derive_more::derive::From;
2use openvm_circuit::{
3    arch::{SystemConfig, VmExtension, VmInventory, VmInventoryBuilder, VmInventoryError},
4    system::phantom::PhantomChip,
5};
6use openvm_circuit_derive::{AnyEnum, InstructionExecutor, VmConfig};
7use openvm_circuit_primitives::bitwise_op_lookup::{
8    BitwiseOperationLookupBus, SharedBitwiseOperationLookupChip,
9};
10use openvm_circuit_primitives_derive::{Chip, ChipUsageGetter};
11use openvm_instructions::*;
12use openvm_rv32im_circuit::{
13    Rv32I, Rv32IExecutor, Rv32IPeriphery, Rv32Io, Rv32IoExecutor, Rv32IoPeriphery, Rv32M,
14    Rv32MExecutor, Rv32MPeriphery,
15};
16use openvm_sha256_transpiler::Rv32Sha256Opcode;
17use openvm_stark_backend::p3_field::PrimeField32;
18use serde::{Deserialize, Serialize};
19use strum::IntoEnumIterator;
20
21use crate::*;
22
23#[derive(Clone, Debug, VmConfig, derive_new::new, Serialize, Deserialize)]
24pub struct Sha256Rv32Config {
25    #[system]
26    pub system: SystemConfig,
27    #[extension]
28    pub rv32i: Rv32I,
29    #[extension]
30    pub rv32m: Rv32M,
31    #[extension]
32    pub io: Rv32Io,
33    #[extension]
34    pub sha256: Sha256,
35}
36
37impl Default for Sha256Rv32Config {
38    fn default() -> Self {
39        Self {
40            system: SystemConfig::default().with_continuations(),
41            rv32i: Rv32I,
42            rv32m: Rv32M::default(),
43            io: Rv32Io,
44            sha256: Sha256,
45        }
46    }
47}
48
49#[derive(Clone, Copy, Debug, Default, Serialize, Deserialize)]
50pub struct Sha256;
51
52#[derive(ChipUsageGetter, Chip, InstructionExecutor, From, AnyEnum)]
53pub enum Sha256Executor<F: PrimeField32> {
54    Sha256(Sha256VmChip<F>),
55}
56
57#[derive(From, ChipUsageGetter, Chip, AnyEnum)]
58pub enum Sha256Periphery<F: PrimeField32> {
59    BitwiseOperationLookup(SharedBitwiseOperationLookupChip<8>),
60    Phantom(PhantomChip<F>),
61}
62
63impl<F: PrimeField32> VmExtension<F> for Sha256 {
64    type Executor = Sha256Executor<F>;
65    type Periphery = Sha256Periphery<F>;
66
67    fn build(
68        &self,
69        builder: &mut VmInventoryBuilder<F>,
70    ) -> Result<VmInventory<Self::Executor, Self::Periphery>, VmInventoryError> {
71        let mut inventory = VmInventory::new();
72        let bitwise_lu_chip = if let Some(&chip) = builder
73            .find_chip::<SharedBitwiseOperationLookupChip<8>>()
74            .first()
75        {
76            chip.clone()
77        } else {
78            let bitwise_lu_bus = BitwiseOperationLookupBus::new(builder.new_bus_idx());
79            let chip = SharedBitwiseOperationLookupChip::new(bitwise_lu_bus);
80            inventory.add_periphery_chip(chip.clone());
81            chip
82        };
83
84        let sha256_chip = Sha256VmChip::new(
85            builder.system_port(),
86            builder.system_config().memory_config.pointer_max_bits,
87            bitwise_lu_chip,
88            builder.new_bus_idx(),
89            Rv32Sha256Opcode::CLASS_OFFSET,
90            builder.system_base().offline_memory(),
91        );
92        inventory.add_executor(
93            sha256_chip,
94            Rv32Sha256Opcode::iter().map(|x| x.global_opcode()),
95        )?;
96
97        Ok(inventory)
98    }
99}